Difference between revisions of "Intermediate C++ Game Programming Tutorial 18"
From Chilipedia
(→Video Timestamp Index) |
(→Video Timestamp Index) |
||
(34 intermediate revisions by the same user not shown) | |||
Line 85: | Line 85: | ||
** It avoids having to change a fighter into a different type when exchanging weaponry | ** It avoids having to change a fighter into a different type when exchanging weaponry | ||
</div> | </div> | ||
− | * One more real world example: "State Machine" for a Boss Battle [https://youtu.be/cdOB_gKnJOM?t=14m28s 14:28] | + | * One more real world example used in [[RPG Project Twin]]: a finite "State Machine" for a Boss Battle [https://youtu.be/cdOB_gKnJOM?t=14m28s 14:28] |
<div class="mw-collapsible-content"> | <div class="mw-collapsible-content"> | ||
− | ** A | + | ** A State Machine models patterns of behavior (like attack, evade, wander, find aid, etc.) |
** You can use virtual functions that control the boss (depending on type of behavior) and transition from one behavior to another, based on some condition | ** You can use virtual functions that control the boss (depending on type of behavior) and transition from one behavior to another, based on some condition | ||
** Very common pattern in game programming, e.g. using AI to model the behavior of enemies | ** Very common pattern in game programming, e.g. using AI to model the behavior of enemies | ||
</div> | </div> | ||
* Presenting the template class <code>Behavior</code> within the class <code>Entity</code> [https://youtu.be/cdOB_gKnJOM?t=15m22s 15:22] | * Presenting the template class <code>Behavior</code> within the class <code>Entity</code> [https://youtu.be/cdOB_gKnJOM?t=15m22s 15:22] | ||
− | * | + | * How to transition between behavioral states? [https://youtu.be/cdOB_gKnJOM?t=16m35s 16:35] |
+ | <div class="mw-collapsible-content"> | ||
+ | ** Associate each state with a stack of successor states that are consecutively called | ||
+ | ** The last state on this stack can then lead into a new chain (fill up another stack) | ||
+ | ** This again represents a combination of inheritance and composition: states are composed of other states as part of their "stack of states"... | ||
+ | ** ... avoiding an explosion of (derived) classes that would be needed to define this behavior with just inheritance | ||
+ | </div> | ||
+ | * The performance impact of using Virtual Functions [https://youtu.be/cdOB_gKnJOM?t=19m36s 19:36] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** The direct impact: If you use virtual functions in a class, all objects of that class will have to store a (hidden) pointer to a virtual function table ("vtable") | ||
+ | ** The v-table holds pointers to code for each virtual function supported by the object. It is used as a lookup table to determine which functions are being called at runtime | ||
+ | ** An indirect impact: because the compiler does not know which function will be called at runtime, it can't inline any virtual functions that are being dynamically bound | ||
+ | ** The difference in performance is generally not problematic, except for specific (rare) cases | ||
+ | </div> | ||
+ | * An example of where performance actually matters: The SpriteEffect system [https://youtu.be/cdOB_gKnJOM?t=21m07s 21:07] | ||
+ | <div class="mw-collapsible-content"> | ||
+ | ** The SpriteEffect system (see [[Intermediate C++ Game Programming Tutorial 14|Intermediate Tutorial 14]]) uses functors to define drawing behavior. These functors are called on heavily as they contain PutPixel calls | ||
+ | ** In theory, virtual functions would be nicer, as you could swap out different effects dynamically at runtime (can't do that with a functor). | ||
+ | ** However, in that scenario the use of virtual functions would introduce performance issues | ||
+ | ** The choice depends on the estimated frequency of function calls (relevant when greater than O(1E6) calls/second) | ||
+ | </div> | ||
</div> | </div> | ||
Line 106: | Line 126: | ||
* [[Intermediate C++ Game Programming Tutorial 19|Next in series (Tutorial 19)]] | * [[Intermediate C++ Game Programming Tutorial 19|Next in series (Tutorial 19)]] | ||
* [[Intermediate C++ Game Programming Series]] | * [[Intermediate C++ Game Programming Series]] | ||
+ | * [[RPG Project Twin]] |
Latest revision as of 03:55, 15 October 2019
Another two-parter here, and we got the real stuff now. Virtual functions allow you to unlock the true potential of inheritance in C++. You need to know this shit.
Contents
[hide]Topics Covered
Part 1
- How to create a virtual function
- Using the override keyword
- Creating a pure virtual function
- Using a container of pointers to manage a heterogeneous collection of objects
- virtual destructors
Part 2
- Using inheritance and composition together
- Basic idea of a polymorphic state machine and its application to entity behavior
Video Timestamp Index
[Expand]
- Creating a "Virtual Function" in the
MemeFighter
class 0:23
- Enabling "Dynamic Dispatch" by using
virtual
on the member function in the base class 3:17
- Applying the
override
keyword to increase code safety 5:17
- Making a base class member function "Pure Virtual" using
virtual void Func(...) = 0;
7:08
- We have now applied the concept of "Polymorphism" 9:16
- Applying Polymorphism to a container of pointers to the shared base type of different derived class objects 9:46
- Applying Polymorphism to objects created on the heap (dynamic memory management) 13:46
- "Virtual Destructors": Managing destructors in base and derived classes 14:48
- Review of termonology and concepts learned 19:49
[Expand]
- Design choices in class hierarchy: inheritance vs. composition 0:43
- Adjusting the MemeFighter code to include the
Weapon
class 4:20
- Add feature where one fighter can take the other fighter's weapon 11:36
- Recap of advantage of the inheritance-composition construct 14:00
- One more real world example used in RPG Project Twin: a finite "State Machine" for a Boss Battle 14:28
- Presenting the template class
Behavior
within the classEntity
15:22 - How to transition between behavioral states? 16:35
- The performance impact of using Virtual Functions 19:36
- An example of where performance actually matters: The SpriteEffect system 21:07
Source Code
Errata
- Forgot the virtual destructor for
class Weapon
! (this one hurts) - In the children, the function signatures should be:
int CalculateDamage( const Attributes& attr,Dice& d ) const override
- Though not technically an error, it might have been a better decision to make
Weapon::GetName()
andWeapon::GetRank()
(pure) virtual functions (this would reduce the amount of per-instance data to just the vtable ptr)