...

воскресенье, 13 октября 2013 г.

Пишем игры на C++, Часть 3/3 — Классика жанра

Пишем игры на C++, Часть 1/3 — Написание мини-фреймворка

Пишем игры на C++, Часть 2/3 — State-based программирование

Здравствуй, Хабрахабр!


Наконец-то мы будем писать игры! Это заключительная часть из цикла уроков


О чем эта часть?





  • Напишем несколько довольно известных игр


Какие именно игры?





  • Крестики-нолики

  • Змейка (возможно)

  • Сапер (возможно)


Исходники и .exe будут представлены в конце статьи


3.1 Крестики-нолики


Классика жанра начинающего девелопера — крестики-нолики.

Это будет небольшой разминкой.

Описывать код в статье не буду, берите попкорн и читайте комментарии в коде :)


Открываем main.cpp



#include "Project.h"

// Размер поля. Размер крестиков и ноликов должен быть 200x200 пикселей
const int GRID_SIZE = 600;

class TicTacToeScreen : public Screen
{
private:
Input* input;
Graphics* graphics;

// Изображения фона, крестиков и ноликов
Image* back;
(Image* player)[2];

// Массив, обозначающий поле, и текущий игрок
int grid[3][3], currplayer;

void StartSettings()
{
// Берем объекты Graphics и Input и устанавливаем заголовок окна

input = game->GetInput();
graphics = game->GetGraphics();
SDL_WM_SetCaption("Tic-Tac-Toe",0);
}

void LoadingImage()
{
// Загрузка изображений

back = graphics->NewImage("C:\\Users\\HOME\\Desktop\\back.bmp");
player[0] = graphics->NewImage("C:\\Users\\HOME\\Desktop\\X.bmp",255,255,255);
player[1] = graphics->NewImage("C:\\Users\\HOME\\Desktop\\O.bmp",255,255,255);
}

void Reset()
{
// Очистка поля и вывод фона

currplayer = 1;

for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
grid[i][j] = 0;

graphics->DrawImage(back,0,0);
graphics->Flip();
}

int GameOver()
{
// -1 - игра не окончена; 0 - ничья; 1 - победили крестики; 2 - победили нолики

// Проверка на чью-нибудь победу
for(int i = 1; i < 3; i++)
// По горизонтали
if( (grid[0][0] == i && grid[1][0] == i && grid[2][0] == i) ||
(grid[0][1] == i && grid[1][1] == i && grid[2][1] == i) ||
(grid[0][2] == i && grid[1][2] == i && grid[2][2] == i) ||

// По вертикали
(grid[0][0] == i && grid[0][1] == i && grid[0][2] == i) ||
(grid[1][0] == i && grid[1][1] == i && grid[1][2] == i) ||
(grid[2][0] == i && grid[2][1] == i && grid[2][2] == i) ||

// По диагонали
(grid[0][0] == i && grid[1][1] == i && grid[2][2] == i) ||
(grid[2][0] == i && grid[1][1] == i && grid[0][2] == i) )
return i;

// Проверка на ничью
int count = 0;
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
if(grid[i][j] != 0)
count++;
// Заполнено все поле
if(count == 9)
return 0;

return -1;
}

void GameOverHandle(int over)
{
// Обработка конца игры

char* message;

switch(over)
{
case 0:
message = "Ничья! Желаете сыграть еще раз?";
break;
case 1:
message = "Крестики победили! Желаете сыграть еще раз?";
break;
case 2:
message = "Нолики победили! Желаете сыграть еще раз?";
break;
// Если игра не окончена, возвращаемся из функции
default:
return;
}

// Спрашиваем пользователя, хочет ли он сыграть еще раз
if(MessageBox(0,message,"Игра окончена",MB_YESNO) == IDYES)
Reset();
else
game->Exit();
}

public:
void Start()
{
StartSettings();
LoadingImage();
Reset();
}

void Update()
{
// Если нажат красный крестик в окне
if(input->IsExit())
game->Exit();

// Если нажата левая кнопка мыши
// P.S. 1 - ЛКМ, 2 - СКМ, 3 - ПКМ
if(input->IsMouseButtonDown(1))
{
// Берем координаты нажатой клетки
int x = input->GetButtonDownCoords().x / (GRID_SIZE / 3),
y = input->GetButtonDownCoords().y / (GRID_SIZE / 3);

// Если мы нажали на пустую клетку
if(grid[x][y] == 0)
{
// Устанавливаем крестик или нолик в клетку
grid[x][y] = currplayer;

if(currplayer == 1)
currplayer = 2;
else
currplayer = 1;

// Рисуем задник
graphics->DrawImage(back,0,0);

// Рисуем крестики и нолики
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
if(grid[i][j] != 0)
graphics->DrawImage(player[ grid[i][j]-1 ], i * (GRID_SIZE / 3), j * (GRID_SIZE / 3));

// Выводим на экран
graphics->Flip();

// Обрабатываем конец игры
GameOverHandle(GameOver());
}
}
}
};


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
Game game;
return game.Execute(new TicTacToeScreen(),GRID_SIZE,GRID_SIZE);
}


TO BE CONTINUED в ближайшее время.

Следите за этим постом


По всем вопросам обращайтесь в ЛС, а если вам не повезло быть зарегистрированным на хабре, пишите на мейл izarizar@mail.ru


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий