locked
Quick help with a maze game? RRS feed

  • Question

  • Code updated now, only two problems left until I'm happy to feel I've completed it.

    When the player hits a wall the counter goes down at 2 lifes per hit. When the game starts the sound I have(beep.wav) which should only sound when the player hits a wall, is sounding each time I begin the game and the sound which should play throughout the game(onestop.wav) isn't playing at all. 

        public partial class Form1 : Form
           
        {
            // This SoundPlayer plays a song when the game begins.
            System.Media.SoundPlayer onestop = new System.Media.SoundPlayer(@"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\onestop.wav");

            // This SoundPlayer plays a sound whenever the player hits a wall.
            System.Media.SoundPlayer beepSound = new System.Media.SoundPlayer(@"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\beep.wav");

            // This SoundPlayer plays a sound when the player finishes the game.
            System.Media.SoundPlayer clapSound = new System.Media.SoundPlayer(@"C:\Users\kC\Favorites\Desktop\Kev stuff\Projects\MazeGame\winningApplause.wav");

           
            public Form1()
            {
                InitializeComponent();
                timer1.Interval = (1000) * (1);
                timer1.Enabled = true;
                timer1.Start();
            }

            private void Form1_Load(object sender, EventArgs e)
            {

                begin();

            }

            int lives = 5;

            private void begin()
            {
                onestop.Play();
                livesTextBox.Text = lives.ToString();
                Point startingPoint = panel1.Location;
                startingPoint.Offset(10, 10);
                Cursor.Position = PointToScreen(startingPoint);
            }

            private void MoveToStart()
            {

                if ( lives > 0)
                {
                    lives--;
                }
                if (lives == 0)
                {
                    MessageBox.Show("You Lose!!");
                    Close();
                }

                else if (lives < 0)
                {
                    MessageBox.Show("You Lose!!");
                    Close();
                }
            }

            private void wall_MouseEnter(object sender, EventArgs e)
            {
                // When the mouse pointer hits a wall or enters the panel,
                // call the MoveToStart() method.
                beepSound.Play();
                MoveToStart();

                lives--;
                livesTextBox.Text = lives.ToString();
            }

            private void finishLabel_MouseEnter(object sender, EventArgs e)
            {
                // Play a sound, show a congratulatory MessageBox, then close the form.
                clapSound.Play();
                MessageBox.Show("Congratulations! You've beaten the maze!");
                Close();
            }

            int gameElapsed = 0;

            private void timer1_Tick(object sender, EventArgs e)
            {
                gameElapsed++;
                textBox1.Text = "" + gameElapsed.ToString();
            }


        }



    • Edited by kcy0 Monday, December 17, 2012 6:44 PM
    Monday, December 17, 2012 3:12 PM

Answers

  • No need to call Start()

    No need to reenable the timer each tick.  It's enabled if you got a tick event.

    No need to reset the interval each tick.  Just set all that stuff once:

    Add a handler for the form's Load event.

    In there, call your begin() function (not in the constructor)

    Also in your begin function, set timer1.Interval and timer1.Enabled.  (or set those properties in the designer of your form.)

    Then each second the timer1_Tick function will be called.  Do whatever work you need to in there.

    Keep track of the number of lives in a field member variable of the form.

    int lives = 5;

    The sound plays when the mouse enters the wall control.  Maybe that's not what you intended.??

    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Monday, December 17, 2012 6:20 PM
  • Hi kcy0,

    What the problems are you encountering now? You can point it out and we will try to help.

    Anyway, two places that maybe you should pay attention to.

    1. You said"When the player hits a wall the counter goes down at 2 lifes per hit"  and if I am not wrong, you use  "lives--;" in wall_MouseEnter event. It should be " lives -= 2;" right?

    2.In MoveToStart method, below the filter "lives<0" and "Live ==0" , you do the same thing.

    Why not put them together?

     if ( lives > 0)
    {
       lives--;
    }
    else
    {
       MessageBox.Show("You Lose!!");
      Close();
    }

    Hope this helps.

    Regards,


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Wednesday, December 19, 2012 2:57 AM
    1. Have you verified how many times you call MoveToStart()?  You might be calling it from other places in your program.
    2. Have you verified how many times the wall_MouseEnter handler is being executed?  You might have wall_MouseEnter hooked up as a handler for multiple events, or for multiple controls on the same form.
    3. Have you verified how many times the MouseEnter event is being fired?  (by attaching another handler?)  It might not work quite the way you thought it does.

    Tracepoints are good for these.  Set a breakpoint on the line.  Then right click on the breakpoint's red circle and choose "When Hit..." and check the "Print a Message" button.  Also make sure the "Continue execution" checkbox is checked, so it will just print a message and then move on.

    Then run your program and watch the "Output" window. (Debug > Windows > Output)

    I think you will find that your wall_MouseEnter handler is running more often than you think it does.

    If you get more messages than you thought, then reconsider the logic of your program or just use a normal breakpoint and check the call stack to see who's calling you in a way that you didn't anticipate.


    Now, what follows is just my opinion...(read on)

    I don't think that for a maze game you should be placing controls on the form to represent walls and using the MouseEnter event.  For example, it's possible to move the mouse from one side of a "wall" control to the other without getting a MouseEnter event.  You'll be able to "cheat" by moving the mouse quickly.

    I suggest trying to get away from using MouseEnter messages.  I suggest rendering the maze to a bitmap, displaying it in a picturebox and then just track MouseMove messages.  

    I'd make the "MouseMove" processing consider a line segment that connect the previous mouse location to the current mouse location.  If one of these line segments crosses a wall, then you can consider that the player went through the wall.  This requires more math, but it's more fool-proof and resistant to cheating with fast mouse movements.

    Don't use a bunch of PictureBox controls on a forms designer to map out your maze.  This is abusing the flexibility of the forms designer.  This will get particularly bad when your maze gets complex and has thousands of walls.  Also, using the forms designer as a maze designer may be convenient for you, but it adds a lot of overhead so you might want to consider a different technique.  Maybe just use a bitmap to define the topology of your maze.  You could even create it in mspaint if you had to.

    Actually what I'd do is make a "maze editor" program that lets you design your own mazes, save and load them, edit them, and maybe even validate the maze to ensure there is a possible solution.


    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Wednesday, December 19, 2012 1:45 PM

