Gdc09 Minimissile

445 views

Published on

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

  • Be the first to like this

No Downloads
Views
Total views
445
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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>

×