
<p>the </p><p>gamedesigninitiative </p><p>at cornell university </p><p>Lecture 8 </p><p>Component Design </p><p><strong>Recall</strong>: Problem with Subclassing </p><p>ꢀ Games have <em>lots </em>of classes </p><p>ꢀ Each game entity is different </p><p>NPC </p><p>ꢀ Needs its own functionality <br>(e.g. object methods) </p><p></p><ul style="display: flex;"><li style="flex:1">Human </li><li style="flex:1">Orc </li></ul><p></p><p>ꢀ Want to avoid <strong>redundancies </strong></p><p>ꢀ Makes code hard to change ꢀ Common source of bugs </p><p>Human Warrior <br>Human Archer </p><ul style="display: flex;"><li style="flex:1">Orc </li><li style="flex:1">Orc </li></ul><p></p><ul style="display: flex;"><li style="flex:1">Archer </li><li style="flex:1">Warrior </li></ul><p></p><p>ꢀ Might be tempted to <strong>subclass </strong></p><p>ꢀ Common behavior in parents ꢀ Specific behavior in children </p><p>Redundant Behavior </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>2</p><p>at cornell university </p><p><strong>Recall</strong>: Problem with Subclassing </p><p>ꢀ Games have <em>lots </em>of classes </p><p>ꢀ Each game entity is different </p><p>NPC </p><p>ꢀ Needs its own functionality <br>(e.g. object methods) </p><p></p><ul style="display: flex;"><li style="flex:1">Warrior </li><li style="flex:1">Archer </li></ul><p></p><p>ꢀ Want to avoid <strong>redundancies </strong></p><p>ꢀ Makes code hard to change ꢀ Common source of bugs </p><p>Human Warrior </p><ul style="display: flex;"><li style="flex:1">Orc </li><li style="flex:1">Human </li></ul><p>Archer <br>Orc </p><ul style="display: flex;"><li style="flex:1">Warrior </li><li style="flex:1">Archer </li></ul><p></p><p>ꢀ Might be tempted to <strong>subclass </strong></p><p>ꢀ Common behavior in parents ꢀ Specific behavior in children </p><p>Redundant Behavior </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>3</p><p>at cornell university </p><p><strong>Alternative</strong>: Decorator Pattern </p><p>New <br>Functionality </p><p>Original Object </p><p>Reference to Original </p><p>base object <br>Functionality </p><p>Decorator <br>Object </p><p>Request </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>4</p><p>at cornell university </p><p><strong>Alternate</strong>: Delegation Pattern </p><p>Original Object </p><p>Reference to </p><p>Delegate </p><p>Request delegate </p><p>Object </p><p>Forward Request </p><p><em>Inversion </em>of the Decorator Pattern </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>5</p><p>at cornell university </p><p>Issues with Static Typing </p><p>Method in original class <br>Original </p><p>object class </p><p>obj.request(arg<sub style="top: 0.6667em;">1</sub>,…, arg<sub style="top: 0.6667em;">n</sub>)ꢀ </p><p>Original Object </p><p>Reference to delegate </p><p>Delegate <br>Object </p><p>Request <br>Forward Request </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>6</p><p>at cornell university </p><p>The Subclass Problem Revisited </p><p>Delegates? </p><p>NPC <br>Orc </p><p>Slot Slot Slot </p><p>Human </p><ul style="display: flex;"><li style="flex:1">Human </li><li style="flex:1">Orc </li></ul><p>NPC </p><p>Warrior </p><p>Archer <br>Human Warrior <br>Human Archer </p><ul style="display: flex;"><li style="flex:1">Orc </li><li style="flex:1">Orc </li></ul><p></p><ul style="display: flex;"><li style="flex:1">Archer </li><li style="flex:1">Warrior </li></ul><p></p><p>Redundant Behavior </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>7</p><p>at cornell university </p><p>Component-Based Programming </p><p>Delegates </p><p>ꢀ <strong>Role</strong>: Set of capabilities </p><p>Role 1 </p><p>ꢀ Class with very little data ꢀ A collection of methods </p><p>Slot </p><p>Role 2 </p><p>ꢀ Add it to object as <em>delegate </em></p><p>Slot </p><p>Entity </p><p>ꢀ Object gains those methods </p><p>Role 3 Role 4 </p><p>Slot </p><p>ꢀ Acts as a “function pointer” </p><p>ꢀ <em>Can-it</em>: search object roles </p><p>ꢀ Check class of each role ꢀ Better than duck typing ꢀ Possible at compile time? </p><p>Field storing a single delegate or </p><p>a <strong>set of delegates </strong></p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>8</p><p>at cornell university </p><p>Aside: Objective-C </p><p>ꢀDelegates are emphasized in <strong>Objective-C </strong></p><p>ꢀ ObjC <em>protocols </em>function like Java interfaces ꢀ But implement with a delegate, not a subclass </p><p>ꢀOften leverages <strong>message passing </strong></p><p>ꢀ Method call is considered a message ꢀ Can call <em>any </em>method on <em>any </em>object ꢀ Will get runtime error if method not supported ꢀ Heavily optimized in latest Apple compilers </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>9</p><p>at cornell university </p><p>Aside: Objective-C </p><p>ꢀDelegates are emphasized in <strong>Objective-C </strong></p><p>ꢀ ObjC <em>protocols </em>function like Java interfaces ꢀ But implement with a delegate, not a subclass </p><p>ꢀOften leverages <strong>message passing </strong></p><p>ꢀ Method call is considered a message ꢀ Can call <em>any </em>method on <em>any </em>object ꢀ Will get runtime error if method not supported ꢀ Heavily optimized in latest Apple compilers </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>10 </p><p>at cornell university </p><p>Working With Static Typing </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Uniform Method </strong></li><li style="flex:1"><strong>Direct Access </strong></li></ul><p></p><p>ꢀ</p><p>if (o has role) {ꢀ o.doSomething(kitchenSink)ꢀ </p><p>extract role from oꢀ role.doSomething(info)ꢀ </p><p>}ꢀ </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>11 </p><p>at cornell university </p><p>Working With Static Typing </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Uniform Method </strong></li><li style="flex:1"><strong>Direct Access </strong></li></ul><p></p><p>ꢀ</p><p>if (o has role) {ꢀ o.doSomething(kitchenSink)ꢀ </p><p>extract role from oꢀ role.doSomething(info)ꢀ </p><p>}ꢀ </p><p><strong>Problem</strong>: </p><p>Multiple capabilities </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>12 </p><p>at cornell university </p><p>Working With Static Typing </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Uniform Method </strong></li><li style="flex:1"><strong>Direct Access </strong></li></ul><p></p><p>ꢀ</p><p>if (o has role) {ꢀ o.doSomething(kitchenSink)ꢀ </p><p>extract role from oꢀ role.doSomething(info)ꢀ </p><p>}ꢀ </p><p><strong>Problem</strong>: </p><p><strong>Problem</strong>: </p><p>Big switch statements <br>Multiple capabilities </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>13 </p><p>at cornell university </p><p>Entities Need Both Is-a and Can-it ꢀ </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Table </strong></li><li style="flex:1"><strong>Chair </strong></li></ul><p></p><p>Objects share same capabilities <em>in theory</em>. But certain actions are <strong>preferred </strong>on each. </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>14 </p><p>at cornell university </p><p>Solving the Problem </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Can-It </strong></li><li style="flex:1"><strong>Is-A </strong></li></ul><p></p><p>ꢀ Indicated by object <strong>roles </strong></p><p>ꢀ Component indicates role ꢀ Check type of each role ꢀ So again a typing solution </p><p>ꢀ Indicated by object <strong>class </strong></p><p>ꢀ But could do more than that </p><p>ꢀ Keep a bag of types </p><p>ꢀ Contains of the descriptions that apply to this object </p><p>ꢀ “Formal duck typing” </p><p>ꢀ <strong>Example</strong>: table, heirloom </p><p>ꢀ Not limited to method name ꢀ Role type indicates action </p><p>ꢀ Why would we do this? </p><p>name, not a noun </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>15 </p><p>at cornell university </p><p>Fast Can-It Testing: Bit Vectors </p><p>ꢀGive each object a bit-vector to cover types </p><p>ꢀ Each role is a position in the bit vector </p><p>ꢀ <strong>Example</strong>: </p><p>0100101ꢀ </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>16 </p><p>at cornell university </p><p>Fast Can-It Testing: Bit Vectors </p><p>ꢀGive each object a bit-vector to cover types </p><p>ꢀ Each role is a position in the bit vector </p><p>ꢀ <strong>Example</strong>: </p><p>0100101ꢀ </p><p>Can Build </p><ul style="display: flex;"><li style="flex:1">Can Fight </li><li style="flex:1">Can Heal </li></ul><p></p><p>ꢀ Use array if more than 32/64 roles </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>17 </p><p>at cornell university </p><p>Fast Can-It Testing: Bit Vectors </p><p>ꢀGive each object a bit-vector to cover types </p><p>ꢀ Each role is a position in the bit vector </p><p>ꢀ <strong>Example</strong>: </p><p>0100101ꢀ </p><p>Can Build </p><ul style="display: flex;"><li style="flex:1">Can Fight </li><li style="flex:1">Can Heal </li></ul><p></p><p>ꢀ Use array if more than 32/64 roles </p><p>ꢀTest is quick logical operation. </p><p>ꢀ <strong>Example</strong>: vector & CAN_FIGHTꢀ </p><p>ꢀ Faster than dynamic typing (why?) </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>18 </p><p>at cornell university </p><p>Model-Controller Separation Revisited </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Model </strong></li><li style="flex:1"><strong>Controller </strong></li></ul><p></p><p>ꢀ Store/retrieve <strong>object data </strong>ꢀ Process <strong>interactions </strong></p><p>ꢀ Preserve any invariants ꢀ Data may include delegates ꢀ Determines is-a properties <br>ꢀ Look at current game state ꢀ Look for “triggering” event ꢀ Apply interaction outcome </p><p><strong>Components </strong></p><p></p><ul style="display: flex;"><li style="flex:1">?</li><li style="flex:1">?</li></ul><p></p><p>ꢀ Process <strong>game actions </strong></p><p>ꢀ Attached to a entity (model) ꢀ Uses the model as context ꢀ Deter<sub style="top: 0.7792em;">A</sub>m<sub style="top: 0.7792em;">rc</sub>i<sub style="top: 0.7792em;">h</sub>n<sub style="top: 0.7792em;">ite</sub>e<sub style="top: 0.7792em;">c</sub>s<sub style="top: 0.7792em;">tur</sub>c<sub style="top: 0.7792em;">e</sub>a<sub style="top: 0.7792em;">P</sub>n<sub style="top: 0.7792em;">at</sub>-<sub style="top: 0.7792em;">t</sub>i<sub style="top: 0.7792em;">e</sub>t<sub style="top: 0.7792em;">rn</sub>p<sub style="top: 0.7792em;">s </sub>roperties </p><p>the </p><p>gamedesigninitiative </p><p>19 </p><p>at cornell university </p><p>Model-Controller Separation Revisited </p><p></p><ul style="display: flex;"><li style="flex:1"><strong>Model </strong></li><li style="flex:1"><strong>Controller </strong></li></ul><p></p><p>ꢀ Store/retrieve <strong>object data </strong>ꢀ Process <strong>interactions </strong></p><p>ꢀ Preserve any invariants ꢀ Data may include delegates ꢀ Determines is-a properties <br>ꢀ Look at current game state ꢀ Look for “triggering” event ꢀ Apply interaction outcome </p><p><strong>Components </strong></p><p>Is this always the best idea? </p><p></p><ul style="display: flex;"><li style="flex:1">?</li><li style="flex:1">?</li></ul><p></p><p>ꢀ Process <strong>game actions </strong></p><p>ꢀ Attached to a entity (model) ꢀ Uses the model as context ꢀ Deter<sub style="top: 0.7792em;">A</sub>m<sub style="top: 0.7792em;">rc</sub>i<sub style="top: 0.7792em;">h</sub>n<sub style="top: 0.7792em;">ite</sub>e<sub style="top: 0.7792em;">c</sub>s<sub style="top: 0.7792em;">tur</sub>c<sub style="top: 0.7792em;">e</sub>a<sub style="top: 0.7792em;">P</sub>n<sub style="top: 0.7792em;">at</sub>-<sub style="top: 0.7792em;">t</sub>i<sub style="top: 0.7792em;">e</sub>t<sub style="top: 0.7792em;">rn</sub>p<sub style="top: 0.7792em;">s </sub>roperties </p><p>the </p><p>gamedesigninitiative </p><p>20 </p><p>at cornell university </p><p><strong>Recall</strong>: Lab 3 in CS 3152 </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>21 </p><p>at cornell university </p><p>Processing Actions in Lab 3 </p><p>GameplayController.cs <br>Ship.cs </p><p></p><ul style="display: flex;"><li style="flex:1">ꢀ Decides whether to shoot </li><li style="flex:1">ꢀ Waits until objects commit </li></ul><p>ꢀ Checks intent in Ship object ꢀ Performs action for intent <br>ꢀ Stores intent in the object </p><p>ꢀ But <strong>DOES NOT </strong>shoot </p><p>the </p><p>gamedesigninitiative </p><p>Game Architecture </p><p>22 </p><p>at cornell university </p><p>Processing Actions in Lab 3 </p><p>GameplayController.cs </p><p>Attach components to controller? </p><p>Ship.cs </p><p></p><ul style="display: flex;"><li style="flex:1">ꢀ Decides whether to shoot </li><li style="flex:1">ꢀ Waits until objects commit </li></ul><p>ꢀ Checks intent in Ship object ꢀ Performs action for intent <br>ꢀ Stores intent in the object </p><p>ꢀ But <strong>DOES NOT </strong>shoot </p><p>the </p><p>gamedesigninitiative </p><p>Game Architecture </p><p>23 </p><p>at cornell university </p><p><strong>Related</strong>: Handling the View </p><p>ꢀ Way too much to draw </p><p>ꢀ Backgrounds ꢀ UI elements </p><p>Update Draw </p><p>ꢀ Individual NPCs ꢀ Other moveable objects </p><p>ꢀ Cannot cram all in Draw ꢀ Put it in game object? </p><p>ꢀ But objects are models </p><p>ꢀ Violates MVC <strong>again </strong></p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>24 </p><p>at cornell university </p><p>First Attempt: A Drawing Canvas </p><p>ꢀ Treat display as a <strong>container </strong></p><p>ꢀ Often called a canvas ꢀ Cleared at start of frame ꢀ Objects added to container ꢀ Draw contents at frame end </p><p>Passed as reference </p><p>ꢀ Canvas abstracts <em>rendering </em></p><p>ꢀ Hides animation details </p><p>void draw(Canvas c) {ꢀ </p><p>// Specify perspectiveꢀ // Add to canvas </p><p>}ꢀ </p><p>ꢀ Like working with widget </p><p>ꢀ Implement draw(c) in model </p><p>ꢀ Classic heavyweight model ꢀ No problems with extension </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>25 </p><p>at cornell university </p><p><strong>Problem</strong>: Canvas Methods </p><p>Ideal </p><p><strong>Model1 </strong></p><p>draw(canvas)ꢀ </p><p><strong>Canvas </strong></p><p>drawShape(…)ꢀ </p><p><strong>Model2 </strong></p><p>draw(canvas)ꢀ </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>26 </p><p>at cornell university </p><p><strong>Problem</strong>: Canvas Methods </p><p>In Practice </p><p><strong>Model1 </strong></p><p>draw(canvas)ꢀ </p><p><strong>Canvas </strong></p><p>drawShape1(…)ꢀ drawShape2(…)ꢀ </p><p><strong>Model2 </strong></p><p>draw(canvas)ꢀ </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>27 </p><p>at cornell university </p><p>Views and Components </p><p>Slot </p><p><strong>Component1ꢀ </strong></p><p>drawShape1(…)ꢀ </p><p>Slot Slot </p><p><strong>Model1 Model2 </strong></p><p><strong>Canvas </strong></p><p>drawPrimitive(…)ꢀ </p><p>Slot Slot Slot </p><p><strong>Component1ꢀ </strong></p><p>drawShape1(…)ꢀ </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>28 </p><p>at cornell university </p><p>Views and Components </p><p>Primitive effects </p><p>Slot </p><p><strong>Component1ꢀ </strong></p><p>Slot </p><p><strong>Model1 </strong></p><p>drawShape1(…)ꢀ </p><p>Slot </p><p>Complex, <br>Shape-specific rendering </p><p>Slot </p><p><strong>Canvas </strong></p><p>drawPrimitive(…)ꢀ </p><p><strong>Component1ꢀ </strong></p><p>drawShape1(…)ꢀ </p><p>Slot </p><p><strong>Model2 </strong></p><p>Slot </p><p>the </p><p>gamedesigninitiative </p><p>Architecture Patterns </p><p>29 </p><p>at cornell university </p><p>Components and AI </p><p><strong>Alert! </strong></p><p>ꢀ NPCs use sense-think-act cycle </p><p>ꢀ <strong>Sense</strong>: perceive the world ꢀ <strong>Think</strong>: choose an action ꢀ <strong>Act</strong>: update the game state </p><p>ꢀ <strong>Act </strong>is stored in components </p><p>ꢀ Capabilities given by roles </p><p>ꢀ Where are <strong>sense </strong>and <strong>think</strong>? </p><p>Yes </p><p>ꢀ In the component/role? </p><p>This is hard </p><p>ꢀ How do roles interact? </p><p>the </p><p>gamedesigninitiative </p><p>Game Architecture </p><p>30 </p><p>at cornell university </p>
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages40 Page
-
File Size-