Gdc09 Minimissile
-
Upload
susan-gold -
Category
Documents
-
view
283 -
download
0
Transcript of Gdc09 Minimissile
![Page 1: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/1.jpg)
![Page 2: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/2.jpg)
MiniGamesRebuilding Three Classic
Joe LinhoffEugene JarvisDarren Torpey
![Page 3: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/3.jpg)
Missile Command, 1980Atari
![Page 4: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/4.jpg)
Learning Objectives
dynamic object management with lists
C-style polymorphism screen to world, world
to screen coordinate
![Page 5: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/5.jpg)
Dynamic Objects
Don't know how many enemy missiles there will be at any time
Missiles can split (MIRVs)
Don't know how many player missiles there will be at any time
The static ways will not work
Lists are the backbone of game development
Doubly linked lists make it easy and quick to unlink nodes
![Page 6: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/6.jpg)
Dynamic Infrastructureinit body final
Good code construction requires guaranteed init and final
Init sets up all list heads
Final runs through & frees all lists
The lists 'own' the object write code such that only way to object is through
list; do not keep any other copies always test pointers before use generally: one owner for every resource
![Page 7: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/7.jpg)
Game Controller Class Owns Game Objects
Simplifies collisions and other multi-type operations
init is in constructor initializes all lists by
making them list heads final is in 'final'
zaps all remaining objects in lists
not destructor b/c we want more control
idea is to clean up after yourself
// JFL 13 Aug 08Game::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 08void 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()
![Page 8: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/8.jpg)
Game Objects
Constructors must setup their own node LLMakeNode() here
part of init Destructor not
explicitly needed
// JFL 14 Aug 07World::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 07int World::draw(void){ qefnDrawGrid(50,10); qefnDrawAxes(1); return 0;} // World::draw()
![Page 9: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/9.jpg)
Owners Must Always Guarantee Cleanup
Game::final() runs through all the lists of objects it owns and zaps them after all the objects it owns are zapped, it deletes itself
and zeros its Singleton instance pointer not called directy, Game derives from qeUpdateBase
and call to objRemove() causes engine to call final() when it's safe
// JFL 18 Aug 08void 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()
![Page 10: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/10.jpg)
Zap & Zap List
Use while when unlinking
Zap unlink calls destructor frees memory 'zap' b/c it's
descriptive, short, not generally used, and cool
// JFL 25 Jan 09int gameZapList(LLNode *head){ LLNode *n; while((n=head->next)&&n->t) gameZap(n); return 1; // nonzero return assumed} // gameZapList()
// JFL 25 Jan 09int 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()
![Page 11: Gdc09 Minimissile](https://reader036.fdocuments.in/reader036/viewer/2022082811/55925dfa1a28ab6d278b45d6/html5/thumbnails/11.jpg)
Simple Doubly Linked C-Style Polymorphic Lists
Build class with list node first Unique type identifiers signal type Use static_cast<TYPE>(node) Scanning is easy
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
Scan from any node forward or backward, skip list head
Use of continue to minimize nesting "Should" use static_cast<>()