Game Programming Patterns Command From the book by Robert Nystrom

Slides:



Advertisements
Similar presentations
OOP Design Patterns Chapters Design Patterns The main idea behind design patterns is to extract the high level interactions between objects and.
Advertisements

Computer Science – Game DesignUC Santa Cruz Today Publish/Subscribe Design Pattern Delegates Sprite movement Particles.
Python November 18, Unit 7. So Far We can get user input We can create variables We can convert values from one type to another using functions We can.
Prototype Pattern Intent:
ARRAYS AND POINTERS Although pointer types are not integer types, some integer arithmetic operators can be applied to pointers. The affect of this arithmetic.
CS 106 Introduction to Computer Science I 04 / 21 / 2008 Instructor: Michael Eckmann.
Command Design Pattern Source: Design Patterns – Elements of Reusable Object- Oriented Software; Gamma, et. al.
CS320n –Visual Programming Interactive Programs Mike Scott (Slides 5-1)
CS 106 Introduction to Computer Science I 04 / 28 / 2010 Instructor: Michael Eckmann.
Abstraction: Polymorphism, pt. 1 Abstracting Objects.
SE320: Introduction to Computer Games Week 8: Game Programming Gazihan Alankus.
Options for User Input Options for getting information from the user –Write event-driven code Con: requires a significant amount of new code to set-up.
Game Scripting By: Nicholas Haines. Aurora Neverwinter Toolset.
Week 4-5 Java Programming. Loops What is a loop? Loop is code that repeats itself a certain number of times There are two types of loops: For loop Used.
Chapter 7 Designing Classes. Class Design When we are developing a piece of software, we want to design the software We don’t want to just sit down and.
Lecture 22 Miscellaneous Topics 4 + Memory Allocation.
1 Data Structures - CSCI 102 CS102 C++ Polymorphism Prof Tejada.
ACM/JETT Workshop - August 4-5, ExceptionHandling and User Interfaces (Event Delegation, Inner classes) using Swing.
Iteration. Adding CDs to Vic Stack In many of the programs you write, you would like to have a CD on the stack before the program runs. To do this, you.
© The McGraw-Hill Companies, 2006 Chapter 4 Implementing methods.
Game Programming Patterns Type Object From the book by Robert Nystrom
REVIEW On Friday we explored Client-Server Applications with Sockets. Servers must create a ServerSocket object on a specific Port #. They then can wait.
Game Scripting by: Nicholas Haines. What is Scripting? Interpreted Language Interpreted Language –As the game runs.
Design Patterns. Patterns “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution.
CS 350 – Software Design The Strategy Pattern – Chapter 9 Changes to software, like other things in life, often focus on the immediate concerns and ignore.
Lexi case study (Part 2) Presentation by Matt Deckard.
CS 151: Object-Oriented Design September 26 Class Meeting Department of Computer Science San Jose State University Fall 2013 Instructor: Ron Mak
CS 106 Introduction to Computer Science I 04 / 23 / 2010 Instructor: Michael Eckmann.
Game Programming Patterns Event Queue From the book by Robert Nystrom
CSCI-383 Object-Oriented Programming & Design Lecture 18.
ECE450 - Software Engineering II1 ECE450 – Software Engineering II Today: Design Patterns VIII Chain of Responsibility, Strategy, State.
ARCH-11: Building your Presentation with Classes John Sadd Fellow and OpenEdge Evangelist Sasha Kraljevic Principal TSE.
0 Odds and Ends in Haskell: Folding, I/O, and Functors Adapted from material by Miran Lipovaca.
Object Oriented Analysis & Design Game Patterns. Contents  What patterns are  Delegation  Game Loop  Scene Graph  Double Buffering  Component 
CPS Inheritance and the Yahtzee program l In version of Yahtzee given previously, scorecard.h held information about every score-card entry, e.g.,
Game Programming Patterns Game Loop From the book by Robert Nystrom
Lesson 2: Reading a program. Remember: from yesterday We learned about… Precise language is needed to program Actors and Classes Methods – step by step.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
CS 106 Introduction to Computer Science I 04 / 18 / 2008 Instructor: Michael Eckmann.
Polymorphism, Virtual Methods and Interfaces Version 1.1.
Sega 500 Scripted events and Sequences Jeff “Ezeikeil” Giles
1 Event Driven Programs Rick Mercer. 2 So what happens next?  You can layout a real pretty GUI  You can click on buttons, enter text into a text field,
Session 7 Introduction to Inheritance. Accumulator Example a simple calculator app classes needed: –AdderApp - contains main –AddingFrame - GUI –CloseableFrame.
Applying the Principles Two Examples. Example 1 New Requirement It would be nice with a simple GUI “to see something” instead of just xUnit tests...
National Diploma Unit 4 Introduction to Software Development Procedures and Functions.
Command Pattern. Intent encapsulate a request as an object  can parameterize clients with different requests, queue or log requests, support undoable.
CSC 108H: Introduction to Computer Programming Summer 2011 Marek Janicki.
Chapter 4 - Finishing the Crab Game
User-Written Functions
Where are we ? Setup Sprites Input Collision Drawing Sprites
PYGAME.
Applying the Principles
CS 350 – Software Design The Strategy Pattern – Chapter 9
Java Programming Language
Behavioral Design Patterns
Object-Oriented Programming & Design Lecture 18 Martin van Bommel
Introduction to Events
Programming Design Patterns
Behavioral and Structural Patterns
Behavioral Patterns Part-I introduction UNIT-VI
File I/O in C Lecture 7 Narrator: Lecture 7: File I/O in C.
PH Chapter 3 Thanks for the Memory Leaks Pushme-Pullyu (pp
DESIGN PATTERNS : Strategy Pattern
Objects First with Java A Practical Introduction using BlueJ
Chapter 9 Carrano Chapter 10 Small Java
Objects First with Java A Practical Introduction using BlueJ
12. Command Pattern SE2811 Software Component Design
Software Engineering and Architecture
Software Engineering and Architecture
Presentation transcript:

Game Programming Patterns Command From the book by Robert Nystrom

Command pattern A command is a “reified method call” – Reify: make real Taking a concept and turning it into a piece of data – which can be stored in a variable – which can be passed to a function It’s a method call wrapped in an object

A dead simple implementation looks like: 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)) lurchIneffectively(); }