All replies

  • No need to call Start()

    No need to reenable the timer each tick.  It's enabled if you got a tick event.

    No need to reset the interval each tick.  Just set all that stuff once:

    Add a handler for the form's Load event.

    In there, call your begin() function (not in the constructor)

    Also in your begin function, set timer1.Interval and timer1.Enabled.  (or set those properties in the designer of your form.)

    Then each second the timer1_Tick function will be called.  Do whatever work you need to in there.

    Keep track of the number of lives in a field member variable of the form.

    int lives = 5;

    The sound plays when the mouse enters the wall control.  Maybe that's not what you intended.??

    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Monday, December 17, 2012 6:20 PM
  • I've taken your advice but I'm still encountering some problems, I'll update my post now with the code changes.
    Monday, December 17, 2012 6:40 PM
  • Hi kcy0,

    What the problems are you encountering now? You can point it out and we will try to help.

    Anyway, two places that maybe you should pay attention to.

    1. You said"When the player hits a wall the counter goes down at 2 lifes per hit"  and if I am not wrong, you use  "lives--;" in wall_MouseEnter event. It should be " lives -= 2;" right?

    2.In MoveToStart method, below the filter "lives<0" and "Live ==0" , you do the same thing.

    Why not put them together?

     if ( lives > 0)
    {
       lives--;
    }
    else
    {
       MessageBox.Show("You Lose!!");
      Close();
    }

    Hope this helps.

    Regards,


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Wednesday, December 19, 2012 2:57 AM
    1. Have you verified how many times you call MoveToStart()?  You might be calling it from other places in your program.
    2. Have you verified how many times the wall_MouseEnter handler is being executed?  You might have wall_MouseEnter hooked up as a handler for multiple events, or for multiple controls on the same form.
    3. Have you verified how many times the MouseEnter event is being fired?  (by attaching another handler?)  It might not work quite the way you thought it does.

    Tracepoints are good for these.  Set a breakpoint on the line.  Then right click on the breakpoint's red circle and choose "When Hit..." and check the "Print a Message" button.  Also make sure the "Continue execution" checkbox is checked, so it will just print a message and then move on.

    Then run your program and watch the "Output" window. (Debug > Windows > Output)

    I think you will find that your wall_MouseEnter handler is running more often than you think it does.

    If you get more messages than you thought, then reconsider the logic of your program or just use a normal breakpoint and check the call stack to see who's calling you in a way that you didn't anticipate.


    Now, what follows is just my opinion...(read on)

    I don't think that for a maze game you should be placing controls on the form to represent walls and using the MouseEnter event.  For example, it's possible to move the mouse from one side of a "wall" control to the other without getting a MouseEnter event.  You'll be able to "cheat" by moving the mouse quickly.

    I suggest trying to get away from using MouseEnter messages.  I suggest rendering the maze to a bitmap, displaying it in a picturebox and then just track MouseMove messages.  

    I'd make the "MouseMove" processing consider a line segment that connect the previous mouse location to the current mouse location.  If one of these line segments crosses a wall, then you can consider that the player went through the wall.  This requires more math, but it's more fool-proof and resistant to cheating with fast mouse movements.

    Don't use a bunch of PictureBox controls on a forms designer to map out your maze.  This is abusing the flexibility of the forms designer.  This will get particularly bad when your maze gets complex and has thousands of walls.  Also, using the forms designer as a maze designer may be convenient for you, but it adds a lot of overhead so you might want to consider a different technique.  Maybe just use a bitmap to define the topology of your maze.  You could even create it in mspaint if you had to.

    Actually what I'd do is make a "maze editor" program that lets you design your own mazes, save and load them, edit them, and maybe even validate the maze to ensure there is a possible solution.


    • Marked as answer by Lisa Zhu Wednesday, December 26, 2012 2:22 AM
    Wednesday, December 19, 2012 1:45 PM