Проект 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

Обявили глобальный список для поиска нужных блоков

 //список претендентов на уничтожение 
        List Pretindent = new List();

Функция расчета проверяемых точек

  //генератор координат которые нужно проверить
        List IndexList(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; 
        }

0
RENDER.RU