goals
play

Goals Understand use of Dragonfly from game Dragonfly programmers - PDF document

2/7/2012 Goals Understand use of Dragonfly from game Dragonfly programmers perspective Mostly, Project 1 Provide overview of Dragonfly architecture Class diagrams Discuss details needed to fully implement Dragonfly classes


  1. 2/7/2012 Goals � Understand use of Dragonfly from game Dragonfly programmer’s perspective � Mostly, Project 1 � Provide overview of Dragonfly architecture � Class diagrams � Discuss details needed to fully implement Dragonfly classes \ ____ Outline – Part I ~==- Saucer Shoot /__o_\ / � Saucer Shoot (next) � What is this code In Saucer::move(): � Overview doing? … move_countdown--; � Managers � When is this method if (move_countdown > 0) return; � Logfile Management called? move_countdown = move_slowdown; … � Game Management � Why do it this way? \ ____ \ ____ ~==- Saucer Shoot /__o_\ ~==- Saucer Shoot /__o_\ / / void Explosion::step() { time_to_live--; � What is this code if (time_to_live <= 0){ void Saucer::move() { WorldManager &world_manager=WorldManager::getInstance(); doing? … world_manager.markForDelete(this); x = pos.getX(); } � Why not do it this way? y = pos.getY(); } Position new_pos; � What should be done � What is time_to_live here? What is it set to new_pos.setX(x-1); new_pos.setY(y); instead? initially? this -> setPos(new_pos) … � What is happening when time_to_live is 0? � Why not just call own destructor? i.e. this->~Saucer() 1

  2. 2/7/2012 C++: Do Not Explicitly Call Destructor C++: Do Not Explicitly Call Destructor void someCode() { void someCode() { File f; { ...code that should execute when f is still open... File f; ← We want the side-effect of f's destructor here! ...code that should execute when f is still open... ...code that should execute after f is closed... } ← f's destructor automatically called here! } ...code that should execute after f is closed... } � Suppose File destructor closes file � What if cannot wrap in local block? � Can you call destructor now? � make close()? � If not, how to fix? C++: Do Not Explicitly Call Destructor C++: Do Not Explicitly Call Destructor class File { � What if allocated via new (as in Saucer Shoot)? public: void close(); ~File(); Bob *p = new Bob(); ... p->~Bob(); // should you do this? private: int fileHandle; // fileHandle >= 0 iff it's open }; � Still, no! File::~File() { close(); � Remember, delete p does two things } � Calls destructor void File::close() { if (fileHandle >= 0) { � Deallocates memory ...code that calls the OS to close the file... fileHandle = -1; } Bob *p = new Bob(); } … delete p; // automagically calls p->~Bob() � User then could call f.close() explicitly Outline – Part I Summary – Destructors and Dragonfly � Don’t call destructor explicitly � Saucer Shoot (done) � For memory allocated by new , use delete � Overview (next) when possible � Managers � For game engine (Dragonfly), want engine to � Logfile Management release memory � Game Management � Use WorldManager::markForDelete() 2

  3. 2/7/2012 Managers Dragonfly Game Engine Dragonfly Classes Game objects Support classes LogManager Saucer: move() Star: onEvent() Manager GAME CODE Hero: key() GameOver: step() ResourceManager WorldManager GraphicsManager InputManager GameManager GameObjectList GameObject DrawCharacter GetKey Sprite Clock InsertObject DRAGONFLY MoveObject GameObjectListIterator Box LoadSprite SendEvent Position Event Allocate memory File open/close COMPUTER PLATFORM Clear display Get keystroke EventStep EventMouse EventCollision EventOut EventKeyboard Managers in C++: Global Variables? Engine Support Systems - Managers � Could make Managers global variables (e.g. outside of � Support systems that manage crucial tasks main() ) � Handling input, Rendering graphics, Logging data � Constructors called before main(), destructors when main() � … ends � Then, declare global variable: � Many interdependent, so startup order matters RenderManager render_manager; � E.g. Log file manager needed first since others log � However, order of constructor/destructor unpredictable messages � E.g. RenderManager r; GraphicsManager g; � E.g. Graphics manager may need memory allocated � Could call g::g() before r::r() ! for sprites, so need Memory manager first. � Plus, explicit globals difficult from library � Often, want only 1 instance of each Manger � Names could be different in user code � E.g. Undefined if two objects managing the graphics � How about static variables inside a function � How to enforce only 1 instance in C++? Managers in C++: Static Variables? Managers: C++ Singletons � Remember, static � Compiler won’t allow class MySingleton { private: void stuff() { variables retain value // Private constructor MySingleton s; static int x = 0; MySingleton(); cout << x; � Instead: // Can’t assign or copy after method terminates MySingleton(MySingleton const& copy); x++; MySingleton& operator=(MySingleton const& copy); � Static variables inside MySingleton &s= } public: // return the 1 and only 1 MySingleton main() { MySingleton::getInstance(); method not created until static MySingleton& getInstance() { stuff(); // prints 0 static MySingleton instance; � Guarantees only 1 copy of return instance; stuff(); // prints 1 method invoked } } MySingleton will exist }; � Use inside Manager class � Use for Dragonfly Managers method go “create” � However, also want to explicitly control when manager � the Singleton starts (not at first getInstance() ) call) � Use startUp() and shutDown() for each 3

  4. 2/7/2012 The Manager Interface Outline – Part I � Saucer Shoot (done) � Overview � All Dragonfly “managers” inherit from this class (done) � Managers (done) � Logfile Management (next) � Game Management Game Engine Messages The LogManager - Functionality � If all goes well, only want game output � Control output to log file � But during development, often not the case � Upon startup � open file � Even for players, may have troubles running game � Upon shutdown � close file � Generally, need help debugging � Attributes � Debuggers are useful tools, but some bugs not easy to � Need file handle find in debugger � What else? � Some bugs timing dependent, only happen at full speed � Some caused by long sequence of events, hard to trace by � Method for general-purpose messages via writeLog() hand � E.g. “Player is moving” � Most powerful debug tool can still be print messages � E.g. “Player is moving to (x,y)” with x and y passed in (e.g. printf() ) � Associate time with each message � However, standard printing difficult when graphical � Could be in “game time” (e.g. game loop iterations) display � Could be in “real time” (i.e. wall-clock � we’ll do this) � One Solution � Print to file General Purpose Output General Purpose Output � For writeLog(), using printf() one of the � Need <stdarg.h> most versatile � Create a va_list #include <stdio.h> � But takes variable number of arguments � Structure gets initialized #include <stdarg.h> with arguments printf(“Bob wrote 123 lines”); // 1 arg void writeLog( const char * fmt, ... ) { � va_start() with printf(“%s wrote %d lines”, “Bob”, 123); // 3 args fprintf( stderr, “Error: ” ); va_list args; name of last known arg � Solution � allow variable number of arguments va_start( args, fmt); � Can then do printf(), vprintf( stderr, fmt, args ); passed into writeLog() va_end( args ); but with va_list } � Specify with “…”: � vprintf() � va_end() when done void writeLog(const char *fmt, …) { … } 4

Recommend


More recommend