Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Перевод SDL Game Framework Series. Часть 6 — SDL Entities

Anna | 24.06.2014 | нет комментариев
В этом уроке, как и обещал, я расскажу вам про такое представление как «Сущности» (Entities). «Сущности» для всех игровых процессов это своего рода такие игровые объекты, которые могут взаимодействовать в какой-либо форме либо каким-то методом друг с ином и с игровым миром. Примерами «Сущностей» могут служить монстры, которых вы встретите на своем нелегком пути, сундуки с сокровищами, которые вы можете открыть, монеты, которые дозволено собрать, стены, об которые дозволено убиться и т.д. Таким образом всякий объект игрового мира тот, что хоть как-то двигается, проявляет интерактивность, может быть представлен в виде этих «Сущностей».

Ну, скажем так: есть у вас какая-то «Гора», которая является частью вашей карты, стоит на месте и легко существует. Это не «Сущность». А вот если вы хотите принудить эту «Гору» перемещаться, падать на вашего героя (просто — взаимодействовать с объектами игрового мира), то её безусловно уместно представить в виде «Сущности». Автор решил разбить повествование на 3 статьи (и я его восхитительно понимаю, там дюже много текста и кода, перевод займет уйму времени, так что ожидайте). В этом уроке будет всё достаточно легко — мы сделаем класс для работы с «Сущностями» и разберем его по косточкам. В дальнейшем уроке узнаем как дозволено сделать карту с поддержкой тайлсетов и руководить ей. Ну и в заключении цикла — подробнейший разбор процессов взаимодействия игровых объектов (обработка пересечений (ну либо соударений) «Сущностей» с другими «Сущностями» и с самой картой).А пока, сделайте, как вы это теснее умеете, 2 файла CEntity.cpp и CEntity.h с таким содержимым:

CEntity.h

#include <vector>

#include "CAnimation.h"
#include "CSurface.h"

class CEntity {
    public:
        static std::vector<CEntity*>    EntityList;

    protected:
        CAnimation      Anim_Control;

        SDL_Surface*    Surf_Entity;

    public:
        float           X;
        float           Y;

        int             Width;
        int             Height;

        int             AnimState;

    public:
        CEntity();

        virtual ~CEntity();

    public:
        virtual bool OnLoad(char* File, int Width, int Height, int MaxFrames);

        virtual void OnLoop();

        virtual void OnRender(SDL_Surface* Surf_Display);

        virtual void OnCleanup();
};

Ну и соответственно:

CEntity.cpp

#include "CEntity.h"

std::vector<CEntity*> CEntity::EntityList;

CEntity::CEntity() {
    Surf_Entity = NULL;

    X = Y = 0.0f;

    Width = Height = 0;

    AnimState = 0;
}

CEntity::~CEntity() {
}

bool CEntity::OnLoad(char* File, int Width, int Height, int MaxFrames) {
    if((Surf_Entity = CSurface::OnLoad(File)) == NULL) {
        return false;
    }

    CSurface::Transparent(Surf_Entity, 255, 0, 255);

    this->Width = Width;
    this->Height = Height;

    Anim_Control.MaxFrames = MaxFrames;

    return true;
}

void CEntity::OnLoop() {
    Anim_Control.OnAnimate();
}

void CEntity::OnRender(SDL_Surface* Surf_Display) {
    if(Surf_Entity == NULL || Surf_Display == NULL) return;

    CSurface::OnDraw(Surf_Display, Surf_Entity, X, Y, AnimState * Width, Anim_Control.GetCurrentFrame() * Height, Width, Height);
}

void CEntity::OnCleanup() {
    if(Surf_Entity) {
        SDL_FreeSurface(Surf_Entity);
    }

    Surf_Entity = NULL;
}

Как обыкновенно, настало время мне объяснить вам что здесь всё-таки происходит. Я инкапсулировал от CApp5 ранее использованных мной (и вами) способов (за исключением обработки событий — расскажу в дальнейшем уроке как и обещал). Такой подход дозволит нам «отделить зёрна от плевел» и обрабатывать «Сущности» больше прозрачно и легко, нежели чем они были бы распиханы все в куче в основном (CApp) классе. Также мы сумеем с легкостью обрабатывать и что-то другое нежели «Сущности». Вы теснее обратили внимание на статический вектор EntityList? Он предуготовлен для хранения списка наших игровых сущностей и прямо доступен через CEntity::EntityList, всё потому что он неподвижен. Значимо: я намеренно объявилEntityList именно в CEntity, от того что такой подход дозволит в грядущем избежать циклических зависимостей. К примеру взаимодействие Карты с Сущностями, когда класс CMap объявлен как член CEntity и CEntity объявлен как член CMap (здесь я сам немножко не осознал что автор имеет в виду), приведет к ошибке на этапе компиляции.

