DESIGN PATTERNS NA
PROGRAMAÇÃO DE JOGOS
Bruno Cicanci @ GameDays 2015
LIVROS
DESIGN PATTERNS
➤ Command
➤ Flyweight
➤ Observer
➤ Prototype
➤ States
➤ Singleton
COMMAND
Padrã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
FLYWEIGHT
Padrã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 PROBLEMA
class 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
OBSERVER
Padrã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 1
class 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 2
class 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
PROTOTYPE
Padrã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 PROBLEMA
class 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 1
class 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 2
class Spawner
{
public:
Spawner(Monster* prototype)
: prototype_(prototype)
{}
Monster* spawnMonster()
{
return prototype_->clone();
}
private:
Monster* prototype_;
};
PROTOTYPE: EXEMPLOS DE USO
STATE
Padrã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 PROBLEMA
void 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
SINGLETON
Padrã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 USO
class 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 LIVROS
Programaçã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

Design Patterns na Programação de Jogo

  • 1.
    DESIGN PATTERNS NA PROGRAMAÇÃODE JOGOS Bruno Cicanci @ GameDays 2015
  • 2.
  • 3.
    DESIGN PATTERNS ➤ Command ➤Flyweight ➤ Observer ➤ Prototype ➤ States ➤ Singleton
  • 4.
  • 5.
    “Encapsular uma solicitaçãocomo 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.
  • 6.
    COMMAND: O PROBLEMA voidInputHandler::handleInput() { if (isPressed(BUTTON_X)) jump(); else if (isPressed(BUTTON_Y)) fireGun(); else if (isPressed(BUTTON_A)) swapWeapon(); else if (isPressed(BUTTON_B)) reloadWeapon(); }
  • 7.
    COMMAND: A SOLUÇÃO classCommand { 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(); }
  • 8.
  • 9.
  • 10.
    “Usar compartilhamento parasuportar 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.
  • 11.
    FLYWEIGHT: O PROBLEMA classTree { private: Mesh mesh_; Texture bark_; Texture leaves_; Vector position_; double height_; double thickness_; Color barkTint_; Color leafTint_; };
  • 12.
    FLYWEIGHT: A SOLUÇÃO classTreeModel { private: Mesh mesh_; Texture bark_; Texture leaves_; }; class Tree { private: TreeModel* model_; Vector position_; double height_; double thickness_; Color barkTint_; Color leafTint_; };
  • 13.
  • 14.
  • 15.
    “Definir uma dependênciaum-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.
  • 16.
    OBSERVER: O PROBLEMA voidPhysics::updateEntity(Entity& entity) { bool wasOnSurface = entity.isOnSurface(); entity.accelerate(GRAVITY); entity.update(); if (wasOnSurface && !entity.isOnSurface()) { notify(entity, EVENT_START_FALL); } }
  • 17.
    OBSERVER: A SOLUÇÃO- PARTE 1 class 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; } } };
  • 18.
    OBSERVER: A SOLUÇÃO- PARTE 2 class 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); } } };
  • 19.
  • 20.
  • 21.
    “Especificar os tiposde 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.
  • 22.
    PROTOTYPE: O PROBLEMA classMonster { // 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(); } };
  • 23.
    PROTOTYPE: A SOLUÇÃO- PARTE 1 class 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_; };
  • 24.
    PROTOTYPE: A SOLUÇÃO- PARTE 2 class Spawner { public: Spawner(Monster* prototype) : prototype_(prototype) {} Monster* spawnMonster() { return prototype_->clone(); } private: Monster* prototype_; };
  • 25.
  • 26.
  • 27.
    “Permite a umobjeto 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.
  • 28.
    STATE: O PROBLEMA voidHeroine::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; } } }
  • 29.
    STATE: A SOLUÇÃO voidHeroine::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; } }
  • 30.
  • 31.
  • 32.
    “Garantir que umaclasse 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.
  • 33.
    “(…) friends don’tlet friends create singletons. NYSTROM, Robert. Game Programing Patterns. Middletown: Genever Bening, 2014. 31 p.
  • 34.
    SINGLETON: O PROBLEMAE A SOLUÇÃO class FileSystem { public: static FileSystem& instance() { if (instance_ == NULL) instance_ = new FileSystem(); return *instance_; } private: FileSystem() {} static FileSystem* instance_; };
  • 35.
    SINGLETON: SUGESTÕES DEUSO class FileSystem { public: FileSystem() { assert(!instantiated_); instantiated_ = true; } ~FileSystem() { instantiated_ = false; } private: static bool instantiated_; }; bool FileSystem::instantiated_ = false;
  • 36.
    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
  • 37.
  • 38.
    OUTROS LIVROS Programação Code Complete CleanCode 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
  • 39.
  • 40.