I got ideas from this tutorial: Python Snake Game
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Snake
{
public partial class Form1 : Form
{
// Snake list of (x, y) positions
private List<Point> _snake = new List<Point>()
{
new Point(10, 10)
};
// Snake movement direction
private Point _snakeDir = new Point(10, 0);
// Food
private Point _food = new Point();
// Random generator
private Random _rnd = new Random();
// Game field size
private int _fieldWidth = 200;
private int _fieldHeight = 200;
// Snake step
private int _snakeStep = 10;
public Form1()
{
InitializeComponent();
// Centers the form on the current screen
CenterToScreen();
// Set a game field size
ClientSize = new Size(_fieldWidth, _fieldHeight);
// Generate an initial random position for the food
GenerateFood();
// Create a timer for the GameLoop method
var timer = new Timer();
timer.Tick += GameLoop;
timer.Interval = 200;
timer.Start();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Draw();
}
private void GameLoop(object sender, System.EventArgs e)
{
Update();
Invalidate();
}
private void Update()
{
// Calc a new position of the head
Point newHeadPosition = new Point(
_snake[0].X + _snakeDir.X,
_snake[0].Y + _snakeDir.Y
);
// Insert new position in the beginning of the snake list
_snake.Insert(0, newHeadPosition);
// Remove the last element
_snake.RemoveAt(_snake.Count - 1);
// Check collision with the food
if (_snake[0].X == _food.X &&
_snake[0].Y == _food.Y)
{
// Add new element in the snake
_snake.Add(new Point(_food.X, _food.Y));
// Generate a new food position
GenerateFood();
}
}
private void Draw()
{
DrawFood();
DrawSnake();
}
private void DrawSnake()
{
foreach (var cell in _snake)
{
DrawRect(cell.X, cell.Y, Color.Green);
}
}
private void DrawFood()
{
DrawRect(_food.X, _food.Y, Color.OrangeRed);
}
private void DrawRect(int x, int y, Color color, int size = 10)
{
Graphics g = CreateGraphics();
SolidBrush brush = new SolidBrush(color);
g.FillRectangle(brush, new Rectangle(x, y, size, size));
brush.Dispose();
g.Dispose();
}
private void GenerateFood()
{
_food.X = 10 * _rnd.Next(0, _fieldHeight / 10 - 1);
_food.Y = 10 * _rnd.Next(0, _fieldHeight / 10 - 1);
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case 'w':
_snakeDir.X = 0;
_snakeDir.Y = -_snakeStep;
break;
case 'a':
_snakeDir.X = -_snakeStep;
_snakeDir.Y = 0;
break;
case 's':
_snakeDir.X = 0;
_snakeDir.Y = _snakeStep;
break;
case 'd':
_snakeDir.X = _snakeStep;
_snakeDir.Y = 0;
break;
}
}
}
}