Съдържание

 

  1. Цели.
  2. Бележки за спрайтовете.
  3. Структура на директориите на проекта.
  4. Описание на класовете и файлове.
  5. Базова структура на главният клас на играта.
  6. Заключение.

 

1. Цели

След краткото въведение в SDL ще си поставим по-амбициозна задача. Искаме да си напишем прост Game engine на SDL2.
Каква ще представлява този Game engine? Какви изисквания ще имаме към него? Общо казано ще искаме да ни даде възможност да пишем прости логически, аркадни игри и въобще всякакъв род 2D игри. За начало ще работим само с SDL_Surface.

  1. Да може да дефинира жизнен цикъл на играта т.е. ясни етапи на инициализиране, render, update и освобождаване на ресурсите.
  2. Да ни даде обектно-ориентирана обвивка на библиотеките на SDL2.
  3. Управление на спрайтовете – прихващане и обработка на събития на спрайта (mouse up, mouse down и т.н.).
  4. Работа с анимирани спрайтове.
  5. И не на последно място, Game engine трябва да има достатъчно прост код, защото целите му са главно образователни и за забавление т.е. трябва да е удобен за промени.

В горните точки не са включени networking, play music и т.н., защото тези свойства присъстват в SDL2.

Това няма да са серия уроци, които постепенно ще показват построяването на Game engine. Game engine ще бъде описан – свойства и взаимовръзки между класовете, и след това ще започнем писането на проста игра – играта 15. В процеса на писането ние ще разширяваме възможностите на Game engine и така ще го изучаваме. В края на крайщата като за начало той ще съдържа само 7 класа (като за начало).
В случая ще ни трябва още една библиотека от SDL2, а именно SDL_image. Ето тук има уроци за инсталирането й под различни операционни системи. Тя ни е необходима, за да може да извеждаме картинки в различни файлови формати.
Source code можем да свалим от тук:
https://github.com/jinnee/opge

2. Бележки за спрайтовете.

Бележки за духчетата (sprites).
Духчета – това ще бъде всичко, което показваме на екрана на играта. Те могат да са статични (background) или анимирани (героите на играта, предмети, явления, като горящ огън например).
При всички ще използваме sprite sheets. Какво представлява това? Най-добре е да се види:
тук и http://www.spriters-resource.com.
Ще използваме готови sprite sheets, но също така и ще си направим някои от вече готови gif картинки.

Преди да започна бележките към класовете искам да подчертая, че целите целите на този Game engine са предимно образователни. Надявам се, че няма много грешки, но дори и да има надявам се заедно да ги поправим 🙂

3. Структура на директориите на проекта.

Нека кръстим директорията на проекта:
opge
– include – поддиректория, съдържаща .h файловете на класовете на нашия Game Engine
– src – поддиректория, съдържаща .cpp файловете
– gsrc – тук ще пишем играта 🙂 – .h и .cpp файловете на нашата игра са тук. Няма да имаме различни поддиректории за тях. Все пак нашите игри няма да са много големи.
– resources – тук ще бъдат всичките ни ресурси – картинки, музика и т.н.

4. Описание на класовете и файлове.

Класове за спрайтове.

  1. Директорията на проекта opge, съдържа файла main.cpp, който ще бъде входната точка на приложението.
  2. Constants – съдържа константите, използвани в Game engine, като типове на спрайтове – статичен спрайт, бутони, директории и т.н.
  3. ImageInstruments – това е клас, с помощта на който ще зареждаме нашите картинки и спрайтове.
  4. AbstractSprite – тук са абстрактните методи за събитията на спрайта, тук се декларират името, типът и групата. Групата ще ни дава възможност за едновременно въздействие върху всички спрайтове от групата. Наследява ImageInstruments и тук е метода за показване на спрайта, ще манипулиране положението му, посока на преместване, скриване и показване и др.
  5. StaticSprite – наследява AbstractSprite и реализира абстрактните методи за събитията на спрайта, методи за работа със мрежата от фреймове на спрайта и др.
  6. AnimatedSprite – наследява StaticSprite и реализира работата със фреймовете на спрайта (Sprite sheet).

