0
 
MiniGames Rebuilding Three Classic Joe Linhoff Eugene Jarvis Darren Torpey
Missile Command, 1980 Atari
Learning Objectives <ul><li>dynamic object management with lists </li></ul><ul><li>C-style polymorphism  </li></ul><ul><li...
Dynamic Objects <ul><li>Don't know how many enemy missiles there will be at any time </li></ul><ul><li>Missiles can split ...
Dynamic Infrastructure init  body  final <ul><li>Good code construction requires guaranteed init and final </li></ul><ul><...
Game Controller Class  Owns Game Objects <ul><li>Simplifies collisions and other multi-type operations  </li></ul><ul><li>...
Game Objects <ul><li>Constructors must setup their own node </li></ul><ul><ul><li>LLMakeNode() here </li></ul></ul><ul><li...
Owners Must Always  Guarantee Cleanup <ul><li>Game::final() </li></ul><ul><ul><li>runs through all the lists of objects it...
Zap & Zap List <ul><li>Use while when unlinking </li></ul><ul><li>Zap </li></ul><ul><ul><li>unlink </li></ul></ul><ul><ul>...
Simple Doubly Linked C-Style Polymorphic Lists <ul><li>Build class with list node first </li></ul><ul><li>Unique type iden...
Upcoming SlideShare
Loading in...5
×

Gdc09 Minimissile

