Проект Bloks C#
Давно мне не давала покоя игры кубики, где нужно было убирать несколько одноцветных блоков и получать за них очки. На самом деле вещь очень и очень затягивающая. Ее я увидел еще на карманном организаторе HP. И залипал в нее много часов. Но теперь интерес создать игру с нуля переборол мою геймерскую страсть и я написал данный проект. А так же сделал набор видео уроков которые помогут и Вам повторить мой подвиг.
1) В начале проекта я расскажу как создать картинки которые и будут частицами поля.
Результат по идее должен получиться следующий
2) Следующим шагом мы создадим проект на C# и опишем функцию создания игрового поля. На котором будет проходить игра.
Тут использовались следующие функции:
Объявим набор глобальных значений
//Размер поля по высоте и ширине экрана static int Col=10 , Row=13; //генератор случайных чисел встроенный в C# Random RND = new Random(); //список картинок из которых случайно выбираеться одна Image[] img = { global::BloksGame.Properties.Resources.Green, global::BloksGame.Properties.Resources.grey, global::BloksGame.Properties.Resources.Red, global::BloksGame.Properties.Resources.Yello,};//список картинок в виде 2х мерного массива
PictureBox[,] Pole = new PictureBox[Col, Row];
В кнопке Выход опишем завершение проветка
Application.Exit();
Опишем функцию создания поля
//Функция генерации поля void CreatePole() { //начальные координаты создания 1 блока int X = 0, //координата по Х Y = panel2.Height - 50; //координата по У //Очищаем поле игры panel2.Controls.Clear(); //создаем пустой массив картинок по размеру поля Pole = new PictureBox[Col, Row]; //начинаем перебирать строки с 0 for (int yy = 0; yy < Row; yy++) { //обнуляем позицию по Х X = 0; //Начинаем двигаться по столбцам for (int xx = 0; xx < Col; xx++) { //создаем новую картинку PictureBox pic = new PictureBox() { Image = img[RND.Next(img.Length)], //загружаем случайную картинку блока Location = new System.Drawing.Point(X, Y), //устанавливаем позицию блока Name = "_"+xx+"_"+yy, //задаем имя блока Size = new System.Drawing.Size(50, 50), //задаем размер блока SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage //задаем параметр описания картинки в границ элемента }; //добавляем картинку на игровое поле panel2.Controls.Add(pic); //запоминаем картинку на карте Pole[xx, yy] = pic; //смещаем координаты на ширину картинки X = X + 50; } //смещаем координаты на высоту картинки Y = Y - 50; } }
Во время старта игры генерируем поле
//показываем игровое поле panel2.Visible = true; //создаем игровое поле CreatePole();
3) Далее добавляем реакцию на щечек для каждого блока и описываем функцию нахождения и уничтожения блоков.
Видео YouTube
Обявили глобальный список для поиска нужных блоков
//список претендентов на уничтожение ListPretindent = new List ();
Функция расчета проверяемых точек
//генератор координат которые нужно проверить ListIndexList(Point coord) { //создаем список предпологаемых мест для поиска точки List P = new List (); //обьявляем переменную которая будет расчетным буфером для точки Point T; //проверяем существует ли вобще точка в том раене где хотим проверять //точка с лева if ((coord.X - 1) >= 0) { T = new Point(coord.X - 1, coord.Y); P.Add(T); } //точка с права if ((coord.X + 1) < Col) { T = new Point(coord.X + 1, coord.Y); P.Add(T); }; //точка с верху if ((coord.Y - 1) >= 0 ) { T = new Point(coord.X , coord.Y - 1); P.Add(T); }; // точка с низу if ((coord.Y + 1) < Row) { T = new Point(coord.X , coord.Y + 1); P.Add(T); }; //возвращаем найденный список точек return P; }
Функция проверки точек
//рекурсивная функция проверки точек
void TestPole(Point coord, Image Color)
{
//проверяем есть ли точка в списке
int Index = Pretindent.IndexOf(coord);
//если точки нет в списке то проверяем
if (Index == -1)
{
//проверяем того ли она цвета
if (Pole[coord.X, coord.Y].Image == Color)
{
//если она нужного цвета то добавляем ее в список
Pretindent.Add(coord);
//рассчитываем координаты для поиска далее
List Test = IndexList(coord);
//создаем для точки набор соседей
foreach (Point T in Test)
{
//проверяем соседей
TestPole(T, Color);
}
}
}
}
Описываем функцию Click
void Click(object sender, EventArgs e) { //очищаем список проверяемых точек Pretindent.Clear(); //получаем данные о блока на который нажали PictureBox PicClik = sender as PictureBox; //читаем с нажатого блока картинку Image CurrentPic = PicClik.Image; //определяем по имени координаты блока string[] NamePars = PicClik.Name.Split('_'); //вычисляем позицию блока int _X_ = Convert.ToInt32(NamePars[1]); int _Y_ = Convert.ToInt32(NamePars[2]); //создаем точку для более простых операция с данными Point I = new Point(_X_, _Y_); //запускаем рекурсивную проверку точек TestPole(I, CurrentPic); //если количество соседних блоков с таким же цветом 3 и более то удаляем из них картинку if (Pretindent.Count > 2) { //перебираем каждый найденный блок foreach (Point ClearPoint in Pretindent) { //удаляем картинку из него Pole[ClearPoint.X, ClearPoint.Y].Image = null; } } }
Модифицируем функцию генерации поля добавляя ее реакцию на нажатие на блок
Текстовое поле
void CreatePole() { //начальные координаты создания 1 блока int X = 0, //координата по Х Y = panel2.Height - 50; //координата по У //Очищаем поле игры panel2.Controls.Clear(); //создаем пустой массив картинок по размеру поля Pole = new PictureBox[Col, Row]; //начинаем перебирать строки с 0 for (int yy = 0; yy < Row; yy++) { //обнуляем позицию по Х X = 0; //Начинаем двигаться по столбцам for (int xx = 0; xx < Col; xx++) { //создаем новую картинку PictureBox pic = new PictureBox() { Image = img[RND.Next(img.Length)], //загружаем случайную картинку блока Location = new System.Drawing.Point(X, Y), //устанавливаем позицию блока Name = "_"+xx+"_"+yy, //задаем имя блока Size = new System.Drawing.Size(50, 50), //задаем размер блока SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage //задаем параметр вписания картинки в граници элемента }; //добавляем реакцию блока на клик мышкой pic.Click += Click; //добавляем картинку на игровое поле panel2.Controls.Add(pic); //запоминаем картинку на карте Pole[xx, yy] = pic; //смещаем координаты на ширину картинки X = X + 50; } //смещаем координаты на высоту картинки Y = Y - 50; } }
4) Добавляем блокам гравитацию, и добавляем в игру подсчет очков.
Обявим глобальную переменную для подсчета очков
//сколько очков набрал игрок int Score = 0;
Модифицируем функцию щелчка на блоке
void Click(object sender, EventArgs e) { //очищаем список проверяемых точек Pretindent.Clear(); //получаем данные о блока на который нажали PictureBox PicClik = sender as PictureBox; //читаем с нажатого блока картинку Image CurrentPic = PicClik.Image; //определяем по имени координаты блока string[] NamePars = PicClik.Name.Split('_'); //вычисляем позицию блока int _X_ = Convert.ToInt32(NamePars[1]); int _Y_ = Convert.ToInt32(NamePars[2]); //создаем точку для более простых операция с данными Point I = new Point(_X_, _Y_); //запускаем рекурсивную проверку точек TestPole(I, CurrentPic); //если количество соседних блоков с таким же цветом 3 и более то удаляем из них картинку if (Pretindent.Count > 2) { //перебираем каждый найденный блок foreach (Point ClearPoint in Pretindent) { //удаляем картинку из него Pole[ClearPoint.X, ClearPoint.Y].Image = null; //подсчет уничтоженных блоков Score += Pretindent.Count; } } }
Опишем функцию гравитации блоков
//функция гравитации блоков void MoverDown() { //перебираем блоки по вертикали for (int yy = 0; yy < Row; yy++) { //перебираем блоки по горизонтали for (int xx = 0; xx < Col; xx++) { //если блок не имеет цвета то if (Pole[xx, yy].Image == null) { //если над блоком без цвета есть блок if (yy + 1 < Row) { //отбираем у верхнего блока цвет Pole[xx, yy].Image = Pole[xx, yy + 1].Image; //и обнуляем у верхнего блока цвет Pole[xx, yy + 1].Image = null; } else { //если нет с вехру блока то берем случайный цвет Pole[xx, yy].Image = img[RND.Next(img.Length)]; } } } } }
Добавляем в проект таймер который будет симулировать гравитацию
private void timer1_Tick(object sender, EventArgs e) { //каждые 100 милисекунд таймера пробуем выполнить гравитацию MoverDown(); //выводим на экран очки сколько заработал игрок label2.Text = " набранные очки " + Score; }
Добавляем кнопку перезапуска игры
private void button3_Click(object sender, EventArgs e)
{
//показываем меню игры
panel1.Visible = true;
//прячем игровое поле
panel2.Visible = false;
}