След като имаме класовете за представяне на спрайта, нека да продължим с класовете за тяхното управление.

  1. SpriteManager – клас обвивка на вектор. Векторът съдържа обекти от тип AbstractSprite, а класът съдържа методи за прибавяне, изтриване на спрайтове във вектора. Само спрайтове, които са във вектора, ще могат да се показват.
  2. SdlApplication – клас, който инициализира SDL, създава прозореца на играта, определя размера, заглавието на прозореца и т.н.
  3. AbstractGame – тук са абстрактните методи, определящи жизнения цикъл на играта.
  4. Game – ядрото на Game engine – наследява AbstractGame и SpriteManager, реализира основния цикъл на играта и определя реда на абстрактните методи AbstractGame.

 

5. Базова структура на главния клас на играта.

По-горе описахме базовите класове на нашия Game engine. Време е да пристъпим към играта. По-горе споменахме, че файловете на играта ще се намират в директорията gsrc. Да създадем там два файла:

FifteenGame.h и FifteenGame.cpp

FifteenGame.h:

  1. #define FIFTEENGAME_H
  2. #include <iostream>
  3. #include „../include/Game.h“
  4. using namespace std;
  5. class FifteenGame : public Game {
  6. public:
  7.       void init();
  8.       void update(double deltaTime);
  9.       void render();
  10.       void freeResources();
  11.       FifteenGame();
  12.       ~FifteenGame();
  13. private:
  14.       SDL_PixelFormat* pixelFormat;
  15. };
  16. #endif // FIFTEENGAME_H

FifteenGame.cpp:

  1. #include <dirent.h>
  2. #include <stdio.h>
  3. #include „FifteenGame.h“
  4. FifteenGame::FifteenGame() {
  5. }
  6. // инициализиране
  7. void FifteenGame::init() {
  8.       pixelFormat = getPixelFormat();
  9.       ImageInstruments::setPixelFormat(pixelFormat);
  10.       // път до картинката използвана за курсор
  11.       string cursor_path = Constants::RESOURCE_DIR + „/tinkerbell4.png“;
  12.      // заглавие на прозореца на играта
  13.      this->setTitle(„Игра 15“);
  14. }
  15. // тук се съобщава на Game engine, ако сме променили спрайта
  16. void FifteenGame::update(double deltaTime) {
  17. }
  18. // показваме спрайта
  19. void FifteenGame::render() {
  20. }
  21. // освобождаване на ресурси
  22. void FifteenGame::freeResources() {
  23.       cout << „freeResources“ << endl;
  24. }
  25. FifteenGame::~FifteenGame() {
  26.      cout << „destructor“ << endl;
  27. }

Това е скелетъг на нашата игра. Остава само да я стартираме, а за това ни липсва функцията main.
Да припомним, че тя се намира в главната директория на играта opge.

main.cpp

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include „include/Game.h“
  4. #include „gsrc/FifteenGame.h“
  5. int main(int argc, char *argv[]) {
  6.      Game * mg = new FifteenGame();
  7.      mg->start();
  8.      delete mg;
  9.      return 0;
  10. }

Готово, можем да стартираме.

6. Заключение.

Да повторим какво ни е необходимо:

  1. Инсталирана библиотека SDL2 и SDL_image (за SDL2)
  2. В средата за разработка, с която работим, си създаваме конзолен c++ проект и към него включваме SDL2 библиотеките.
  3. Сваляме файловете за играта от https://github.com/jinnee/opge..
  4. Импортираме файловете, свалени от https://github.com/jinnee/opge в нашия проект.
  5. Компилираме и стартираме.

Ако изпитвате трудности с инсталирането и използването на SDL2 и SDL_image, то тук lazyfoo.net ще намерите подробни инструкции за инсталирането и използването въобще на всякакви c/c++ библиотеки.

Към нашият Game engine в следващите уроци ще добавим button, background и cursor.

Приятно кодиране.

Автор: Янко Попов