278

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
278
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Gdc09 Minimissile"

  1. 2. MiniGames Rebuilding Three Classic Joe Linhoff Eugene Jarvis Darren Torpey
  2. 3. Missile Command, 1980 Atari
  3. 4. Learning Objectives <ul><li>dynamic object management with lists </li></ul><ul><li>C-style polymorphism </li></ul><ul><li>screen to world, world to screen coordinate </li></ul>
  4. 5. Dynamic Objects <ul><li>Don't know how many enemy missiles there will be at any time </li></ul><ul><li>Missiles can split (MIRVs) </li></ul><ul><li>Don't know how many player missiles there will be at any time </li></ul><ul><li>The static ways will not work </li></ul><ul><li>Lists are the backbone of game development </li></ul><ul><li>Doubly linked lists make it easy and quick to unlink nodes </li></ul>
  5. 6. Dynamic Infrastructure init body final <ul><li>Good code construction requires guaranteed init and final </li></ul><ul><li>Init </li></ul><ul><ul><li>sets up all list heads </li></ul></ul><ul><li>Final </li></ul><ul><ul><li>runs through & frees all lists </li></ul></ul><ul><li>The lists 'own' the object </li></ul><ul><ul><li>write code such that only way to object is through list; do not keep any other copies </li></ul></ul><ul><ul><li>always test pointers before use </li></ul></ul><ul><ul><li>generally: one owner for every resource </li></ul></ul>
  6. 7. Game Controller Class Owns Game Objects <ul><li>Simplifies collisions and other multi-type operations </li></ul><ul><li>init is in constructor </li></ul><ul><ul><li>initializes all lists by making them list heads </li></ul></ul><ul><li>final is in 'final' </li></ul><ul><ul><li>zaps all remaining objects in lists </li></ul></ul><ul><ul><li>not destructor b/c we want more control </li></ul></ul><ul><li>idea is to clean up after yourself </li></ul>// JFL 13 Aug 08 Game::Game(chr *name) : qeUpdateBase(name,0,GAMEID_GAME) { this->name = qeObjName(this->_oShared); LLMakeHead(&this->listOfGameThings); LLMakeHead(&this->listOfWorlds); LLMakeHead(&this->listOfBuildings); LLMakeHead(&this->listOfPlayers); LLMakeHead(&this->listOfBadGuys); LLMakeHead(&this->listOfPlayerProjs); LLMakeHead(&this->listOfBadGuyProjs); } // Game::Game() // JFL 18 Aug 08 void Game::final() { // don't call directly, use objRemove() Game *game; if((game=Game::instance)) { gameZapList(&game->listOfBadGuyProjs); gameZapList(&game->listOfPlayerProjs); gameZapList(&game->listOfBadGuys); gameZapList(&game->listOfPlayers); gameZapList(&game->listOfBuildings); gameZapList(&game->listOfWorlds); gameZapList(&game->listOfGameThings); delete game; // free the C++ object Game::instance=0; // reset pointer } } // Game::final()
  7. 8. Game Objects <ul><li>Constructors must setup their own node </li></ul><ul><ul><li>LLMakeNode() here </li></ul></ul><ul><li>part of init </li></ul><ul><li>Destructor not explicitly needed </li></ul>// JFL 14 Aug 07 World::World(chr *name) { szcpy(this->name,sizeof(this->name),name,0); LLMakeNode(this,GAMEID_WORLD); SET3(this->xyzMin,-110,0,0); SET3(this->xyzMax,110,200,0); } // World::World() // JFL 14 Aug 07 int World::draw(void) { qefnDrawGrid(50,10); qefnDrawAxes(1); return 0; } // World::draw()
  8. 9. Owners Must Always Guarantee Cleanup <ul><li>Game::final() </li></ul><ul><ul><li>runs through all the lists of objects it owns and zaps them </li></ul></ul><ul><ul><li>after all the objects it owns are zapped, it deletes itself and zeros its Singleton instance pointer </li></ul></ul><ul><ul><li>not called directy, Game derives from qeUpdateBase and call to objRemove() causes engine to call final() when it's safe </li></ul></ul>// JFL 18 Aug 08 void Game::final() { // don't call directly, use objRemove() Game *game; if((game=Game::instance)) { gameZapList(&game->listOfBadGuyProjs); gameZapList(&game->listOfPlayerProjs); gameZapList(&game->listOfBadGuys); gameZapList(&game->listOfPlayers); gameZapList(&game->listOfBuildings); gameZapList(&game->listOfWorlds); gameZapList(&game->listOfGameThings); delete game; // free the C++ object Game::instance=0; // reset pointer } } // Game::final()
  9. 10. Zap & Zap List <ul><li>Use while when unlinking </li></ul><ul><li>Zap </li></ul><ul><ul><li>unlink </li></ul></ul><ul><ul><li>calls destructor </li></ul></ul><ul><ul><li>frees memory </li></ul></ul><ul><ul><li>'zap' b/c it's descriptive, short, not generally used, and cool </li></ul></ul>// JFL 25 Jan 09 int gameZapList(LLNode *head) { LLNode *n; while((n=head->next)&&n->t) gameZap(n); return 1; // nonzero return assumed } // gameZapList() // JFL 25 Jan 09 int gameZap(LLNode *n) { // unlink the game object LLUnlink(n); // call destructor for game objects switch(n->t) { case GAMEID_INPUT:((Input*)n)->~Input();break; case GAMEID_CAMERA:((Camera*)n)->~Camera();break; case GAMEID_HUD:((HUD*)n)->~HUD();break; case GAMEID_WORLD:((World*)n)->~World();break; case GAMEID_BUILDING:((Building*)n)->~Building();break; case GAMEID_PLAYER:((Player*)n)->~Player();break; case GAMEID_PROJ:((Proj*)n)->~Proj();break; case GAMEID_BADGUY:((BadGuy*)n)->~BadGuy();break; default: BRK(); // add handler for type } // switch // free the memory delete (qe*)n; return 1; // nonzero return assumed } // gameZap()
  10. 11. Simple Doubly Linked C-Style Polymorphic Lists <ul><li>Build class with list node first </li></ul><ul><li>Unique type identifiers signal type </li></ul><ul><li>Use static_cast<TYPE>(node) </li></ul><ul><li>Scanning is easy </li></ul>LLNode *n; BadGuy *bad; for(n=this->listOfBadGuys.next;n->t;n=n->next) { if(n->t!=GAMEID_BADGUY) continue; bad=(BadGuy*)n; // handle bad guy } // for <ul><li>Scan from any node forward or backward, skip list head </li></ul><ul><li>Use of continue to minimize nesting </li></ul><ul><li>&quot;Should&quot; use static_cast<>() </li></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×