Краткое описание классов
Program – начальный класс который имеет метод Main(), с этого метода начианается работа программы. В нем выхывается метод Run, для класса UserBox.
UserBox – предоставляет пользователю окно ввода имени. И выводит начальную информацию о игре.
проектирование игра абстракция инкапсуляция алгоритм
SnakeCSharpWindow – главный класс в моем проекте. В нем реализована логика игры.
Person - класс описания игрока.
Table – класс описывает таблицу рекордов.
Dir – класс описывает одну часть змейки.
Apple – класс описывает яблоко которое должна съесть змея.
AboutBox1 – класс описывает окно «О программе»
Основные алгоритмы
Одним из основных методов является метод SnakeCSharpWindow_Paint. В этом методе проверяется столкновения змейки с хвостом, стенкой или яблоком. И вызывается нужный метод. Также проверяется является ли следующее яблоко бонусным.
Метод SnakeCSharpWindow_KeyDown отслеживает нажатие клавиш.
Метод TheEnd вызывается в случае поражения, а метод Triumph в случае победы(когда игрок набирает 1000 очков).
Исходный код
Класс Program.
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new UserBox());
}
}
Класс UserBox – предоставляет начальное окно программы. В нем содержится небольшое описание процесса игры и поле для ввода имени пользователя.
public partial class UserBox : Form
{
public UserBox()
{
InitializeComponent();
label2.Text = "Игра змейка. \nЦель игры: управляя змейкой собирать яблоки которые появляются на игровом поле. \nДля управления змейкой используйте клавиши вниз, вверх, влево, вправо \nДля начала игры нажмите любую клавишу управления и змейка начнет движение. \nДля продалжения нажмите \"Enter\" ";
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
this.Hide();
var x = new SnakeCSharpWindow(textBox1.Text);
x.Show();
}
}
}
Класс SnakeCSharpWindow - основной класс в котором описана логика игры.
public partial class SnakeCSharpWindow : Form
{
int points = 0;
int count_apple = 0;
int bonus = 1;
bool m = false;
private Timer t = new Timer();
private Dir dir = new Dir(0, 0);
static private LinkedList<Dir> snake = new LinkedList<Dir>(); //LinkedList doesn't have add...
public Table table = new Table();
private Person person = new Person();
private Apple apple = new Apple(false, snake);
public SnakeCSharpWindow(string player)
{
MainMenu menu = new MainMenu();
MenuItem item = new MenuItem("&Файл");
menu.MenuItems.Add(item);
// Add the menu entries to the "File" menu
item.MenuItems.Add(new MenuItem("&Выход", new EventHandler(Exit)));
item = new MenuItem("&Уровень");
menu.MenuItems.Add(item);
// Add the menu entries to the "File" menu
item.MenuItems.Add(new MenuItem("Быстрее", new EventHandler(LevelUp)));
item.MenuItems.Add(new MenuItem("Медленне", new EventHandler(LevelDown)));
// Create a new Menu
item = new MenuItem("&Помощь");
menu.MenuItems.Add(item);
// Add the menu entries to the "Help" menu
item.MenuItems.Add(new MenuItem("&О проекте", new EventHandler(OnAbout)));
// Attach the menu to the window
Menu = menu;
this.ClientSize = new System.Drawing.Size(640, 480);
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Name = "SnakeCSharpWindow";
this.Text = "SnakeCSharp";
this.Paint += new PaintEventHandler(SnakeCSharpWindow_Paint);
this.KeyDown += new KeyEventHandler(SnakeCSharpWindow_KeyDown);
t.Tick += new EventHandler(t_Tick);
t.Start();
snake.AddFirst(new Dir(10, 10));
person.Player = player;
}
private void LevelUp(object sender, EventArgs ev)
{
if (bonus < 5)
{
t.Interval -= 20;
bonus += 1;
}
}
private void LevelDown(object sender, EventArgs ev)
{
if (bonus > 1)
{
t.Interval += 20;
bonus -= 1;
}
}
private void OnAbout(object sender, EventArgs ev)
{
AboutBox1 about = new AboutBox1();
about.ShowDialog();
about = null;
}
void SnakeCSharpWindow_KeyDown(object sender, KeyEventArgs e) //Change direction
{
if (e.KeyCode == Keys.Left) { dir = new Dir(-10, 0); }
if (e.KeyCode == Keys.Right) { dir = new Dir(10, 0); }
if (e.KeyCode == Keys.Up) { dir = new Dir(0, -10); }
if (e.KeyCode == Keys.Down) { dir = new Dir(0, 10); }
if (e.KeyCode == Keys.Escape) { this.Close(); }
}
void SnakeCSharpWindow_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(new Pen(Color.Red, 3), 0, 0, 640, 480);
e.Graphics.FillRectangle(apple.Color, apple.Coordinates.X, apple.Coordinates.Y, 10, 10);
e.Graphics.DrawString(points.ToString(), new Font("Arial", 30), new SolidBrush(Color.Orange), new PointF(540, 10));
e.Graphics.DrawString("Уровень: " + bonus.ToString(), new Font("Arial", 20), new SolidBrush(Color.DarkBlue), new PointF(10, 10));
if (points >= (bonus *200)) { LevelUp(sender, e); }
int i = 0;
int point = 1;
if (m) { point = 3; }
foreach (Dir cur in snake) //Draw snake and check self collision
{
e.Graphics.FillRectangle(Brushes.Black, cur.point.X, cur.point.Y, 10, 10);
if (i != 0 && snake.First.Value.point.X == cur.point.X && snake.First.Value.point.Y == cur.point.Y) { TheEnd(e); }
i++;
}
if (snake.First.Value.point.X == 640 | snake.First.Value.point.Y == 480 | snake.First.Value.point.Y == 0 | snake.First.Value.point.X == 0) { TheEnd(e); }
if (snake.First.Value.point.X == apple.Coordinates.X && snake.First.Value.point.Y == apple.Coordinates.Y) //Collision apple
{
if (count_apple % 5 == 0) { apple = new Apple(true, snake); m = true; }
else { apple = new Apple(false, snake); m = false; }
count_apple++;
points += (point * bonus);
snake.AddLast(snake.Last.Value);
if (points >= 1000) { Triumph(e); }
}
}
void t_Tick(object sender, EventArgs e) //Move Snake
{
snake.AddFirst(new Dir(snake.First.Value.point.X + dir.point.X, snake.First.Value.point.Y + dir.point.Y));
snake.RemoveLast();
this.Refresh();
}
void TheEnd(PaintEventArgs e)
{
String drawString = "The End";
Font drawFont = new Font("Arial", 15);
SolidBrush drawBrush = new SolidBrush(Color.Red);
PointF drawPoint = new PointF(270, 10);
e.Graphics.DrawString(drawString, drawFont, drawBrush, drawPoint);
t.Dispose();
person.Points = points;
table.Add(person);
e.Graphics.DrawString("Ваш результат: ", drawFont, new SolidBrush(Color.Green), new PointF(200, 30));
e.Graphics.DrawString(person.Player + " : " + Convert.ToString(person.Points), drawFont, new SolidBrush(Color.Green), new PointF(200, 50));
e.Graphics.DrawString("Рекорды", new Font("Arial", 15), new SolidBrush(Color.Black), new PointF(250, 70));
List<Person> temp = table.GetAllPersons();
int w = 90;
drawFont = new Font("Tahoma", 15);
drawBrush = new SolidBrush(Color.Orange);
int n = temp.Count;
if (n > 10) { n = 10; }
for (int i = 0; i < n; i++)
{
e.Graphics.DrawString(temp[i].Player + " : " + Convert.ToString(temp[i].Points), drawFont, drawBrush, new PointF(200, w));
w += 20;
}
table.Close();
}
void Triumph(PaintEventArgs e)
{
t.Dispose();
String drawString = "Победа";
Font drawFont = new Font("Arial", 100);
SolidBrush drawBrush = new SolidBrush(Color.Red);
PointF drawPoint = new PointF(100, 10);
e.Graphics.DrawString(drawString, drawFont, drawBrush, drawPoint);
drawFont = new Font("Arial", 15);
t.Stop();
person.Points = points;
table.Add(person);
e.Graphics.DrawString("Ваш результат: ", drawFont, new SolidBrush(Color.Green), new PointF(200, 130));
e.Graphics.DrawString(person.Player + " : " + Convert.ToString(person.Points), drawFont, new SolidBrush(Color.Green), new PointF(200, 150));
e.Graphics.DrawString("Рекорды", new Font("Arial", 15), new SolidBrush(Color.Black), new PointF(250, 170));
List<Person> temp = table.GetAllPersons();
temp.OrderByDescending(y => y.Points);
int w = 190;
drawFont = new Font("Tahoma", 15);
drawBrush = new SolidBrush(Color.Orange);
int n = temp.Count;
if (n > 10) { n = 10; }
for (int i = 0; i < n; i++)
{
e.Graphics.DrawString(temp[i].Player + " : " + Convert.ToString(temp[i].Points), drawFont, drawBrush, new PointF(200, w));
w += 20;
}
table.Close();
}
public void Exit(object sender, EventArgs e)
{
this.Close();
}
}
Класс AboutBox1 – предоставляет нам окно «О программе»
public AboutBox1()
{
InitializeComponent();
this.Text = String.Format("О проекте");
this.labelProductName.Text = "Курсовой проект \"Змейка\"";
this.labelVersion.Text = String.Format("Студента группы 052001");
this.labelCopyright.Text = "Горбача Андрея";
this.labelCompanyName.Text = null;
this.textBoxDescription.Text = "Программа создана как курсовой проект. \n"+ "Для повышения знаний и умений создателя.\n" +
"Программа предназначена для любых возрастов.\n";
}
Класс Dir – описывает квадрат, из которого состоит змейка.
public class Dir
{
public Point point { get; set; }
public Dir(int x, int y)
{
point = new Point(x, y);
}
}
Класс Apple – описывает яблоко.
public class Apple
{
public Apple(bool b, LinkedList<Dir> snake)
{
int x = myRnd.Next(64 - 1) * 10;
int tx = myRnd.Next(2, 64 - 2) * 10;
int ty = myRnd.Next(2, 48 - 2) * 10;
foreach (Dir cur in snake) //Draw snake and check self collision
{
if (snake.First.Value.point.X == tx && snake.First.Value.point.Y == ty)
{
tx += 1;
ty += 1;
}
}
if (tx >= ((64 - 1) * 10)) { tx -= 1; }
if (ty >= ((64 - 1) * 10)) { ty -= 1; }
Coordinates = new Point(myRnd.Next(2, 64 - 2) * 10, myRnd.Next(2, 48 - 2) * 10);
if (b) { Color = Brushes.Red; }
else Color = Brushes.Green;
}
private static Random myRnd = new Random();
public Point Coordinates
public Brush Color { get; set; }
}
Класс Person – описывает игрока.
public class Person
{
public string Player { get; set; }
public int Points { get; set; }
}
Класс Table – описывает таблицу рекордов.
public partial class Table : Person
{
public StreamWriter FW;
public StreamReader FR;
public FileStream fileStream;
public List<Person> table = new List<Person>();
public Table()
{
fileStream = new FileStream("Catalog.txt", FileMode.OpenOrCreate);
FW = new StreamWriter(fileStream);
FR = new StreamReader(fileStream);
RedToListRecord();
}
public void Add(Person x)
{
table.Add(x);
WritePerson(x);
}
public void WritePerson(Person x)
{
FW.WriteLine(x.Player);
FW.WriteLine(x.Points);
}
public List<Person> GetAllPersons()
{ return table; }
public void RedToListRecord()
{
while (FR.EndOfStream == false)
{
Person p = new Person();
p.Player = FR.ReadLine();
p.Points = Convert.ToInt32(FR.ReadLine());
table.Add(p);
}
Sort();
}
public void Sort()
{
table = table.OrderByDescending(y => y.Points).ToList();
}
public void Close()
{
FW.Close();
FR.Close();
fileStream.Close();
}
}
