ProgLab1_winforms/GUI/SnakeForm.cs

195 lines
5.5 KiB
C#
Raw Permalink Normal View History

using laba3.Subprograms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Formats.Asn1.AsnWriter;
namespace ProgLab1.GUI
{
public partial class SnakeForm : Form
{
private System.Windows.Forms.Timer gameTimer = new System.Windows.Forms.Timer();
private List<Point> snake = new List<Point>();
private Point food = Point.Empty;
private int tileSize = 20;
private string direction = "Right";
private string nextDirection = "Right";
private bool isGameOver = false;
private int score = 0;
private Level level;
private int sizex;
private int sizey;
private Random rand = new Random();
public SnakeForm(Level level, int sizex, int sizey, Form onCloseForm)
{
this.level = level;
this.sizex = sizex;
this.sizey = sizey;
InitializeComponent();
InitializeGame();
this.FormClosing += new FormClosingEventHandler((object sender, FormClosingEventArgs e) => {onCloseForm.Show();});
}
private void InitializeGame()
{
this.Text = "Snake Game";
this.ClientSize = new Size(sizex*tileSize, sizey*tileSize);
this.DoubleBuffered = true;
this.KeyDown += OnKeyDown;
this.Paint += OnPaint;
gameTimer.Interval = level switch
{
Level.Low => 250,
Level.Medium => 125,
Level.High => 50,
_ => 500,
}; ;
gameTimer.Tick += OnGameTick;
gameTimer.Start();
ResetGame();
}
private void ResetGame()
{
snake.Clear();
snake.Add(new Point(2, sizey/2)); // Initial snake head
snake.Add(new Point(1, sizey/2)); // Initial snake body
snake.Add(new Point(0, sizey/2)); // Initial snake tail
direction = "Right";
nextDirection = "Right";
isGameOver = false;
SpawnFood();
}
private void SpawnFood()
{
int maxX = sizex;
int maxY = sizey;
do
{
food = new Point(rand.Next(0, maxX), rand.Next(0, maxY));
} while (snake.Contains(food));
}
private void OnGameTick(object sender, EventArgs e)
{
if (isGameOver) return;
// Update direction
direction = nextDirection;
// Calculate new head position
Point newHead = snake[0];
switch (direction)
{
case "Up": newHead.Y--; break;
case "Down": newHead.Y++; break;
case "Left": newHead.X--; break;
case "Right": newHead.X++; break;
}
// Check collisions
if (newHead.X < 0 || newHead.Y < 0 ||
newHead.X >= sizex ||
newHead.Y >= sizey ||
snake.Contains(newHead))
{
isGameOver = true;
gameTimer.Stop();
Dialogs.GameOver($"Счёт: {score}");
this.Close();
return;
}
// Move snake
snake.Insert(0, newHead);
if (newHead == food)
{
SpawnFood();
addScore();
}
else
{
snake.RemoveAt(snake.Count - 1); // Remove tail
}
this.Invalidate(); // Redraw
}
private void OnPaint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// Draw snake
foreach (Point p in snake)
{
DrawTile(g, p.X, p.Y, Brushes.Green);
}
// Draw food
DrawTile(g, food.X, food.Y, Brushes.Red);
// Draw grid (optional)
for (int x = 0; x < this.ClientSize.Width; x += tileSize)
{
for (int y = 0; y < this.ClientSize.Height; y += tileSize)
{
g.DrawRectangle(Pens.Gray, x, y, tileSize, tileSize);
}
}
}
private void DrawTile(Graphics g, int x, int y, Brush brush)
{
g.FillRectangle(brush, x * tileSize, y * tileSize, tileSize, tileSize);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (isGameOver && e.KeyCode == Keys.R)
{
ResetGame();
gameTimer.Start();
return;
}
switch (e.KeyCode)
{
case Keys.Up: if (direction != "Down") nextDirection = "Up"; break;
case Keys.Down: if (direction != "Up") nextDirection = "Down"; break;
case Keys.Left: if (direction != "Right") nextDirection = "Left"; break;
case Keys.Right: if (direction != "Left") nextDirection = "Right"; break;
}
}
private void addScore()
{
score += level switch
{
Level.Low => 50,
Level.Medium => 100,
Level.High => 250,
_ => 1,
};
}
public enum Level
{
Low,
Medium,
High
}
}
}