Классическая игра “Змейка” – это идеальный проект для освоения основ программирования на C#. Она проста в концепции, но позволяет изучить важные аспекты, такие как обработка событий, работа с графикой, создание игровой логики и управление временем. В этом руководстве мы шаг за шагом создадим функциональную и визуально привлекательную версию “Змейки” с использованием библиотеки Windows Forms.
1. Настройка проекта:
Создайте новый проект в Visual Studio, выбрав “Windows Forms App (.NET Framework)”. Вы можете использовать любую версию .NET Framework, начиная с 4.5. Назовите проект “SnakeGame”.
2. Дизайн формы:
На главной форме (Form1.cs) нам понадобится лишь небольшой набор элементов:
- Timer: Этот компонент будет отвечать за обновление положения змейки и проверку столкновений с определенной частотой. Добавьте его на форму, дважды щелкнув на нем, чтобы создать обработчик события
Tick
. Назовите таймерgameTimer
. - PictureBox: Это изображение, которое будет отображать игровое поле. Установите его
SizeMode
вStretchImage
для правильного масштабирования. Назовите егоgamePanel
. Размеры PictureBox будут определять размер игрового поля.
Никаких других элементов управления нам не понадобится.
3. Игровая логика (C# код):
Внутри класса Form1
создадим необходимые переменные и методы:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
public partial class Form1 : Form
{
private Random random = new Random();
private List<Point> snake = new List<Point>();
private Point food;
private int score = 0;
private int direction = 0; // 0 - right, 1 - down, 2 - left, 3 - up
private int cellSize = 20;
private int panelWidth, panelHeight;
public Form1()
{
InitializeComponent();
// Задаем начальное положение змейки и еды
snake.Add(new Point(10, 10));
GenerateFood();
}
private void gameTimer_Tick(object sender, EventArgs e)
{
MoveSnake();
CheckCollision();
DrawGame();
}
private void MoveSnake()
{
Point head = snake[0];
Point newHead;
switch (direction)
{
case 0: newHead = new Point(head.X + 1, head.Y); break;
case 1: newHead = new Point(head.X, head.Y + 1); break;
case 2: newHead = new Point(head.X - 1, head.Y); break;
case 3: newHead = new Point(head.X, head.Y - 1); break;
default: newHead = head; break;
}
snake.Insert(0, newHead);
if (newHead != food) snake.RemoveAt(snake.Count - 1);
else {score++; GenerateFood();}
}
private void CheckCollision()
{
Point head = snake[0];
if (head.X < 0 || head.X >= panelWidth / cellSize ||
head.Y < 0 || head.Y >= panelHeight / cellSize ||
snake.Skip(1).Any(p => p == head))
{
gameTimer.Stop();
MessageBox.Show("Game Over! Your score: " + score);
}
}
private void GenerateFood()
{
food = new Point(random.Next(0, panelWidth / cellSize), random.Next(0, panelHeight / cellSize));
//Проверка на наложение с телом змейки
while (snake.Contains(food)) {
food = new Point(random.Next(0, panelWidth / cellSize), random.Next(0, panelHeight / cellSize));
}
}
private void DrawGame()
{
Bitmap bmp = new Bitmap(gamePanel.Width, gamePanel.Height);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.Black);
foreach (Point p in snake)
{
g.FillRectangle(Brushes.Green, p.X * cellSize, p.Y * cellSize, cellSize, cellSize);
}
g.FillRectangle(Brushes.Red, food.X * cellSize, food.Y * cellSize, cellSize, cellSize);
gamePanel.Image = bmp;
}
private void Form1_Load(object sender, EventArgs e)
{
panelWidth = gamePanel.Width;
panelHeight = gamePanel.Height;
gameTimer.Interval = 100; // Скорость игры
gameTimer.Start();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.Up: if (direction != 1) direction = 3; break;
case Keys.Down: if (direction != 3) direction = 1; break;
case Keys.Left: if (direction != 0) direction = 2; break;
case Keys.Right: if (direction != 2) direction = 0; break;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
4. Обработка событий:
gameTimer_Tick
: Этот обработчик события вызывается с интервалом, указанным в свойствеInterval
таймера. Здесь мы вызываем методыMoveSnake()
,CheckCollision()
иDrawGame()
.Form1_Load
: Этот обработчик вызывается при загрузке формы. Здесь мы инициализируем размеры игрового поля и запускаем таймер.ProcessCmdKey
: Этот метод перехватывает нажатия клавиш со стрелками, изменяя направление движения змейки.
5. Запуск и игра:
Запустите проект. Управляйте змейкой с помощью стрелок на клавиатуре. Игра закончится, если змейка столкнется со стеной или самой собой.
6. Улучшения:
Вы можете улучшить игру, добавив:
- Увеличение сложности: Увеличивайте скорость игры с течением времени или по достижении определенного количества очков.
- Звуковые эффекты: Добавьте звуки для поедания еды и столкновения.
- Отображение счета: Покажите текущий счет игрока на форме.
- Меню: Создайте меню для начала новой игры, настройки сложности и выхода.
- Графика: Добавьте более качественную графику для змейки и еды.
Этот подробный пример позволит вам создать базовую версию “Змейки”. Экспериментируйте, добавляйте новые функции и улучшайте игру – это лучший способ научиться программировать!