У меня не получается заставить звук работать в моей игре с астероидами? - PullRequest
2 голосов
/ 04 августа 2020

Итак, я писал ремейк игры Asteroids для Atari 1979 года в приложении C# Visual Studio 2019 Windows Forms. Проблема, с которой я столкнулся, заключается в том, что звуки работают некорректно:

Вот где я реализую звук, когда метеорит падает на корабль:

private void DetectShipToMeteorCollisions()
{
    if (!_ship.IsActive)
        return;

    for (int meteorIndex = 0; meteorIndex < _meteors.Count; meteorIndex++)
    {
        if (_meteors[meteorIndex].CollidesWithShip(_ship))
        {
            _meteors[meteorIndex].IsActive = false;
            GameManager.RaiseMeteorHit(_meteors[meteorIndex]);
            BlowUpShip();
        }
        SoundPlayer1 sound = new SoundPlayer1("bang_6.wav");
        sound.Play(); 
    }
}

// "bang_6. wav "импортируется в проект Visual Studio.

А вот код для SoundPlayer1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;

namespace AsteroidsGdiApp.Core
{
    public class SoundPlayer1
    {
        private byte[] m_soundBytes;
        private string m_fileName;

        private enum Flags
        {
            SND_SYNC = 0x0000,  /* play synchronously (default) */
            SND_ASYNC = 0x0001,  /* play asynchronously */
            SND_NODEFAULT = 0x0002,  /* silence (!default) if sound not found */
            SND_MEMORY = 0x0004,  /* pszSound points to a memory file */
            SND_LOOP = 0x0008,  /* loop the sound until next sndPlaySound */
            SND_NOSTOP = 0x0010,  /* don't stop any currently playing sound */
            SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
            SND_ALIAS = 0x00010000, /* name is a registry alias */
            SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
            SND_FILENAME = 0x00020000, /* name is file name */
            SND_RESOURCE = 0x00040004  /* name is resource name or atom */
        }

        [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]
        private extern static int WCE_PlaySound(string szSound, IntPtr hMod, int flags);

        [DllImport("CoreDll.DLL", EntryPoint = "PlaySound", SetLastError = true)]
        private extern static int WCE_PlaySoundBytes(byte[] szSound, IntPtr hMod, int flags);

        /// <summary>
        /// Construct the Sound object to play sound data from the specified file.
        /// </summary>
        public SoundPlayer1(string fileName)
        {
            m_fileName = fileName;
        }

        /// <summary>
        /// Construct the Sound object to play sound data from the specified stream.
        /// </summary>
        public SoundPlayer1(Stream stream)
        {
            // read the data from the stream
            m_soundBytes = new byte[stream.Length];
            stream.Read(m_soundBytes, 0, (int)stream.Length);
        }

        /// <summary>
        /// Play the sound
        /// </summary>
        public void Play()
        {
            // if a file name has been registered, call WCE_PlaySound,
            //  otherwise call WCE_PlaySoundBytes
            if (m_fileName != null)
                WCE_PlaySound(m_fileName, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_FILENAME));
            else
                WCE_PlaySoundBytes(m_soundBytes, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_MEMORY));
        }

        public static void PlayEmbeddedSound(Assembly assembly, string resourceName)
        {
            SoundPlayer1 sound = new SoundPlayer1(assembly.GetManifestResourceStream(resourceName));
            sound.Play();
        }

        public static void PlayFromFile(string filePath)
        {
            SoundPlayer1 sound = new SoundPlayer1(filePath);
            sound.Play();
        }
    }
}

Попытка скомпилировать после вставки звука приводит к этой ошибке:

Интересно, почему это могло быть? Большое спасибо.

enter image description here

So upon fixing the error, I am attempting to add a sound effect for when a bullet is fired. But for some reason it is not detecting this wav file when it has been imported into the project the same way.

I wonder why it is not finding this wav file.

Here is is, imported to the project. Thanks.

enter image description here

private void DetectBulletCollisions()
{

    for(int meteorIndex = 0; meteorIndex < _meteors.Count; meteorIndex++)
    {
        for (int bulletIndex = 0; bulletIndex < _photons.Length; bulletIndex++)
            
        {
            //TODO get rid of event drive desing here
            _meteors[meteorIndex].TestIfShot(_photons[bulletIndex]);
            System.IO.Stream str = Properties.Resources.mySoundFile;
            System.Media.SoundPlayer snd = new System.Media.SoundPlayer("gunshot.wav");
            snd.Play();
        }
    }
}

Исключение gunshot.wav enter image description here

Here the file is in same directory. So fact that Visual Studio is not seeing it is bizarre. It's imported in the visual studio project as well, thanks.

введите описание изображения здесь

1 Ответ

0 голосов
/ 07 августа 2020

Попробуйте создать в проекте папку с именем «SoundFiles» для сохранения файлов WAV, которые вы хотите воспроизвести.

введите описание изображения здесь

Затем получите доступ к файлам с помощью следующего кода.

System.Media.SoundPlayer snd = new System.Media.SoundPlayer(AppDomain.CurrentDomain.BaseDirectory + @"../../SoundFiles/temp.wav");
snd.Play();
...