【问题标题】:Soundplayer issue? boolean statement should execute a sound播放器问题?布尔语句应该执行一个声音
【发布时间】:2014-03-15 00:26:03
【问题描述】:

我遇到了一个我似乎无法解决的问题,如果 KeyPressed == false 的测试确实会播放“car_still.wav”,但如果 KeyPressed == true 的测试不会什么都玩。

我该如何解决上述问题以及,

如何将 player/player2.Stop() 集成到任一 if 语句中(如果一个声音播放,另一个停止),因为现在我收到一个错误“名称‘播放器’不存在在当前上下文中”。

提前谢谢你。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    private int carX;
    private int roadTilesY = -193;
    int speedY;
    int time;
    bool keyPressed;
    System.Media.SoundPlayer player;
    System.Media.SoundPlayer player2; 


    public Form1()
    {
        InitializeComponent();
        gameSounds();
        carX = this.Width / 2 - 30;
        speedY = 0;
        time = 0;
    }

    private void gameSounds()
    {
        if (!keyPressed)
        {
            player = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_still.wav");
            player.PlayLooping();
        }
        else
        {
            player2 = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_speeding.wav");
            player2.PlayLooping();
            if (player != null)
                player.Stop();
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        PlayerCar.Invalidate();
        PlayerCar.Location = new Point(carX, PlayerCar.Location.Y);
        RoadTileAnimation();
        npcCarMovement();
        if (keyPressed == true)
        {
            label1.Text = "Key pressed";
        }
        if (keyPressed == false)
        {
            label1.Text = "key not pressed";
        }

        label2.Text = "" + speedY;


    }

    private void RoadTileAnimation()
    {
        roadTilesY = roadTilesY - speedY;

        if (roadTilesY >= -50)
        {
            roadTilesY = -193;
        }

        roadTiles.Location = new Point(roadTiles.Location.X, roadTilesY);

    }


    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {

        if (e.KeyCode == Keys.Left)
        {
           carX = carX - 15;
           if ((carX + PlayerCar.Width) > this.Width)
           {
               carX = this.Width - PlayerCar.Width - 10;
           }

        }

        if (e.KeyCode == Keys.Right)
        {
            carX = carX + 15;
            if ((carX + PlayerCar.Width) > this.Width)
            {
                carX = this.Width - PlayerCar.Width - 10;
            }
        }

        if (e.KeyCode == Keys.Up)
        {

            speedY = speedY - 1;
            keyPressed = true;
        }

        if (e.KeyCode == Keys.Down)
        {
            speedY = speedY + 3;
            if (speedY > 0)
            {
                speedY = 0;
            }
            keyPressed = true;

        }
    }

    private void timer2_Tick(object sender, EventArgs e)
    {
        if (speedY != 0)
        {

            time++;
            time = time - speedY / 8;
            timeLabel.Text = time.ToString() + " m";
        }
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Up)
        {
            keyPressed = false;
        }

        if (e.KeyCode == Keys.Down)
        {
            keyPressed = false;
        }

        if (e.KeyCode == Keys.Left)
        {
            keyPressed = false;
        }

        if (e.KeyCode == Keys.Right)
        {
            keyPressed = false;
        }
    }
    private void npcCarMovement()
    {
        npcCar.Invalidate();
        npcCar.Location = new Point(npcCar.Location.X, npcCar.Location.Y + 2);
        npcCar.Location = new Point(npcCar.Location.X, npcCar.Location.Y - speedY);

    }
}
}

【问题讨论】:

  • 为了您的更新,我会确保有问题的文件存在并且输出窗口中不会出现异常。

标签: c# audio boolean soundplayer


【解决方案1】:

从根本上说,这是一个范围界定问题。基本上,每当您编写 {} 时,都会创建一个新范围。给定范围内的行可以访问该范围,以及它嵌套的任何范围。

在您的 if 语句中,您创建了播放器对象(它现在位于该 if 语句的范围内)。在 else 语句中,不知道播放器对象,因为它不在 else 块可访问的范围内。

要解决此问题,请将其声明为类级别变量。您仍然可以在 if 语句中分配它,只需确保在 else 中检查 null。从技术上讲,您可以在函数范围内声明它(这将使错误消失),但下次运行函数时(可能会被垃圾收集)它会设置为 null,因为一旦函数超出范围(返回) 所有局部变量都丢失了,它们已经“超出范围”。

【讨论】:

    【解决方案2】:

    您正在条件语句中创建 SoundPlayer,如果它们将在您的应用程序的整个时间内使用,请在类级别创建它们。看看这个MSDN Article的解释

    public partial class Form1 : Form
    {
        System.Media.SoundPlayer player; //Note that they are created here
        System.Media.SoundPlayer player2; //They will be visible to the entire class
        bool keyPressed;
        public Form1()
        {
            InitializeComponent();
        }
    
        private void gameSounds()
        {
            if (!keyPressed) //Note that these Booleans are either true/false no need to compare to true or false
            {
                player = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_still.wav");
                player.PlayLooping();
            }
            else //this will be run if keypressed is true
            {
                player2 = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_speeding.wav");
                player2.PlayLooping();
                if(player != null) 
                    player.Stop(); 
            }
        }
    
    }
    

    根据 cmets 中的说明进行更改:

    发生的情况是,当您停止其他声音播放器时,它会停止所有播放器。我会亲自检查一下您的 keyPressed 变量是否已经与您要发送的状态相同,以及是否未发送。我已将您的 gameSounds 例程修改为:

    private void gameSounds()
    {
        if (!keyPressed)
        {
            player2.Stop();
            player.PlayLooping();
        }
        else 
        {
            player.Stop();
            player2.PlayLooping();
        }
    }
    

    我还将 player 和 player2 的整个定义放在你的类级别声明中:

    System.Media.SoundPlayer player = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_still.wav");
    System.Media.SoundPlayer player2 = new System.Media.SoundPlayer(@"C:\Users\Parker\Desktop\Game\car_speeding.wav");
    

    我看不到你在哪里调用 gameSounds 方法,除了在你的 Form_Load EventHandler 中,但我会确保如果它 keyPressed 变量已经处于相同的状态,你不会一直点击你的 gamesounds 方法,只是让声音循环直到你改变 keyPressed 的状态。

    这些是我用来测试的方法:

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (!keyPressed)
        {
            keyPressed = true;
            gameSounds();
        }
    }
    
    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if(keyPressed)
        {
            keyPressed = false;
            gameSounds();
        }
    
    }
    

    【讨论】:

    • 我已将代码更改为您提供的代码,但仍然不行。另一个声音仍然没有播放。还有什么想法吗?我已经用新版本更新了我的初始帖子。
    • @SzymonZmudzki 你想多路复用这些声音吗?
    • 不,我正在寻找的是:当汽车静止时播放“car_still”声音,而当汽车静止时播放“car_speeding”声音。
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多