简体   繁体   English

声音播放器问题? 布尔语句应执行声音

[英]Soundplayer issue? boolean statement should execute a sound

I've ran into a bit of an issue I can't seem to resolve, the test for if KeyPressed == false does play the 'car_still.wav', however the test for if KeyPressed == true doesn't play anything at all. 我遇到了一个似乎无法解决的问题,KeyPressed == false的测试确实播放了“ car_still.wav”,但是KeyPressed == true的测试在播放时没有任何作用所有。

How do I go about fixing the issue mentioned above and also, 我该如何解决上述问题,

How can I integrate a player/player2.Stop() into either of the if statements (if one sound plays, the other one stops) because right now I'm getting an error "The name 'player' does not exist in the current context". 我如何将player / player2.Stop()集成到两个if语句中(如果一个声音播放,另一个声音停止),因为现在我收到一个错误消息“当前播放器名称不存在”上下文”。

Thank you in advance. 先感谢您。

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);

    }
}
}

You are creating your SoundPlayers in your Conditional Statements, If they are going to be in use for the entire time of your application create them at the class level. 您将在条件语句中创建SoundPlayers,如果要在整个应用程序中使用它们,请在类级别上创建它们。 Look at this MSDN Article for an explanation 查看此MSDN文章以获取解释

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(); 
        }
    }

}

Change base on clarification in the comments: 根据注释中的说明进行更改:

What is happening is when you stop the other soundplayer it stops them all. 发生的是,当您停止另一个声音播放器时,所有声音播放器都停止了。 I would personally put a check to see if your keyPressed variable is already in the same state as what you are wanting to send and if it is not send it. 我亲自检查一下keyPressed变量是否已经与您要发送的状态相同,以及是否未发送。 I have modified your gameSounds routine to this: 我已经将您的gameSounds例程修改为:

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

I also put the entire definition for player and player2 in your class level declarations: 我也将播放器和播放器2的整个定义放在您的类级别声明中:

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");

I do not see where you are calling the gameSounds method except in your Form_Load EventHandler but I would make sure that if it the keyPressed variable was already in the same state that you don't keep hitting your gamesounds method just let the sound loop until you change the state of keyPressed. 除了在Form_Load EventHandler中,我看不到您在哪里调用gameSounds方法,但我要确保,如果keyPressed变量已经处于相同的状态,您就不会继续按自己的gameounds方法,只是让声音循环直到您更改keyPressed的状态。

These are the methods that I was using to test: 这些是我用来测试的方法:

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();
    }

}

At it's root, this is a scoping issue. 从根本上讲,这是一个范围界定问题。 Basically, whenever you write {}, you create a new scope. 基本上,每当您编写{}时,您都会创建一个新的作用域。 A line within a given scope has access to that scope, and any scopes it is nested in. 给定范围内的行可以访问该范围及其嵌套的任何范围。

In your if statement, you create the player object (which now lives inside the scope of that if statement). 在if语句中,创建播放器对象(现在位于该if语句的范围内)。 In the else statement, there is no knowledge of the player object because it isn't in a scope accessible to the else block. 在else语句中,不知道player对象,因为它不在else块可访问的范围内。

To fix this, declare it as a class level variable. 要解决此问题,请将其声明为类级变量。 You can still assign it in the if statement, just be sure to check for null in the else. 您仍然可以在if语句中分配它,只需确保在else中检查是否为null。 You could technically declare it in the function scope (this would make the error go away) but it would be set to null the next time the function is run(and possibly garbage collected) because as soon as the function goes out of scope (returns) all local variables are lost, they have "gone out of scope". 您可以从技术上在函数范围内声明它(这将使错误消失),但是在下次运行该函数(并可能会进行垃圾回收)时将其设置为null,因为一旦该函数超出范围(返回) )所有局部变量都丢失了,它们已经“超出范围”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM