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

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

Anna | 24.06.2014 | нет комментариев

Поздравляю вас, если вы прочитали 1-й урок! Он довольно огромный. Обещаю, что здесь кода будеть поменьше, а итогов огромнее :)

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

  • Мы попытаемся постичь state-based programming, с поддержкой которого новые ярусы и меню делаются дюже легко

В дальнейшем посте будут настоящие игры :)

2.1. Состояния

Сейчас хорошо бы осознать, из чего, собственно, состоит игра.

Возможен, у нас есть игра, где много менюшек, ярусов и прочих «состояний». Как дозволено с ними взаимодействовать? ?сно, что код типа:

    void Update()
	{
        switch(state)
		{
		case State::MENU:
            // 100 строк
		case State::SETTINGS:
            // 200 строк
		case State::LEVEL1:
            // Ужасно считать
        }
    }

Вызывает лютый незачет в плане комфорта.

Как насчет того, Дабы всякому состоянию сделать своего преемника от какого-нибудь класса с наименованием, возможен, Screen, и применять его в Game?

Сделайте Screen.h

#ifndef SCREEN_H
#define SCREEN_H

#include "Incl.h"

#include "Game.h"
class Game;

class Screen
{
protected:
	Game* game;
public:
	void SetController(Game* game);

	virtual void Start();
	virtual void Update();
	virtual void Destroy();
};

#endif

Данный класс имеет экземпляр Game, откуда преемники берут указатели на Graphics и Input
Его виртуальные функции для преемников:

  • Start — вызов всякий раз при старте (предназначение состоянием)
  • Update — вызов всякий цикл
  • Destroy — вызов по истреблению (заключение работы программы либо предназначение иного состояния)

Screen.cpp

#include "Screen.h"

void Screen::SetController(Game* game)
{
	this->game = game;
}

void Screen::Start()
{

}

void Screen::Update()
{

}

void Screen::Destroy()
{

}

Обновляем Game.h и Game.cpp

#ifndef _GAME_H_
#define _GAME_H_

#include "Project.h"

#include "Graphics.h"
class Graphics;
#include "Input.h"
class Input;
#include "Screen.h"
class Screen;

class Game
{
private:
	bool run;

	Graphics* graphics;
	Input* input;
	Screen* screen;

public:
	Game();
	int Execute(Screen* startscreen, int width, int height);

	Graphics* GetGraphics();
	Input* GetInput();
	Screen* GetScreen();
	void SetScreen(Screen* screen);

	void Exit();
};

#endif

В класс Game включается объект Screen и изменяется функция Execute, куда из main.cpp передаем объект своего преемника Screen

Game.cpp

#include "Game.h"

Game::Game()
{
	run = true;
}

int Game::Execute(Screen* startscreen, int width, int height)
{
	graphics = new Graphics(width,height);
	input = new Input();
	screen = startscreen;

	screen->SetController(this);
	this->screen->Start();

	while(run)
	{
		input->Update();
		screen->Update();
	}

	screen->Destroy();

	delete graphics;
	delete input;
	delete screen;

	SDL_Quit();
	return 0;
}

Graphics* Game::GetGraphics()
{
	return graphics;
}

Input* Game::GetInput()
{
	return input;
}

Screen* Game::GetScreen()
{
	return screen;
}

void Game::SetScreen(Screen* screen)
{
	this->screen->Destroy();
	delete this->screen;
	this->screen = screen;
	this->screen->SetController(this);
	this->screen->Start();
}

void Game::Exit()
{
	run = false;
}

Значимым изменениям подвергается способ Execute — он обрабатывает нынешнее состояние

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

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