Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

ROBERT NYSTROM GAME PROGRAMMING PATTERNS III.8 Thema: Sequencing Patterns Seminar: Softwaretechnologie II (Teil 2) Dozent: Prof. Dr. Manfred Thaller Referent:

Ähnliche Präsentationen


Präsentation zum Thema: "ROBERT NYSTROM GAME PROGRAMMING PATTERNS III.8 Thema: Sequencing Patterns Seminar: Softwaretechnologie II (Teil 2) Dozent: Prof. Dr. Manfred Thaller Referent:"—  Präsentation transkript:

1 ROBERT NYSTROM GAME PROGRAMMING PATTERNS III.8 Thema: Sequencing Patterns Seminar: Softwaretechnologie II (Teil 2) Dozent: Prof. Dr. Manfred Thaller Referent: Alexander Abboud Universität zu Köln - Sommersemester 2015

2 Sequencing Patterns Jede Welt braucht eine Zeit  „Spieluhr“ muss für virtuelle Welten erfunden + eingebaut werden Double Buffer Game Loop Update Method

3 Sequencing Patterns Jede Welt braucht eine Zeit  „Spieluhr“ muss für virtuelle Welten erfunden + eingebaut werden Double Buffer Problem: Welt soll simultan nicht sequenziell erscheinen Lösung hierfür: Momentaufnahmen Game Loop Update Method

4 Double Buffering Beispiel: Flackern von Grafikinhalten Bild wird aus dem Framebuffer gelesen

5 Tearing / Flickering

6 Lösung: Double Buffering Vergleich mit verschiedenen Bühnen eines Theaterstücks  2 Framebuffer von einem wird gelesen, Bild auf ihm immer vollständig auf den anderen wird geschrieben anschließend: Tausch der beiden

7 Wann und Wie? Wann? Grafikinfos werden schrittweise verändert  Veränderungen sollen aber erst nach Abschluss zu sehen sein Tearing ist vorhanden (untere Bildteile fehlen). Das Bild flackert. Wie? Bufferklasse mit a) nächstem Buffer auf den geschrieben wird b) aktuellem Buffer von dem gelesen wird c) Tauschfunktion

8 class Framebuffer { public: Framebuffer() { clear(); } void clear() // der gesamte Buffer (jeder Pixel) wird auf weiß gesetzt { for (int i = 0; i < WIDTH * HEIGHT; i++) { pixels_[i] = WHITE; } void draw(int x, int y) // die in draw() aufgerufenen Pixel werden schwarz { pixels_[(WIDTH * y) + x] = BLACK; } const char* getPixels() { return pixels_; } private: static const int WIDTH = 160; static const int HEIGHT = 120; char pixels_[WIDTH * HEIGHT]; }; class Scene { public: void draw() { buffer_.clear(); buffer_.draw(1, 1); buffer_.draw(4, 1); buffer_.draw(1, 3); buffer_.draw(2, 4); buffer_.draw(3, 4); buffer_.draw(4, 3); } Framebuffer& getBuffer() { return buffer_; } private: Framebuffer buffer_; };

9 class Scene { public: // an dieser Stelle sind nun 2 Buffer: keine direkte Referenzierung, sondern 2 Pointer Scene() : current_(&buffers_[0]), // aus diesem Buffer wird immer gelesen next_(&buffers_[1]) // in diesen wird immer geschrieben {} void draw() { next_->clear(); next_->draw(1, 1); //... next_->draw(4, 3); swap(); // Aufruf am Ende des Zeichnens der swap-Funktion } Framebuffer& getBuffer() { return *current_; } private: void swap() { // Pointer werden einfach ausgetauscht Framebuffer* temp = current_; current_ = next_; next_ = temp; } Framebuffer buffers_[2]; Framebuffer* current_; Framebuffer* next_; };

10 Nicht nur für Grafiken: Beispiel 2 Spiel, bei dem sich Spieler gegenseitig schlagen, wenn sie selbst geschlagen wurden sie werden in eine Reihenfolge gestellt  immer der Nachfolgende wird geschlagen jeder Spieler erhält einen „slapped_“ Status das Ergebnis einer Runde soll dem User direkt sichtbar sein class Actor { public: Actor() : slapped_(false) {} // initial: nicht geschlagen virtual ~Actor() {} virtual void update() = 0; // bei jedem Frame, wird ein update aufgerufen void reset() { slapped_ = false; } void slap() { slapped_ = true; } // wenn ein anderer Spieler geschlagen wird bool wasSlapped() { return slapped_; } // wenn der Spieler selbst geschlagen wurde private: bool slapped_; };

11 class Stage { public: void add(Actor* actor, int index) { actors_[index] = actor; } void update() { for (int i = 0; i < NUM_ACTORS; i++) { actors_[i]->update(); actors_[i]->reset(); } private: static const int NUM_ACTORS = 3; Actor* actors_[NUM_ACTORS]; }; class Comedian : public Actor { public: void face(Actor* actor) { facing_ = actor; } virtual void update() { if (wasSlapped()) facing_->slap(); } private: Actor* facing_; }; die Spieler werden auf Stage verteilt mit der 1x pro Frame aufgerufenen update()- Methode werden die Spieler nacheinander geupdated sorgt dafür, dass ein geschlagener Spieler seinen Gegenüber („facing“) schlägt

12 Beispiel 2 Durch verschiedenes Positionieren der Spieler, kommen allerdings unterschiedliche Ergebnisse heraus: harry->slap(); stage.update(); Stage updates actor 0 (Harry) Harry was slapped, so he slaps Baldy Stage updates actor 1 (Baldy) Baldy was slapped, so he slaps Chump Stage updates actor 2 (Chump) Chump was slapped, so he slaps Harry Stage update ends harry->slap(); stage.update(); Stage updates actor 0 (Chump) Chump was not slapped, so he does nothing Stage updates actor 1 (Baldy) Baldy was not slapped, so he does nothing Stage updates actor 2 (Harry) Harry was slapped, so he slaps Baldy Stage update ends

13 Double Buffered Objects auch hier kann Double Buffering helfen jeder Spieler kriegt 2 slapped_ states: currentSlapped_  hieraus wird gelesen nextSlapped_  hier wird hineingeschrieben mit update() werden erste alle Statusse geupdated anschließend mit swap() getauscht

14 Besonderheiten swap()-Methode Performance und Komplexität vorheriger Inhalt wichtig?

15 Vielen Dank für die Aufmerksamkeit!


Herunterladen ppt "ROBERT NYSTROM GAME PROGRAMMING PATTERNS III.8 Thema: Sequencing Patterns Seminar: Softwaretechnologie II (Teil 2) Dozent: Prof. Dr. Manfred Thaller Referent:"

Ähnliche Präsentationen


Google-Anzeigen