Many games let the user configure how their buttons are mapped. To support that, we need to turn those direct calls to jump() and fireGun() into something that we can swap out. “Swapping out” sounds a lot like assigning a variable, so we need an object that we can use to represent a game action. Enter: the Command pattern.

We define a base class that represents a triggerable game command: class Command { public: virtual ~Command() {} virtual void execute() = 0; }; Then we create subclasses for each of the different game actions: class JumpCommand : public Command { public: virtual void execute() { jump(); } }; class FireCommand : public Command { public: virtual void execute() { fireGun(); } }; // You get the idea...

In our input handler, we store a pointer to a command for each button: class InputHandler { public: void handleInput(); // implementation on next slide // Methods to bind commands... (“swapping out”) private: Command* buttonX_; Command* buttonY_; Command* buttonA_; Command* buttonB_; };

Now the input handling just delegates to those: 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(); } Where each input used to directly call a function, now there’s a layer of indirection:

That’s the Command pattern in a nutshell. But wait, there’s more… The command can control different objects The game’s AI can emit Command objects Undo and Redo

The command classes we just defined work for the previous example, but they’re pretty limited. The problem is that they assume there are these top-level jump(), fireGun(), etc. functions that implicitly know how to find the player’s avatar and make him dance like the puppet he is. That assumed coupling limits the usefulness of those commands. The only thing the JumpCommand can make jump is the player. Let’s loosen that restriction. Instead of calling functions that find the commanded object themselves, we’ll pass in the object that we want to order around: class Command { public: virtual ~Command() {} virtual void execute(GameActor& actor) = 0; };

We pass the GameActor reference in to execute() so that the derived command can invoke methods on an actor of our choice, like so: class JumpCommand : public Command { public: virtual void execute(GameActor& actor) { actor.jump(); } };

Next, we change handleInput() so that it returns commands: Command* InputHandler::handleInput() { if (isPressed(BUTTON_X)) return buttonX_; if (isPressed(BUTTON_Y)) return buttonY_; if (isPressed(BUTTON_A)) return buttonA_; if (isPressed(BUTTON_B)) return buttonB_; // Nothing pressed, so do nothing. return NULL; } It can’t execute the command immediately since it doesn’t know what actor to pass in.

Then, we need some code that takes that Command object and runs it on the actor representing the player. Something like: Command* command = inputHandler.handleInput(); if (command) { command->execute(actor); // actor is a GameActor& } Adding a layer of indirection between the command and the actor that performs it has given us a neat little ability: we can let the player control any actor in the game now by changing the actor we execute the commands on.

What about all of the other actors in the world? Those are driven by the game’s AI. We can use this same command pattern as the interface between the AI engine and the actors; the AI code simply emits Command objects. The decoupling here between the AI that selects commands and the actor code that performs them gives us a lot of flexibility. We can use different AI modules for different actors. Or we can mix and match AI for different kinds of behavior.

Undo and redo are well-known use of the Command pattern. If a command object can do things, it’s a small step for it to be able to undo them. Undo is used in some strategy games where you can roll back moves that you didn’t like. It’s de rigueur in tools that people use to create games.

class MoveUnitCommand : public Command { public: MoveUnitCommand(Unit* unit, int x, int y) : unit_(unit), x_(x), y_(y) {} virtual void execute() { unit_->moveTo(x_, y_); } private: Unit* unit_; int x_, y_; }; This is a variation in how the Command pattern gets implemented. The Command object is specific, and is bound to a particular unit and place to move.

The input handling code will be creating an instance of MoveUnitCommand every time the player chooses a move. Something like: Command* handleInput() { Unit* unit = getSelectedUnit(); if (isPressed(BUTTON_UP)) { // Move the unit up one. int destY = unit->y() - 1; return new MoveUnitCommand(unit, unit->x(), destY); } if (isPressed(BUTTON_DOWN)) { // Move the unit down one. int destY = unit->y() + 1; return new MoveUnitCommand(unit, unit->x(), destY); } // Other moves... return NULL; }

To make commands undoable, we define another operation each Command subclass needs to implement: class Command { public: virtual ~Command() {} virtual void execute() = 0; virtual void undo() = 0; };

Here’s our previous move command with undo support: class MoveUnitCommand : public Command { public: MoveUnitCommand(Unit* unit, int x, int y) : unit_(unit), xBefore_(0), yBefore_(0), x_(x), y_(y) {} virtual void execute() { // Remember the unit's position before the move // so we can restore it. xBefore_ = unit_->x(); yBefore_ = unit_->y(); unit_->moveTo(x_, y_); } virtual void undo() { unit_->moveTo(xBefore_, yBefore_); } private: Unit* unit_; int xBefore_, yBefore_; int x_, y_; };

To let the player undo a move, we keep around the last command they executed. When they bang on Control-Z, we call that command’s undo() method. (If they’ve already undone, then it becomes “redo” and we execute the command again.) Supporting multiple levels of undo isn’t much harder. Instead of remembering the last command, we keep a list of commands and a reference to the “current” one. When the player executes a command, we append it to the list and point “current” at it.