Reputation: 3132
I have to do a snake game for a small project in school. I have gotten so far as to that the snake moves in a direction endlessly. however pressing another direction will just add that direction to the movement of the snake. so when you press up first then left it goes north east. I am pretty much stuck on how to solve this. I have written a stop() method but I don't know how to implement it. if you guys could give me some tips it would be much appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Snake
{
class Snake
{
//Attributes go here....
private Form frmSnake;
private static Button btnSnake;
private static Label lblStatus;
private static Timer timerUP;
private static Timer timerLEFT;
private static Timer timerDOWN;
private static Timer timerRIGHT;
//Initialize a Snake Object...
public Snake()
{
initComponents();
initTimers ();
startAllTimers ();
initEventHandler(this);
frmSnake.ShowDialog();
}
//give the Components of snake object values
private void initComponents()
{
frmSnake = new Form();
lblStatus = new Label();
btnSnake = new Button();
frmSnake.Controls.Add(btnSnake);
frmSnake.Controls.Add(lblStatus);
frmSnake.SetBounds(400, 400, 700, 550);
frmSnake.Text = "Snake";
lblStatus.SetBounds(0, 495, 700, 20);
lblStatus.BackColor = System.Drawing.Color.Red;
btnSnake.SetBounds((frmSnake.Width / 2) - (btnSnake.Width / 2), ((frmSnake.Height - lblStatus.Height) / 2) - (btnSnake.Height / 2), 10, 10);
}
private void initTimers ()
{
timerUP = new Timer ();
timerLEFT = new Timer ();
timerDOWN = new Timer ();
timerRIGHT = new Timer ();
timerUP.Enabled = true;
timerUP.Interval = 100;
timerLEFT.Enabled = true;
timerLEFT.Interval = 100;
timerDOWN.Enabled = true;
timerDOWN.Interval = 100;
timerRIGHT.Enabled = true;
timerRIGHT.Interval = 100;
}
private void disposeTimers ()
{
timerUP.Dispose ();
timerLEFT.Dispose ();
timerDOWN.Dispose ();
timerRIGHT.Dispose ();
}
private void stopTimer (Timer timer)
{
timer.Stop ();
}
private void stopAllTimers ()
{
timerUP.Stop ();
timerDOWN.Stop ();
timerLEFT.Stop();
timerRIGHT.Stop();
}
private void startAllTimers ()
{
timerUP.Start ();
timerDOWN.Start ();
timerRIGHT.Start ();
timerLEFT.Start ();
}
private void startTimer (Timer timer)
{
timer.Start ();
}
//initializes the event handler which handles a key press W,A,S,D from user
//W,A,S,D correspondents UP,LEFT,DOWN,RIGHT
private void initEventHandler(Snake snake)
{
snake.frmSnake.KeyPreview = true;
snake.frmSnake.KeyDown += new KeyEventHandler(snake.frm_KeyDown);
}
//handle the key press event sent from previous method
private void frm_KeyDown(object sender, KeyEventArgs e)
{
disposeTimers ();
initTimers ();
switch ( e.KeyData )
{
//if up is pressed
case Keys.W:
{
startTimer ( timerUP );
timerUP.Tick += new EventHandler ( timerUP_Tick );
}
break;
//if left is pressed
case Keys.A:
{
startTimer ( timerLEFT );
timerLEFT.Tick += new EventHandler ( timerLEFT_Tick );
//move snake 5 spaces
}
break;
//if down is pressed
case Keys.S:
{
startTimer ( timerDOWN );
timerDOWN.Tick += new EventHandler ( timerDOWN_Tick );
//move snake 5 spaces
}
break;
//if right is pressed
case Keys.D:
{
startTimer ( timerRIGHT );
timerRIGHT.Tick += new EventHandler ( timerRIGHT_Tick );
//move snake 5 spaces
}
break;
}
}
void timerRIGHT_Tick ( object sender, EventArgs e )
{
btnSnake.Location = new Point ( btnSnake.Location.X + 5, btnSnake.Location.Y );
}
void timerDOWN_Tick ( object sender, EventArgs e )
{
btnSnake.Location = new Point ( btnSnake.Location.X, btnSnake.Location.Y + 5 );
}
void timerLEFT_Tick ( object sender, EventArgs e )
{
btnSnake.Location = new Point ( btnSnake.Location.X - 5, btnSnake.Location.Y );
}
void timerUP_Tick ( object sender, EventArgs e )
{
//move snake 5 spaces
btnSnake.Location = new Point ( btnSnake.Location.X, btnSnake.Location.Y - 5 );
}
private void setLabelStatus(string text, Color color)
{
lblStatus.Text = "";
lblStatus.BackColor = color;
lblStatus.Text = text;
}
//main method initializes a snake game
static void Main(string[] args)
{
Snake snake = new Snake();
}
}
}
Upvotes: 3
Views: 1877
Reputation: 4002
Declare the Timers for each key as private globals then call the Start()
and Stop()
methods when you wish to change the directions.
// Declare
Timer UpTimer = new Timer();
Timer DownTimer = new Timer();
Timer LeftTimer = new Timer();
Timer RightTimer = new Timer();
// If Left Key pressed
UpTimer.Stop();
DownTimer.Stop();
LeftTimer.Start();
RightTimer.Stop();
Upvotes: 1
Reputation: 8766
You need to keep track of which timers you've already created, so you can delete them later (presumably inside a 'stop' method).
Either that, or you could have one timer for movement that always fires (start it at game startup), and then store what the 'current direction' is and use that inside the timer.
The second method is probably better as you could roll some of your "per frame" game logic in there later (checking if the snake has eaten itself, etc) instead of duplicating it across all the various timer callbacks.
Upvotes: 4