Шаг 124.
Microsoft Visual C++ 2010. Начала.
Игра "Сапер". Игра

    На этом шаге мы рассмотрим основные функции, которые используются во время игры .

    Во время игры программа воспринимает нажатия кнопок мыши и в соответствии с правилами игры открывает клетки или ставит в клетки флажки. Основную работу выполняет функция обработки события MouseClick:

// щелчок в клетке игрового поля
private: System::Void panel1_MouseClick(System::Object^  sender, 
    System::Windows::Forms::MouseEventArgs^  e) {
	 if (status == 2)
		 // игра завершена
		 return;
	 if (status == 0)
		 // первый щелчок
		 status = 1;
	 // Преобразуем координаты мыши в индексы клетки поля,
	 // в которой был сделан щелчок;
	 // (e.X, e.Y) - координаты точки формы,
	 // в которой была нажата кнопка мыши
	 int row, col;
	 row = e->Y/H + 1;
	 col = e->X/W + 1;
	 // координаты области вывода
	 int x = (col-1)* W + 1,
		 y = (row-1)* H + 1;
	 // щелчок левой кнопки мыши
	 if (e->Button == System::Windows::Forms::MouseButtons::Left)
	 {
		 // открыта клетка, в которой есть мина
		 if (Pole[row,col] == 9)
		 {
			 Pole[row,col] += 100;
			 // игра закончена
			 status = 2;
			 // перерисовать форму
			 this->panel1->Invalidate();
		 }
		 else
			 if (Pole[row,col] < 9)
				 // открыть клетку
				 this->open(row,col);
	 }
	 // щелчок правой кнопки мыши
	 if (e->Button == System::Windows::Forms::MouseButtons::Right)
	 {
		 // в клетке нет флага, ставим его
		 if (Pole[row,col] <= 9) 
		 {
			 nFlag += 1;
			 if (Pole[row,col] == 9)
				 nMin += 1;
			 Pole[row,col] += 200;
			 if ((nMin == NM) && (nFlag == NM)) 
			 {
				 // игра закончена
				 status = 2;
				 // перерисовываем все игровое поле
				 this->panel1->Invalidate();
			 }
			 else
				 // перерисовываем только клетку
				 this->Kletka(g, row, col, status);
		 }
		 else
			 // В клетке был поставлен флаг,
			 // повторный щелчок правой кнопки мыши
			 // убирает его и закрывает клетку
			 if (Pole[row,col] >= 200)
			 {
				 nFlag -= 1;
				 Pole[row,col] -= 200;
				 // перерисовываем клетку
				 this->Kletka(g, row, col, status);
			 }
	 }
 }

    Функция через параметр e получает координаты точки окна (панели), в которой игрок щелкнул кнопкой мыши, а также информацию о том, какая кнопка была нажата. Сначала процедура преобразует координаты точки, в которой игрок нажал кнопку мыши, в координаты клетки игрового поля. Затем делает необходимые изменения в массиве Polе и, если нажата правая кнопка, вызывает функцию flag, которая рисует в клетке флажок. Если нажата левая кнопка в клетке, в которой нет мины, то эта клетка открывается — на экране появляется ее содержимое. Если левая кнопка нажата в клетке, в которой есть мина, то вызывается функция showPole, которая показывает все мины, в том числе и те, которые игрок не успел найти.

    Функция flag рисует флажок:

// рисует флаг
void flag(Graphics^ g, int x, int y)
{
	array<Point>^ p = gcnew array<Point>(3);
	array<Point>^ m = gcnew array<Point>(5);
	//Point[] m = new Point[5];
	// флажок
	p[0].X = x+4; p[0].Y = y+4;
	p[1].X = x+30; p[1].Y = y+12;
	p[2].X = x+4; p[2].Y = y+20;
	g->FillPolygon(Brushes::Red, p);
	// древко
	g->DrawLine(Pens::Black, x+4, y+4, x+4, y+35);
	// буква M на флажке
	m[0].X = x+8; m[0].Y = y+14;
	m[1].X = x+8; m[1].Y = y+8;
	m[2].X = x+10; m[2].Y = y+10;
	m[3].X = x+12; m[3].Y = y+8;
	m[4].X = x+12; m[4].Y = y+14;
	g->DrawLines(Pens::White, m);
}

    Флажок (рисунок 1) состоит из четырех примитивов: линии (древко), замкнутого контура (флаг) и ломаной линии (буква "М").


Рис.1. Флажок

    Функция рисует флажок, используя метод базовой точки, т. е. координаты всех точек, определяющих положение элементов рисунка, отсчитываются от базовой точки.

    Функция mina рисует мину (рисунок 2), которая состоит из восьми примитивов: два прямоугольника и сектор образуют корпус мины, остальные элементы рисунка — линии ("усы" и полоски на корпусе).

// рисует мину
void mina(Graphics^ g, int x, int y)
{
	// корпус
	g->FillRectangle(Brushes::Green, x+16, y+26, 8, 4);
	g->FillRectangle(Brushes::Green, x+8, y+30, 24, 4);
	g->DrawPie(Pens::Black, x+6, y+28, 28, 16, 0, -180);
	g->FillPie(Brushes::Green, x+6, y+28, 28, 16, 0, -180);
	// полоса на корпусе
	g->DrawLine(Pens::Black, x+12, y+32, x+28, y+32);
	// вертикальный "ус"
	g->DrawLine(Pens::Black, x+20, y+22, x+20, y+26);
	// боковые "усы"
	g->DrawLine(Pens::Black, x+8, y+30, x+6, y+28);
	g->DrawLine(Pens::Black, x+32, y+30, x+34, y+28);
}


Рис.2. Мина

    Обеим функциям в качестве параметров передаются координаты базовой точки, от которой надо рисовать.

    На следующем шаге мы рассмотрим вывод справочной информации.




Предыдущий шаг Содержание Следующий шаг