Выходит, данный вектор будет беречь все наши игровые «Сущности» в виде ссылок на них (сделано с упором на грядущее, когда от класса CEntity будут наследоваться другие классы). Так, скажем, если бы мы собирались сделать игру Megaman, у нас был бы класс CMegaMan наследованный от CEntity. И с поддержкой полиморфизма мы сумеем беречь объекты класса CMegaMan в EntityList. Это и есть повод, по которой мы объявили вышеуказанные функции, как виртуальные, а некоторые члены класса защищенными.

У нашей «Сущности» есть всеобщие для всех «Сущностей» параметры — координаты, размеры, поверхность для отрисовки картинки. Также имеется и способ для загрузки этой картинки, по умолчанию — легко прозрачная область. Лирическое отхождение: не опасайтесь изменять данный код, это не постулат, он не высечен из камня. Меняйте его так как вам вздумается, а если ошибетесь, оригинал неизменно здесь, никуда не денется!

В способе OnLoop у нас обязаны быть реализованы основные вычисления. Но пока мы оставим там только расчет кадров анимации. Также обратите внимание, что мы установили для анимации только переменнуюMaxFrames, а всё остальное оставили по умолчанию. Приглядимся к OnRender. Взамен того, Дабы делать тупо отрисовку на экран, я ввел параметр, Дабы стало допустимым указывать всякую поверхность, в которую мы бы хотели отрисовывать «Сущность». Таким образом вы можете даже накладывать отрисовку «Сущностей» друг на друга.

Ну и напоследок у нас OnCleanup, любимая моя чистка каждого и каждая (Чистилище по мне ревет), освободитель памяти, небольшой эконом.

Как я теснее говорил в самом начале — мы сделали только базовую конструкцию класс для «Сущностей», и, не кривя душой, скажу что пока данный монстр немного чего может (но будет уметь в следующих уроках). Но принудить его заработать мы можем теснее теперь! Откроем
CApp.h и добавим парочку «Сущностей»:

CApp.h

#include "CEntity.h"

//... здесь наш не изменяющийся код

private:
    CEntity         Entity1;
    CEntity         Entity2;

Загрузим их, прописав код в CApp_OnInit.cpp. (здесь понадобятся картинка с прошлого урока, правильней 2 её копии):

CApp_OnInit.cpp

if(Entity1.OnLoad("./entity1.bmp", 64, 64, 8) == false) {
    return false;
}

if(Entity2.OnLoad("./entity2.bmp", 64, 64, 8) == false) {
    return false;
}

Entity2.X = 100;

CEntity::EntityList.push_back(&Entity1);
CEntity::EntityList.push_back(&Entity2);

Помните, как я говорил, что мы, в основном, инкапсулируем основные функции игры в классе сущностей? Сейчас необходимо их немного повызывать. Редактируем CApp_OnLoop.cpp:

for(int i = 0;i < CEntity::EntityList.size();i  ) {
    if(!CEntity::EntityList[i]) continue;

    CEntity::EntityList[i]->OnLoop();
}

Т.е. мы пробегаемся по нашему вектору с «Сущностями» и у всякой «Сущности» вызываем способ OnLoop (а также проводим небольшую проверку, чтобы не нарваться на нулевой указатель). Осталось то же самое сделать и в CApp_OnRender.cpp:

for(int i = 0;i < CEntity::EntityList.size();i  ) {
    if(!CEntity::EntityList[i]) continue;

    CEntity::EntityList[i]->OnRender(Surf_Display);
}

Очисточка, родимая, ну привет:

for(int i = 0;i < CEntity::EntityList.size();i  ) {
    if(!CEntity::EntityList[i]) continue;

    CEntity::EntityList[i]->OnCleanup();
}

CEntity::EntityList.clear();

Последним штрихом (CEntity::EntityList.clear()) мы обнуляем вектор «Сущностей»… Компилируем, запускаем, любуемся!
Каждому спасибо за внимание.

Ссылки на начальный код:

Ссылки на все уроки:

 

Источник: programmingmaster.ru

 

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB