Загрузка данных
C# 18.05
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;
namespace WindowsFormsApp1805
{
public partial class Form_Snake : Form
{
private const int CELL_SIZE_PIXELS = 30; // Размер клетки игрового поля, в пикселях
private const int ROWS_NUMBER = 15; // Количество рядов в игровом поле
private const int COLS_NUMBER = 15; // Количество столбцов в игровом поле
private const int FIELD_LEFT_OFFSET_PIXELS = 40; // Отступ в пикселях от левого края формы
private const int FIELD_TOP_OFFSET_PIXELS = 15; // Отступ в пикселях от правого края формы
private const int INITIAL_SNAKE_SPEED_INTERVAL = 1000; // Задержка (свойство "Interval") для основного игрового таймера TimerGameLoop
private const int SPEED_INCREMENT_BY = 10; // На сколько миллисекунд увеличить скорость "Змейки" при очередном поглощении змейкой "Еды"
private enum SnakeDirection
{
Left,
Right,
Up,
Down
}
private SnakeDirection snakeDirection = SnakeDirection.Up; // Текущее направление движения "Змейки"
private LinkedList<Point> snake = new LinkedList<Point>(); // Список точек, содержащих координаты всего "тела Змейки"
private Point food; // Точка, содержащая координаты "Еды" для "Змейки"
private Random rand = new Random(); // Генератор псевдослучайных чисел. нужен для генерации очередной "Еды" в произвольном месте игрового поля
private bool isGameEnded; // Признак: игра завершена?
private bool isGamePaused;
private int points = 0;
private int foodEaten = 0;
public Form_Snake()
{
InitializeComponent();
}
private void MoveSnake()
{
LinkedListNode<Point> head = snake.First;
Point newHead = new Point(0, 0);
switch (snakeDirection)
{
case SnakeDirection.Left:
newHead = new Point(head.Value.X, head.Value.Y - 1); break;
case SnakeDirection.Right:
newHead = new Point(head.Value.X, head.Value.Y + 1); break;
case SnakeDirection.Down:
newHead = new Point(head.Value.X + 1, head.Value.Y); break;
case SnakeDirection.Up:
newHead = new Point(head.Value.X - 1, head.Value.Y); break;
}
if (snake.Any(point => point.X == newHead.X && point.Y == newHead.Y))
{
Invalidate();
GameOver();
return;
}
snake.AddFirst(newHead);
if(newHead.X == food.X && newHead.Y == food.Y)
{
AddPlayerPoints();
foodEaten++;
GenerateFood();
}
else
{
snake.RemoveLast();
}
}
private bool IsGameOver()
{
LinkedListNode<Point> head = snake.First;
switch (snakeDirection)
{
case SnakeDirection.Left: return head.Value.Y - 1 < 0; break;
case SnakeDirection.Right: return head.Value.Y + 1 >= COLS_NUMBER; break;
case SnakeDirection.Down: return head.Value.X + 1 >= ROWS_NUMBER; break;
case SnakeDirection.Up: return head.Value.X - 1 < 0; break;
}
return false;
}
private void GameOver()
{
isGameEnded = true;
timer1.Stop();
if (MessageBox.Show("Конец игры! Начать заново?", "Конец игры", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
StartGame();
}
private void Form_Snake_Load(object sender, EventArgs e)
{
DoubleBuffered = true;//чтобы при отрисовке всех элементов игры включить режим двойной буферизации для формы
BackColor = Color.Black;
StartGame();
}
private void StartGame()
{
//GenerateFood();
InitializeSnake();
isGameEnded = false;
isGamePaused = false;
points = 0;
foodEaten = 0;
timer1.Start();
timer1.Interval = INITIAL_SNAKE_SPEED_INTERVAL;
}
private void PauseOrUnspaceGame()
{
if (!isGamePaused)
{
timer1.Stop();
Invalidate();
}
else timer1.Start();
isGamePaused = !isGamePaused;
}
private void InitializeSnake()
{
snakeDirection = SnakeDirection.Up;
snake.Clear();
snake.AddFirst(new Point(ROWS_NUMBER - 1, COLS_NUMBER / 2 - 1));
}
private void GenerateFood()
{
bool isFoodClashWithSnake;
do
{
food = new Point(rand.Next(0, ROWS_NUMBER), rand.Next(0, COLS_NUMBER));
isFoodClashWithSnake = false;
foreach (Point p in snake)
{
if (p.X == food.X && p.Y == food.Y)
{
isFoodClashWithSnake = true;
break;
}
}
} while (isFoodClashWithSnake);
timer1.Interval -= SPEED_INCREMENT_BY;
}
private void AddPlayerPoints()
{
if (food.X == 0 && food.Y == 0 ||
food.X == ROWS_NUMBER - 1 && food.Y == COLS_NUMBER - 1 ||
food.X == 0 && food.Y == COLS_NUMBER - 1 ||
food.X == ROWS_NUMBER - 1 && food.Y == 0)
points += 1000;
else if (food.X == 0 || food.X == ROWS_NUMBER - 1 || food.Y == COLS_NUMBER - 1 || food.Y == 0)
points += 500;
else points += 250;
}
private void DrawStatusAndKeyboardHints(Graphics g)
{
Font fontState = new Font("Console", 14);
int statusLeftOffset = FIELD_LEFT_OFFSET_PIXELS + CELL_SIZE_PIXELS * COLS_NUMBER + 10;
g.DrawString($"Длина змейки {snake.Count}", fontState, Brushes.Lime,
new Point(statusLeftOffset, 10));
g.DrawString($"Скорость {INITIAL_SNAKE_SPEED_INTERVAL - timer1.Interval+5}", fontState, Brushes.Lime,
new Point(statusLeftOffset, 30));
g.DrawString($"ОЧки {snake.Count}", fontState, Brushes.Lime,
new Point(statusLeftOffset, 50));
g.DrawString($"Еды съедено {foodEaten}", fontState, Brushes.Lime,
new Point(statusLeftOffset, 70));
g.DrawString($"Управление", fontState, Brushes.White,
new Point(statusLeftOffset, 160));
g.DrawString($"Вверх: W", fontState, Brushes.White,
new Point(statusLeftOffset, 190));
g.DrawString($"Вниз: S", fontState, Brushes.White,
new Point(statusLeftOffset, 210));
g.DrawString($"Влево: A", fontState, Brushes.White,
new Point(statusLeftOffset, 230));
g.DrawString($"Вправо: D", fontState, Brushes.White,
new Point(statusLeftOffset, 250));
g.DrawString($"Пауза: Space", fontState, Brushes.White,
new Point(statusLeftOffset, 270));
g.DrawString($"Выход: Escape", fontState, Brushes.White,
new Point(statusLeftOffset, 310));
if(isGamePaused)
{
g.DrawString($"Игра на паузе ...", fontState, Brushes.Yellow,
new Point(statusLeftOffset, 350));
}
fontState.Dispose();
}
private void DrawGrid(Graphics g)
{
for (int row = 0; row <= ROWS_NUMBER; row++)
{
g.DrawLine(Pens.Cyan,
new Point(FIELD_LEFT_OFFSET_PIXELS,
FIELD_TOP_OFFSET_PIXELS + row * CELL_SIZE_PIXELS),
new Point(FIELD_LEFT_OFFSET_PIXELS + CELL_SIZE_PIXELS * ROWS_NUMBER,
FIELD_TOP_OFFSET_PIXELS + row * CELL_SIZE_PIXELS)
);
for (int col = 0; col <= COLS_NUMBER; col++)
{
g.DrawLine(Pens.Cyan,
new Point(FIELD_LEFT_OFFSET_PIXELS + col * CELL_SIZE_PIXELS,
FIELD_TOP_OFFSET_PIXELS),
new Point(FIELD_LEFT_OFFSET_PIXELS + col * CELL_SIZE_PIXELS,
FIELD_TOP_OFFSET_PIXELS + CELL_SIZE_PIXELS * COLS_NUMBER)
);
}
}
}
private void DrawSnake(Graphics g)
{
foreach (Point p in snake)
{
g.FillRectangle(Brushes.Lime, new Rectangle(
FIELD_LEFT_OFFSET_PIXELS + p.Y * CELL_SIZE_PIXELS + 1,
FIELD_TOP_OFFSET_PIXELS + p.X * CELL_SIZE_PIXELS + 1,
CELL_SIZE_PIXELS - 1,
CELL_SIZE_PIXELS - 1));
}
}
private void DrawFood(Graphics g)
{
g.FillRectangle(Brushes.Red, new Rectangle(
FIELD_LEFT_OFFSET_PIXELS + food.Y * CELL_SIZE_PIXELS + 1,
FIELD_TOP_OFFSET_PIXELS + food.X * CELL_SIZE_PIXELS + 1,
CELL_SIZE_PIXELS - 1,
CELL_SIZE_PIXELS - 1));
}
private void Form_Snake_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
DrawGrid(g);
DrawFood(g);
DrawSnake(g);
DrawStatusAndKeyboardHints(g);
}
private void timer1_Tick(object sender, EventArgs e)
{
if (IsGameOver()) GameOver();
else { MoveSnake(); Invalidate(); }
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.Left:
ChangedSnakeDirection(SnakeDirection.Right, SnakeDirection.Left); break;
case Keys.Right:
ChangedSnakeDirection(SnakeDirection.Left, SnakeDirection.Right); break;
case Keys.Down:
ChangedSnakeDirection(SnakeDirection.Up, SnakeDirection.Down); break;
case Keys.Up:
ChangedSnakeDirection(SnakeDirection.Down, SnakeDirection.Up); break;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void ChangedSnakeDirection(SnakeDirection restrictedDirection, SnakeDirection newDirection)
{
if (snakeDirection != restrictedDirection)
{
snakeDirection = newDirection;
}
}
private void Form_Snake_KeyDown(object sender, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Left: case Keys.A:
ChangedSnakeDirection(SnakeDirection.Right, SnakeDirection.Left); break;
case Keys.Right:
case Keys.D:
ChangedSnakeDirection(SnakeDirection.Left, SnakeDirection.Right); break;
case Keys.Down:
case Keys.S:
ChangedSnakeDirection(SnakeDirection.Up, SnakeDirection.Down); break;
case Keys.Up:
case Keys.W:
ChangedSnakeDirection(SnakeDirection.Down, SnakeDirection.Up); break;
case Keys.Space:
if(isGameEnded && !timer1.Enabled)
{
StartGame();
}
else
{
PauseOrUnspaceGame();
}
break;
}
}
}
}
______________________________________________________________________________________________________
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;
namespace WindowsFormsApp1805
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void змейкаToolStripMenuItem_Click(object sender, EventArgs e)
{
CheckIsOpenForm(new Form_Snake());
}
void CheckIsOpenForm(Form form)
{
string text = form.Text;
bool isOpen = false;
if (Application.OpenForms.Count != 0)
{
foreach(Form s in Application.OpenForms)
{
if(s.Text == text)
{
isOpen = true;
s.WindowState = FormWindowState.Normal;
s.BringToFront();
break;
}
}
}
if (!isOpen)
{
form.MdiParent = this;
form.Show();
}
}
}
}