Design Patterns na Programação de Jogo

Preview:

Citation preview

DESIGN PATTERNS NA PROGRAMAÇÃO DE JOGOS

Bruno Cicanci @ GameDays 2015

LIVROS

DESIGN PATTERNS

➤ Command

➤ Flyweight

➤ Observer

➤ Prototype

➤ States

➤ Singleton

COMMANDPadrão comportamental de objetos

“Encapsular uma solicitação como um objeto, desta forma permitindo parametrizar clientes com diferentes solicitações, enfileirar ou fazer o registro (log) de solicitações e suportar operações que podem ser desfeitas.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 222 p.

COMMAND: O PROBLEMA

void InputHandler::handleInput()

{

if (isPressed(BUTTON_X)) jump();

else if (isPressed(BUTTON_Y)) fireGun();

else if (isPressed(BUTTON_A)) swapWeapon();

else if (isPressed(BUTTON_B)) reloadWeapon();

}

COMMAND: A SOLUÇÃO class Command

{

public:

virtual ~Command() {}

virtual void execute() = 0;

};

class JumpCommand : public Command

{

public:

virtual void execute() { jump(); }

};

void InputHandler::handleInput()

{

if (isPressed(BUTTON_X))

buttonX_->execute();

else if (isPressed(BUTTON_Y))

buttonY_->execute();

else if (isPressed(BUTTON_A))

buttonA_->execute();

else if (isPressed(BUTTON_B))

buttonB_->execute();

}

COMMAND: EXEMPLOS DE USO

FLYWEIGHTPadrão estrutural de objetos

“Usar compartilhamento para suportar eficientemente grandes quantidades de objetos de granularidade fina.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 187 p.

FLYWEIGHT: O PROBLEMAclass Tree

{

private:

Mesh mesh_;

Texture bark_;

Texture leaves_;

Vector position_;

double height_;

double thickness_;

Color barkTint_;

Color leafTint_;

};

FLYWEIGHT: A SOLUÇÃO

class TreeModel

{

private:

Mesh mesh_;

Texture bark_;

Texture leaves_;

};

class Tree

{

private:

TreeModel* model_;

Vector position_;

double height_;

double thickness_;

Color barkTint_;

Color leafTint_;

};

FLYWEIGHT: EXEMPLOS DE USO

OBSERVERPadrão comportamental de objetos

“Definir uma dependência um-para-muitos entre objetos, de maneira que quando um objeto muda de estado todos os seus dependentes são notificados e atualizados automaticamente.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 274 p.

OBSERVER: O PROBLEMA

void Physics::updateEntity(Entity& entity)

{

bool wasOnSurface = entity.isOnSurface();

entity.accelerate(GRAVITY);

entity.update();

if (wasOnSurface && !entity.isOnSurface())

{

notify(entity, EVENT_START_FALL);

}

}

OBSERVER: A SOLUÇÃO - PARTE 1class Observer

{

public:

virtual ~Observer() {}

virtual void onNotify(const Entity& entity, Event event) = 0;

};

class Achievements : public Observer

{

public:

virtual void onNotify(const Entity& entity, Event event)

{

switch (event)

{

case EVENT_ENTITY_FELL:

if (entity.isHero() && heroIsOnBridge_)

{

unlock(ACHIEVEMENT_FELL_OFF_BRIDGE);

}

break;

}

}

};

OBSERVER: A SOLUÇÃO - PARTE 2class Physics : public Subject

{

public:

void updateEntity(Entity& entity);

};

class Subject

{

private:

Observer* observers_[MAX_OBSERVERS];

int numObservers_;

protected:

void notify(const Entity& entity, Event event)

{

for (int i = 0; i < numObservers_; i++)

{

observers_[i]->onNotify(entity, event);

}

}

};

OBSERVER: EXEMPLOS DE USO

PROTOTYPEPadrão de criação de objetos

“Especificar os tipos de objetos a serem criados usando uma instância-protótipo e criar novos objetos pela cópia desse protótipo.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 121 p.

PROTOTYPE: O PROBLEMAclass Monster

{

// Stuff...

};

class Ghost : public Monster {};

class Demon : public Monster {};

class Sorcerer : public Monster {};

class Spawner

{

public:

virtual ~Spawner() {}

virtual Monster* spawnMonster() = 0;

};

class GhostSpawner : public Spawner

{

public:

virtual Monster* spawnMonster()

{

return new Ghost();

}

};

