-
Snake game WinForms
hi, I recently started to build a snake game in c# using WinForms and i got stuck.
I'm not sure how to build the main loop.
In C I know it should look like this:
Code:
int main()
{
Initialize()...
while (NoCollision)
{
moveSnake();
drawSnake();
}
Endgame()..
}
but I don't know how to implement the concept in Forms. I guess it got something to do with threads or methods that are already exist in the lang'.
So how is it should look like?
Thanks a lot (:
-
A main() likely already exists. Typically, that code would go there in a console application. In a WinForms application, it would be triggered by one of the many form's events or the events of controls placed on it like when a button on a form is clicked, the form is loading, some text is entered into a textbox, etc. Your loop otherwise looks fine to me (I'm a little rusty as I haven't been using C# that much over the last few months). If you continue to have any problems post the errors its giving you.
-
One way would be to add a Timer that triggers an event to calculates the new snake and invalidate the form causing it to redraw. To handle keypresses add a handler to the KeyDown event for the form.
-
1) You download Visual Studio C#
2) You built a C# Windows Forms project
3) Read some very basic tutorial about events
Then basically you would have
Code:
private void KeyDownEvent(object sender, EventArgs e)
{
if (e.Key == Keys.Down)
{
Snake.MoveDown();
}
else if ...
}
Every time you press an arrow button then the Snake will move accordingly because the even will be triggered. You basically don't have to do anything else.
The snake can be an List<Panel>. The Panel is just a square vizualized so you just need to move them (changing the Location property) and you have your Snake game.
So
4) Read a very basic tutorial about Panels
5) Search some more for timer etc etc
-
Thank you.
Should I create a function for the form paint or i can use the timer function for it?
Should I re-draw the whole snake or only the parts that has changed?
If I'll make a method for each direction wouldn't it be a code duplication? and how can I make the snake move while nothing is pressed?
-
Actually, you need a timer anyway for the Snake game. Every X seconds it will redraw ONLY the moved parts and the food if eaten. The parts that are redrawn are the head, the tail and one more piece is moved from the back to the front.
Well, I think you only have a choice of a rectangle so it would be the whole snake. Though, invalidating everything is OK if X is not too small.
The event for a key will store the last pressed key. That will be used to determine where the snake moves every X seconds.
NOTE: You need to disable automatic invalidation if you go with Panels since everytime you move them the automatically invalidate. Just disable this and invalidate every X seconds
-
ok, now I got somehing like this:
Code:
private void FormGame_KeyDown(object sender, KeyEventArgs e)
{
key = e.KeyCode;
}
Code:
private void timer1_Tick(object sender, EventArgs e)
{
switch (key)
{
case Keys.Up:
snake.MoveUp(); break;
case Keys.Down:
snake.MoveDown(); break;
case Keys.Left:
snake.MoveLeft(); break;
case Keys.Right:
snake.MoveRight(); break;
}
snake.ReDraw(); // Re-Draws the new head and erases the previous tail
}
I'm trying to think of a way to block the option to move to the opposite direction, because now he can move left and just by a click - move right.
Should I save the previous direction?
I have another problem: When he start a new game, I just do:
Code:
snake = new Snake(this.CreateGraphics());
key = Keys.Left;
snake.Draw();
timer1.Start();
but it leaves the previous snake drawn. How can I create a function that clean the traces which would be called when the snake object is disposed?
-
To block the option of moving in the opposite direction you would just check if current direction == up or down then the options to move are left and right, otherwise the options to move are up and down.
I would move all the key-logic to the keydown function and just save the direction of the snake for the next tick. Then when the timer ticks again you move the snake based on the next direction.
To clear what has been drawn use the Graphics.Clear method
Graphics.Clear Method (System.Drawing)
-
It is hard to implement anything real-time in Forms b/c it is not a real-time system. You can either use a timer to re-draw the screen or you can look into overriding the WndProc and/or creating a windows hook via SetWindowHookEx() and hook into the WndProc at the lowest level before the messages even get to the window. To do this you will have to bring in some of the Windows hook API calls and use P/Invoke to use them.
You can also check out this link. It uses the same idea that old MFC programs used when they used the application idle message to run their game loop.
http://blogs.msdn.com/b/tmiller/arch...05/415008.aspx