1 / 52

Topic 07: Interactivity for Games

Topic 07: Interactivity for Games. Overview. Techniques Timer and its events Collision detection and response for loop and Array (review) Main example: Air Raid AirRaid.swf in W drive Release Assignment 2 See Assignment.02 folder. Skeleton Program. AirRaid_skeleton.fla.

chessa
Télécharger la présentation

Topic 07: Interactivity for Games

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Topic 07: Interactivity for Games SCM-CityU

  2. Overview • Techniques • Timer and its events • Collision detection and response • for loop and Array (review) • Main example: Air Raid • AirRaid.swf in W drive • Release Assignment 2 • See Assignment.02 folder SCM-CityU

  3. Skeleton Program • AirRaid_skeleton.fla Based on an example in book:ActionScript 3.0 Game Programming University, 2nd Edition SCM-CityU

  4. Frame 1 stop(); startButton.addEventListener(MouseEvent.CLICK,clickStart); function clickStart(event:MouseEvent){ startButton.removeEventListener(MouseEvent.CLICK,clickStart); gotoAndStop(2);// go to frame for main game } Name: startButton SCM-CityU

  5. Frame 2 // control the movement of the gun stage.addEventListener(MouseEvent.MOUSE_MOVE, onGunMove); function onGunMove(e:MouseEvent):void{ gun.x = e.stageX;// use mouse to control gun’s translation } // score board initialization var shotsHit:int=0; var timeLeft:int=10; updateGameScore(); functionupdateGameScore():void{ shotsHitTxt.text=String("Score: "+ shotsHit); timeLeftTxt.text=String("Time Left: "+ timeLeft); } Name: shotsHitTxt Name: gun Name: timeLeftTxt SCM-CityU

  6. Frame 3 Name: playAgainButton playAgainButton.addEventListener(MouseEvent.CLICK,clickPlayAgain); function clickPlayAgain(event:MouseEvent){ playAgainButton.removeEventListener( MouseEvent.CLICK,clickPlayAgain); gotoAndStop(2);// go back to main frame to restart game } SCM-CityU

  7. Timer SCM-CityU

  8. Timer (ref) • Usage 1: continuous updating for every user-specified interval(e.g., for programmatic animation) • E.g., rotating second hand per second • timer_events.swf • Updating frequency is specifiedby you, largely independent of Flash’s FPS setting • E.g., for every 1 second • Cf. ENTER_FRAME: animation synchronized with Flash runtime’s frame rate • E.g., Corresponding event listener will be invoked for 30 times per second (due to FPS = 30) SCM-CityU

  9. Timer (ref) • Usage 2: count down • Allowing to perform certain action after a given time period SCM-CityU

  10. Creating Timers • Timer is a complex data type • Syntax of variable definition for complex data type • Number of parameters can be zero, e.g., our SymbolDuck from last class (data type by us) • var duck:SymbolDuck = new SymbolDuck(); • var varName:ComplexType = newComplexType(para1, …, para2); SCM-CityU

  11. Creating Timers • Timer has two parameters (ref) • interval: in milliseconds between timer event • TimerEvent.TIMER event happens whenever a timer reaches the specified interval • E.g., if interval = 1000, there is a TimerEvent.TIMER event for every second • An interval lower than 20 milliseconds is NOT recommended (too fast), which may causes runtime problems • repeatCount: total number of TimerEvent.TIMER needed • E.g., if repeatCount = 10, the timer will stop after 10 TimerEvent.TIMER events are completed;it will then trigger a TimerEvent.TIMER_COMPLETE • If zero (by default), the timer repeats infinitely Timer(interval:Number, repeatCount:int=0) SCM-CityU

  12. Starting/Stopping Timers • Timer instance will not start to invoke events until you call its start()method • If your timer doesn’t work, it is often because you forget to start the timer (common problem)! • To stop the timer, call its stop() method var timer:Timer =new Timer(1000,2); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); var i:int=0; function onTimer(e:TimerEvent):void{ i++; trace("number of repetitions", i); } SCM-CityU

  13. Example var timer:Timer =new Timer(1000); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); function onTimer(evt:TimerEvent):void{ watch.hand.rotation +=5; } SCM-CityU

  14. Class Exercise • New year countdown • Count down from 10 to 1 • Output one number per second • Output “Happy New Year” 1 second after “1” is outputted • I.e., output “Happy New Year” instead of “0” • Hint: we need to output 11messages, one per second SCM-CityU

  15. for Loop vs ENTER_FRAME/Timer • All of them allow repetitive execution of some code • However, unlike ENTER_FRAME or Timer, for loop itself is NOT sufficient for creating animation • Because of no frame refreshing for individual (for) iterations • E.g., NoAnimationWithForLoop.flavs AnimationWithTimer.fla var speed:Number=10; for(var i:uint =0; i <20; i++){ circle.x += speed; circle.y += speed; } Direct jumping SCM-CityU

  16. Back to Main Example • Task: creating multiple planes in a random manner • Random intervals: use Timer • Random side: starting from either left or right • Random speed: random velocity; direction is dependent on which side the plane comes from • Random altitude • Random plane shape: one out of 5 plane models SCM-CityU

  17. Random Intervals • It seems easy to make timer interval random • E.g., var t:Timer = new Timer(100+100*Math.random()); • But such solution still cannot make the delay for creating individual planes random • E.g., waiting for 1 second before creating Plane 1; waiting for 0.78 second before creating Plane 2 • In fact, with such timer, every plane will be created for a fixed interval SCM-CityU

  18. Random Intervals • Solution • setTimer function below initializes a timer with random interval. This function will be repeated at random intervals var t:Timer; setTimer(); function setTimer():void{ t =new Timer(1000+Math.random()*1000,1); t.addEventListener(TimerEvent.TIMER_COMPLETE, timerComplete); t.start(); } function timerComplete(e:TimerEvent):void{ // create a plane // ... // for next timer with random interval setTimer(); } SCM-CityU

  19. Example • TimerWithRandomInterval.fla var t:Timer; setTimer(); functionsetTimer():void{ t =new Timer(1000+Math.random()*1000,1); t.addEventListener(TimerEvent.TIMER_COMPLETE,timerComplete); t.start(); } functiontimerComplete(e:TimerEvent):void{ // create a circle and add it to stage var c:Symbol1 =new Symbol1(); c.x=stage.stageWidth*Math.random(); c.y=stage.stageHeight*Math.random(); addChild(c); // for next timer with random interval setTimer(); } SCM-CityU

  20. Review: Dynamically Creating Display Objects in AS • Create a class name for your symbol • E.g., MySymbol • Create a symbol instance in AS • E.g., var s:MySymbol = newMySymbol(); • Display it to stage • addChild(s); SCM-CityU

  21. Review: Instance Name vs Class Name • Instance name: like variable name in AS • If your AS wants to directly assess some existing symbol instance on stage, assign instance name • Class name: like data type in AS • If your AS wants to dynamically create new symbol instances, create class name for your symbol! • Class naming style is the same asvariable/instance naming style This name has no special usage SCM-CityU

  22. SCM-CityU

  23. Scope of Variables • Local variables • Defined in function bodies (in-between function {}) • Can be used only within the function where variables are created • Can preventname collision • Global variables • Can be accessedeverywhere var v01:Number=3;// global variable function show1():void{ var v02:Number=4;// local variable var v03:Number=5;// local variable trace(v01);// 3 } function show2():void{ var v02:Number=6;// local variable trace(v02);// 6 trace(v03);// compilation error: local variable in show1 } show1(); show2(); trace(v01);// 3 trace(v02);// compilation error: local variable in show1/show2 trace(v03);// compilation error: local variable in show1 SCM-CityU

  24. Random Speed • Each plane has a random speed • How to store such set of random speed values? • Solution 1: create another array to store speed values • For plane planes[i], its corresponding speed is planeSpeedArray[i] var planeSpeedArray:Array=newArray(); SCM-CityU

  25. Random Speed • Solution 2: associate speed directly with each plane(much simpler!) • Airplane is a complex data type • For complex data type, you can create temporary propertiesby assignment operator • Such temporary properties behave exactly the same as predefined properties like x, y, alpha etc. • You might use any valid variable name as property name, e.g., p.speed =Math.random()* 8 + 3; p.speedX =Math.random()* 8 + 3; SCM-CityU

  26. Random Side • Originally planes are designed for right-to-left flight • Need to flipping shape for planes from left border • By setting scaleX = -1 • Exact transformation will depend on the location of registration point • E.g., example below has registration at top-left corner x x scaleX = -1 Y Y SCM-CityU

  27. SCM-CityU

  28. Class Exercise • Task: fire a bullet for each mouse click • Create an Array: name bullets • Add event listener for MouseEvent.CLICK • Inside this event listener, create a bullet and add it to stage • In this exercise, don’t bother the movement of bullets SCM-CityU

  29. Make Planes Moving for(declare counter; condition; update counter){ // statement(s) to execute repeatedly // as long as condition is true } for(var i:int=1; i <=100; i++){ trace(i); } • Review: for loop structure • Starting with for keyword • Example Spring 2012 SCM-CityU SCM-CityU 29

  30. Make Planes Moving • Class exercise • Make each plane planes[i] move at speed of planes[i].speed • Hint: use for loop to access every plane in planes array SCM-CityU

  31. Removing Off-Screen Planes • Since we’re keeping inserting new planes, we have to remove planes that are off screen • Otherwise we’ll lead to many unused planes in RAM • But how? • Question 1: how to check? • Depending on flight direction • (p.speed < 0 && p.x < 0) || (p.speed > 0 && p.x > stage.stageWidth) • Question 2: how to remove such planes from stage and planes array? • Removal from stage is easy. Just use removeChild(plane); • How to remove all off-screen planes from the array? • Use Array.pop()? But this removes the last element of the array only. What if the element to be removed has an arbitrary index? SCM-CityU

  32. Removing Off-Screen Planes from Array • Solution: use Array’s splice method (ref) • splice(startIndex:int, deleteCount:uint): Array; • startIndex: where the deletion begins • deleteCount: number of elements to be deleted • Returning an array containing the elements that were removed var vegetables:Array=newArray( "spinach","green pepper","cilantro","onion","avocado"); // remove 2 elements starting at index 2 var spliced:Array= vegetables.splice(2,2); trace(vegetables);// spinach,green pepper,avocado trace(spliced);// cilantro,onion SCM-CityU

  33. Removing Off-Screen Planes from Array • How can we use splice together with for loop? • For example, how to remove all elements that are equal to 3 from an array below? • Above solution is wrong! Why? var a:Array=[3,3,5,6,7,3,3,5,7,3]; for(var i:uint =0; i < a.length; i++){ if(a[i]==3){ a.splice(i,1); trace(a); } } trace("final: ", a); SCM-CityU

  34. Removing Off-Screen Planes from Array • Some 3 cannot be removed successfully! Iteration 0 3 3 3 5 5 6 6 7 7 3 3 3 3 5 5 7 7 3 3 First 3 is sliced and i++ i=0 i=1 Iteration 1 SCM-CityU

  35. Removing Off-Screen Planes from Array • Correct solution: bottom-up iteration var a:Array=[3,3,5,6,7,3,3,5,7,3]; for(var i:int= a.length-1; i >=0; i--){ if(a[i]==3){ a.splice(i,1); trace(a); } } trace("final: ", a); 3 3 3 3 5 5 6 6 7 7 3 3 3 3 5 5 7 7 3 i=9 i=8 Iteration 0 Iteration 1 SCM-CityU

  36. Class Exercise • Task: making bullets moving! • You can get the ideas from movePlanes function SCM-CityU

  37. Next Step • Check if any bullet hitsany plane SCM-CityU

  38. Collision Detection & Response SCM-CityU

  39. Collision Detection (wiki) • Building block for many applications, e.g., games • Detecting if objects intersect with each other • Detection complexity depends on shape complexity SCM-CityU

  40. Collision Detection in AS • Collision against stage borders or other boundaries SCM-CityU

  41. Collision Detection in AS • Collision between complex objects • Use DisplayObject’s hitTestObject method or hitTestPoint method • E.g., bird.hitTestObject(wall); SCM-CityU

  42. hitTestObject Method (ref) • Check if bounding boxes of two display objects intersect with each other • Check if two corresponding rectangles overlap or not • E.g., bird.hitTestObject(wall); • Return true if intersection detected; false otherwise. SCM-CityU

  43. Example • Decrease HP points when collision is detected • Start with skeleton program in W drive wall hp bird bird.hitTestObject(wall) Equivalent testing hill hill.hitTestObject(bird) SCM-CityU

  44. Class Exercise • Task: detect if there is collision between bird and hill bird hill SCM-CityU

  45. Weakness of hitTestObject Method • It is possible that • Display objects do not intersect with each other • But their bounding boxes do intersect SCM-CityU

  46. hitTestPoint Method (ref) • obj.hitTestPoint(x, y, shapeFlag) • Detect if point (x, y) intersects with obj • If shapeFlag == true, detection is done against object shape • If shapeFlag == false, detection is done against bounding box of the object • E.g., hill.hitTestPoint(mouseX, mouseY, true) (x,y) (x,y) shapeFlag == false shapeFlag == true SCM-CityU

  47. Collision Detection in AS • How to detect collision between objects with complex shapes? • Approximate solution • Sample the boundary of one object into a set of points {pi} • For every pi, check if it intersects with another shape • Using shapeA.hitTestPoint(pi.x, pi.y, true); p0 p1 p9 Shape A p2 p8 p3 p5 p7 p4 p6 SCM-CityU

  48. Class Exercise • Check if any bullet hits any plane • Hint: use nested for loop • For every bullet b • For every plane p • Do hit test on the pair of b and p SCM-CityU

  49. Avoid Getting Hit Twice • How to avoid any plane or bullet getting hit twice? • Simply removing bullets/planes from stage and array • Use Array’s splice method • Traverse array in bottom-up manner • If a bullet hits any plane, it is meaningless to compare it with the other plane elements in planes array • We need to immediatelly exit the inner loop if any hit is detected • Use break key word // for each bullet for(var bi:int= bullets.length-1; bi >=0; bi--){ // for each plane for(var ai:int= planes.length-1; ai >=0; ai--){ // splicing elements below } } SCM-CityU

  50. Early Exit of for Loop • Break statement causes inner-most loop to be terminated immediately for(var i:int=0; i <=10; i++){ if(i ==8){ break;// exit the loop }trace(i); } for(var i:int=0; i <=10; i++){ for(var j:int=0; j <=15; j++){ if(j ==8){ break;// exit inner loop only } trace(i, j); } } SCM-CityU

More Related