PROTOTYPE: A SOLUÇÃO - PARTE 1class Monster

{

public:

virtual ~Monster() {}

virtual Monster* clone() = 0;

// Other stuff...

};

class Ghost : public Monster {

public:

Ghost(int health, int speed)

: health_(health),

speed_(speed)

{}

virtual Monster* clone()

{

return new Ghost(health_, speed_);

}

private:

int health_;

int speed_;

};

PROTOTYPE: A SOLUÇÃO - PARTE 2class Spawner

{

public:

Spawner(Monster* prototype)

: prototype_(prototype)

{}

Monster* spawnMonster()

{

return prototype_->clone();

}

private:

Monster* prototype_;

};

PROTOTYPE: EXEMPLOS DE USO

STATEPadrão comportamental de objetos

“Permite a um objeto alterar seu comportamento quando o seu estado interno muda. O objeto parecerá ter mudado sua classe.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 284 p.

STATE: O PROBLEMAvoid Heroine::handleInput(Input input)

{

if (input == PRESS_B)

{

if (!isJumping_ && !isDucking_)

{

// Jump...

}

}

else if (input == PRESS_DOWN)

{

if (!isJumping_)

{

isDucking_ = true;

}

}

else if (input == RELEASE_DOWN)

{

if (isDucking_)

{

isDucking_ = false;

}

}

}

STATE: A SOLUÇÃO void Heroine::handleInput(Input input)

{

switch (state_)

{

case STATE_STANDING:

if (input == PRESS_B)

{

state_ = STATE_JUMPING;

}

else if (input == PRESS_DOWN)

{

state_ = STATE_DUCKING;

}

break;

case STATE_JUMPING:

if (input == PRESS_DOWN)

{

state_ = STATE_DIVING;

}

break;

case STATE_DUCKING:

if (input == RELEASE_DOWN)

{

state_ = STATE_STANDING;

}

break;

}

}

STATE: EXEMPLOS DE USO

SINGLETONPadrão de criação de objetos

“Garantir que uma classe tenha somente uma instância E fornecer um ponto global de acesso para a mesma.

GAMMA, Erich et al. Design Patterns: soluções reutilizáveis de software orientado a objetos. Porto Alegre: Bookman, 2000. 130 p.

“(…) friends don’t let friends create singletons.

NYSTROM, Robert. Game Programing Patterns. Middletown: Genever Bening, 2014. 31 p.

SINGLETON: O PROBLEMA E A SOLUÇÃO class FileSystem

{

public:

static FileSystem& instance()

{

if (instance_ == NULL) instance_ = new FileSystem();

return *instance_;

}

private:

FileSystem() {}

static FileSystem* instance_;

};

SINGLETON: SUGESTÕES DE USOclass FileSystem

{

public:

FileSystem()

{

assert(!instantiated_);

instantiated_ = true;

}

~FileSystem() { instantiated_ = false; }

private:

static bool instantiated_;

};

bool FileSystem::instantiated_ = false;

OUTROS DESIGN PATTERNS➤ Double Buffer ➤ Game Loop

➤ Update Method

➤ Bytecode

➤ Subclass Sandbox ➤ Type Object

➤ Component

➤ Event Queue

➤ Service Locator ➤ Data Locality

➤ Dirty Flag

➤ Object Pool

➤ Spatial Partition ➤ Abstract Factory

➤ Builder

➤ Factory Method ➤ Adapter

➤ Bridge

➤ Composite

➤ Decorator ➤ Facade

➤ Proxy

➤ Chain of Responsibility

➤ Interpreter ➤ Iterator

➤ Mediator

➤ Memento

➤ Strategy ➤ Template Method

➤ Visitor

HTTP://GAMEPROGRAMMINGPATTERNS.COM

OUTROS LIVROSProgramação

Code Complete

Clean Code

Programação de Jogos

Game Programming Patterns

Game Programming Algorithms and Techniques

Game Coding Complete

Inteligência Artificial

Programming Game AI by Example

Física

Physics for Game Developers

Computação Gráfica

3D Math Primer for Graphics and Game

Game Design

Game Design Workshop

Level Up! The Guide to Great Game Design

Produção

The Game Production Handbook

Agile Game Development with Scrum

HTTP://GAMEDEVELOPER.COM.BR

OBRIGADO!bruno@gamedeveloper.com.br

@cicanci