Игра "змейка" с делегатами, событиями и потоками - C#
Формулировка задачи:
Здравствуйте! Задали курсовую, написать игру на С# с делегатами и событиями, а также, чтобы передвижение объектов выполнялось в потоке. Сроки жмут, пыталась переделать вот эту змейку, но ничего не вышло!! помогите пожалуйста:*:*:*
Решение задачи: «Игра "змейка" с делегатами, событиями и потоками»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using System.Threading; //<------ Подключим библиотеку для работы с потоками. namespace Example { public class Program : Form { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new Program()); } //класс для удобства работы с координатами яблока и сегментов змеи public class coord { public int X; public int Y; public coord(int x, int y) { X = x; Y = y; } } //Timer timer = new Timer(); Random rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); // условная ширина "поля действия" в клетках, высота и размер клетки в пикселах int W = 20, H = 30, S = 20; // собственно змея: список сегментов(нулевой индекс в списке - голова змеи) List<coord> snake = new List<coord>(); coord apple; // координаты яблока int way = 0; // направление движения змеи: 0 - вверх, 1 - вправо, 2 - вниз, 3 - влево int apples = 0; // количество собранных яблок int stage = 1; // уровень игры int score = 0; // набранные очки в игре int SleepInterval = 200; // <----- задержка передвижения в мс Thread t; Program() { this.Text = "Snake"; // заголовок формы this.FormBorderStyle = FormBorderStyle.FixedDialog; // мышкой нельзя растягивать форму this.MaximizeBox = false; // делаем недоступной кнопку "развернуть во весь экран" this.StartPosition = FormStartPosition.CenterScreen; // форма отображается по центру экрана this.DoubleBuffered = true; // для прорисовки int caption_size = SystemInformation.CaptionHeight; // высота шапки формы int frame_size = SystemInformation.FrameBorderSize.Height; // ширина границы формы // устанавливаем размер внутренней области формы W * H с учетом высоты шапки и ширины границ this.Size = new Size(W * S + 2 * frame_size, H * S + caption_size + 2 * frame_size); this.Paint += new PaintEventHandler(Program_Paint); // привязываем обработчик прорисовки формы this.KeyDown += new KeyEventHandler(Program_KeyDown); // привязываем обработчик нажатий на кнопки // делаем змею из трех сегментов, с начальными координатами внизу и по-центру формы snake.Add(new coord(W / 2, H - 3)); snake.Add(new coord(W / 2, H - 2)); snake.Add(new coord(W / 2, H - 1)); apple = new coord(rand.Next(W), rand.Next(H)); // координаты яблока t = new Thread(new ThreadStart(MovingThread)); t.Start(); } // обработка нажатий на клавиши(здесь только стрелки) // меняем направление движения, если оно не противоположное void Program_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyData) { case Keys.Up: if (way != 2) way = 0; break; case Keys.Right: if (way != 3) way = 1; break; case Keys.Down: if (way != 0) way = 2; break; case Keys.Left: if (way != 1) way = 3; break; } } private void MovingThread() { while (true) { // запоминаем координаты головы змеи int x = snake[0].X, y = snake[0].Y; // в зависимости от направления вычисляем где будет голова на следующем шаге // сделал чтобы при достижении края формы голова появлялась с противоположной стороны // и змея продолжала движение switch (way) { case 0: y--; if (y < 0) GameOwer(); break; case 1: x++; if (x >= W) GameOwer(); break; case 2: y++; if (y >= H) GameOwer(); break; case 3: x--; if (x < 0) GameOwer(); break; } coord c = new coord(x, y); // сегмент с новыми координатами головы snake.Insert(0, c); // вставляем его в начало списка сегментов змеи(змея выросла на один сегмент) if (snake[0].X == apple.X && snake[0].Y == apple.Y) // если координаты головы и яблока совпали { apple = new coord(rand.Next(W), rand.Next(H)); // располагаем яблоко в новых случайных координатах apples++; // увеличиваем счетчик собранных яблок score += stage; // увеличиваем набранные очки в игре: за каждое яблоко прибавляем количество равное номеру уровня if (apples % 10 == 0) // после каждого десятого яблока { stage++; // повышаем уровень SleepInterval -= 10; // и уменьшаем интервал срабатывания яблока } } else // если координаты головы и яблока не совпали - убираем последний сегмент змеи(т.к. ранее добавляли новую голову) snake.RemoveAt(snake.Count - 1); for (int i = 1; i < snake.Count; i++) // <------- { if ((snake[i].X == snake[0].X) && (snake[i].Y == snake[0].Y)) GameOwer(); } Invalidate(); System.Threading.Thread.Sleep(SleepInterval); } } private void GameOwer() // <-------- завершение игры { t.Abort(); Invalidate(); } // собственно, отрисовка void Program_Paint(object sender, PaintEventArgs e) { // рисуем красным кружком яблоко, синим квадратом голову змеи и зелеными квадратами тело змеи e.Graphics.FillEllipse(Brushes.Red, new Rectangle(apple.X * S, apple.Y * S, S, S)); e.Graphics.FillRectangle(Brushes.Blue, new Rectangle(snake[0].X * S, snake[0].Y * S, S, S)); for (int i = 1; i < snake.Count; i++) e.Graphics.FillRectangle(Brushes.Green, new Rectangle(snake[i].X * S, snake[i].Y * S, S, S)); // сообщение о количестве собранных яблок, уровне и количестве очков string state = "Apples:" + apples.ToString() + "\n" + "Stage:" + stage.ToString() + "\n" + "Score:" + score.ToString(); // выводим это сообщение в левом верхнем углу e.Graphics.DrawString(state, new Font("Arial", 10, FontStyle.Italic), Brushes.Black, new Point(5, 5)); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д