I'm attempting to create a simple snake game in C# visual studio as an exercise. I have very little knowledge of the Windows Forms App, but it seemed like the easiest way to access drawing and user input with the arrows.
Is this a good framework to use for a simple game like this in C#?
But here is my real question. I'm trying to create the game loop which loops about every second, and changes where the head of the snake is going to be drawn next. But I cannot figure out how to call the Paint event multiple times. It seems like it calls once, and then exits. If I put a while() loop inside of the paint method with Thread.Sleep(), it draws a rectangle every second, but I don't have access to the KeyEventArgs or anything else because the running code is trapped inside the Paint call.
I want the initial paint call to draw the starting point for the snake, and then looping paint calls, I'm guessing to another paint method(?) which asks the controller which button was pressed last, and then draws the next rectangle in that direction. What is the intended way to do this and create that game loop?
I would appreciate any information and knowledge to help teach me this process, and any other advice or input is welcome!
Here is my current code: '''
public partial class FormMain : Form
{
private readonly int pixelSize;
private readonly int gridSize;
private readonly int center;
private string currDirection;
public FormMain()
{
pixelSize = 30;
currDirection = "right";
// Calculating size of the grid based on the size of the 'pixel'
gridSize = 640 / pixelSize;
// Calculating the starting position of the snake in the center of the screen
center = (gridSize / 2) * pixelSize;
InitializeComponent();
}
private void FormMain_Paint(object sender, PaintEventArgs e)
{
// referencing the Graphics object and setting the color of the snake
Graphics g = e.Graphics;
Pen seaPen = new Pen(Color.MediumSeaGreen);
// This draws the initial center rectangle
Point currentHeadLocation = new Point(center, center);
Rectangle r;
// Here's the loop that should happen every second or so, probably in another method.
while (true)
{
r = new Rectangle(currentHeadLocation, new Size(pixelSize, pixelSize));
g.DrawRectangle(seaPen, r);
if (currDirection.Equals("right"))
{
currentHeadLocation = new Point(currentHeadLocation.X + pixelSize, currentHeadLocation.Y);
}
else if (currDirection.Equals("left"))
{
currentHeadLocation = new Point(currentHeadLocation.X - pixelSize, currentHeadLocation.Y);
}
else if (currDirection.Equals("up"))
{
currentHeadLocation = new Point(currentHeadLocation.X, currentHeadLocation.Y - pixelSize);
}
else if (currDirection.Equals("down"))
{
currentHeadLocation = new Point(currentHeadLocation.X, currentHeadLocation.Y + pixelSize);
}
Thread.Sleep(1000);
}
}
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Left:
currDirection = "left";
break;
case Keys.Right:
currDirection = "right";
break;
case Keys.Up:
currDirection = "up";
break;
case Keys.Down:
currDirection = "down";
break;
}
}
}
'''