{"id":452,"date":"2010-08-07T10:19:25","date_gmt":"2010-08-07T15:19:25","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/?p=452"},"modified":"2014-03-16T12:46:05","modified_gmt":"2014-03-16T17:46:05","slug":"flex-asteriods-game-ship-animation","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2010\/08\/07\/flex-asteriods-game-ship-animation\/","title":{"rendered":"Flex Asteriods Game Ship Animation"},"content":{"rendered":"<p><strong>By Lon (Alonzo) Hosford<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"http:\/\/lh6.ggpht.com\/_e5pwU0LJbN8\/TG0-BcpjvlI\/AAAAAAAAFrM\/M7x-riqrfrc\/s144\/AsteriodsShipMovement_8-19-2010%2010-21-20%20AM.png\" class=\"alignleft\" width=\"144\" height=\"108\" \/>This example is based on Keith Peters ground breaking book on animation for ActionScript 3, <a href=\"http:\/\/www.amazon.com\/gp\/product\/1590597915?ie=UTF8&amp;tag=hosfordusa&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590597915\">Foundation Actionscript 3.0 Animation: Making Things Move.<\/a><\/p>\n<p>Keith lays out the basic fundamentals of motion. A great start point example to understand velocity, friction, acceleration and direction is the Asteroids game style ship moving through space. I also reproduced a similar example using HTML5 canvas you can view here: <a href=\"https:\/\/www.lonhosford.com\/lonblog\/2011\/10\/24\/html5-canvas-based-animation-asteriods-space-ship-movement\/\">HTML5 Canvas Based Animation Asteriods Space Ship Movement<\/a><\/p>\n<figure style=\"width: 134px\" class=\"wp-caption alignright\"><a href=\"http:\/\/www.amazon.com\/gp\/product\/1590597915?ie=UTF8&amp;tag=hosfordusa&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590597915\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\"  src=\"http:\/\/lh4.ggpht.com\/_e5pwU0LJbN8\/TF1xrKyqv4I\/AAAAAAAAFqI\/IFBuU9b7ijs\/s800\/51PvDwNRxYL._SL160_.jpg\" alt=\"Keith Peters AS3 Animation\" width=\"134\" height=\"160\" class=\"  \" title=\"Keith Peters AS3 Animation\"\/><\/a><figcaption class=\"wp-caption-text\">Learn More<\/figcaption><\/figure>\n<p>Many similar examples just assume you are going to use the keyboard to control the ship. This example decouples the ship acceleration and movement from keyboard. However we then double back and use the keyboard to control the ship. You will see in the MXML Application code, the keyboard events call methods on the ArrowShip class. However you could provide buttons for mouse clicks or even go crazy with a multi-touch application.<\/p>\n<p>The example is created in Flex Builder Running Eclipse but can be adapted to AIR or Flash.  <a href=\"https:\/\/www.lonhosford.com\/content\/flex\/AsteriodsShipMovement\/AsteriodsShipMovement.zip\">Download the example code<\/a>. You can also use Flash CS3 and CS4. You need create a Flash document in the src directory and set AsteriodsShipMovement as you document class. You also need to include the Flex 3 library, the Flex.swc file, into your Actionscript 3 settings. Tareq AlJaber article shows how that is done on page two of his article  <a href=\"http:\/\/www.adobe.com\/devnet\/flash\/articles\/embed_metadata_02.html\" target=\"_blank\">Embedding metadata with Flash<\/a>. For your convenience you can download a Flash CS4 file that is set up, but still you may need to check the Actionscript 3 settings if the movie will not play because you might have a non-standard installation.   <a href=\"https:\/\/www.lonhosford.com\/content\/flex\/AsteriodsShipMovement\/AsteriodsShipMovement_Flash_CS4.zip\">Download the Flash CS4 example<\/a>.<\/p>\n<p>You can use any graphic for the ship. More on how to do that is noted on the comments for ArrowShip class code.<\/p>\n<p>I added lots of comments in the code. The following is an overview of each code piece.<\/p>\n<p>The AsteroidsShipMovement class is the main class to start the example.  Line 17 is where you set the size and speed of your Flash movie.<\/p>\n<p>The background is a simple shape. You can embellish to your preference. See line 34.<\/p>\n<p>The ship needs a mask to define when it leaves view. That can be any size but generally is the same size as the stage or smaller. Thus your flying area can be smaller. The mask must be a rectangle. See line 38.<\/p>\n<p>AsteroidsShipMovement.as<\/p>\n<pre class=\"brush: as3; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npackage\r\n{\r\n.\r\n.\r\n.\r\n\timport com.alh.ui.ships.ArrowShip;\r\n\timport com.alh.ui.ships.Ship;\r\n\timport flash.display.MovieClip;\r\n\timport flash.display.Shape;\r\n\timport flash.display.Sprite;\r\n\timport flash.display.StageScaleMode;\r\n\timport flash.events.KeyboardEvent;\r\n\timport flash.geom.Rectangle;\r\n\timport flash.ui.Keyboard;\r\n\r\n\t\/\/ SET GAME SIZE AND SPEED HERE\r\n\t&#x5B;SWF(width=600, height = 600, frameRate = &quot;30&quot;)]\r\n\r\n\tpublic class AsteriodsShipMovement extends Sprite\r\n\t{\r\n\t\t\/\/ Basic game background - set your preference here\r\n\t\tpublic static const backgroundColor:Number = 0x0000ff;\r\n\t\tpublic static const backgroundBorderColor:Number = 0x666666;\r\n\t\tpublic static const backgroundBorderWidth:Number = 2;\r\n\r\n\t\t\/\/ Create the ship\r\n\t\tprivate var arrowShip:ArrowShip;\r\n\t\tpublic function AsteriodsShipMovement()\r\n\t\t{\r\n\t\t\t\/\/ Set stage options\r\n\t\t\tinitStage();\r\n\r\n\t\t\t\/\/ Create a background\r\n\t\t\tvar backgroundRect:Shape = getRectShape(backgroundColor, backgroundBorderColor, backgroundBorderWidth, stage.stageWidth, stage.stageHeight)\r\n\t\t\taddChild(backgroundRect);\r\n\r\n\t\t\t\/\/ Create the boundaries for the arrowShip, create the arrowShip.\r\n\t\t\tvar shipMaskRect:Shape = getRectShape(0x000000, 0x000000, backgroundBorderWidth, stage.stageWidth, stage.stageHeight)\r\n\t\t\tarrowShip = new ArrowShip(shipMaskRect);\r\n\t\t\taddChild(arrowShip);\r\n\t\t\tarrowShip.x = shipMaskRect.width \/ 2;\r\n\t\t\tarrowShip.y = shipMaskRect.height \/ 2;\r\n\r\n\t\t\t\/\/ Use keyboard events to control the ship\r\n\t\t\tstage.addEventListener( KeyboardEvent.KEY_DOWN, keyPressed);\r\n\t\t\tstage.addEventListener( KeyboardEvent.KEY_UP, keyReleased);\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Set any stage options per your needs\r\n\t\t * *\/\r\n\t\tprivate function initStage():void\r\n\t\t{\r\n\t\t\tstage.scaleMode = StageScaleMode.NO_SCALE;\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Handler for KeyboardEvent.KEY_DOWN\r\n\t\t * *\/\r\n\t\tprivate function keyPressed(evt:KeyboardEvent):void\r\n\t\t{\r\n\t\t\t\/\/ Either accelerate or turn the ship\r\n\t\t\tswitch (evt.keyCode)\r\n\t\t\t{\r\n\t\t\t\tcase Keyboard.UP:\r\n\t\t\t\t\tarrowShip.accelerate(Ship.START);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Keyboard.LEFT:\r\n\t\t\t\t\tarrowShip.turn(Ship.LEFT, Ship.START);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Keyboard.RIGHT:\r\n\t\t\t\t\tarrowShip.turn(Ship.RIGHT, Ship.START);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t\/**\r\n\t\t * Handler for KeyboardEvent.KEY_UP\r\n\t\t * *\/\r\n\r\n\t\tprivate function keyReleased(evt:KeyboardEvent):void\r\n\t\t{\r\n\t\t\t\/\/ Either stop accelerating or stop turning the ship\r\n\t\t\tswitch (evt.keyCode)\r\n\t\t\t{\r\n\t\t\t\tcase Keyboard.UP:\r\n\t\t\t\t\tarrowShip.accelerate(Ship.STOP);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Keyboard.LEFT:\r\n\t\t\t\t\tarrowShip.turn(Ship.LEFT, Ship.STOP);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase Keyboard.RIGHT:\r\n\t\t\t\t\tarrowShip.turn(Ship.RIGHT, Ship.STOP);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Utility to draw a rectangle Shape object\r\n\t\t * *\/\r\n\t\tprivate function getRectShape(bgColor:uint, borderColor:uint, borderSize:uint, width:uint, height:uint):Shape\r\n\t\t{\r\n\t\t\tvar newShape:Shape = new Shape();\r\n\t\t\tnewShape.graphics.beginFill(bgColor);\r\n\t\t\tnewShape.graphics.lineStyle(borderSize, borderColor);\r\n\t\t\tnewShape.graphics.drawRect(0, 0, width, height);\r\n\t\t\tnewShape.graphics.endFill();\r\n\t\t\treturn newShape;\r\n\t\t}\r\n\r\n\t}\r\n}\r\n<\/pre>\n<p>The ArrowShip class is a subclass of the Ship class. The Ship class does all the common functions for ship objects. The ArrowShip class is basically the skin. You subclass the Ship class and add your ship image on line 11.<\/p>\n<p>ArrowShip.as<\/p>\n<pre class=\"brush: as3; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\npackage com.alh.ui.ships\r\n{\r\n\timport flash.display.DisplayObject;\r\n\r\n\tpublic class ArrowShip extends Ship\r\n\t{\r\n\r\n\t\t&#x5B;Embed(source=&quot;\/assets\/ArrowShip.png&quot;)]\r\n\t\tprivate var ShipImg:Class;\r\n\t\tprivate var a:int;\r\n\t\t\/**\r\n\t\t * Constructor\r\n\t\t * param maskRect represents the container boundaries for the ship and its mask\r\n\t\t * *\/\r\n\t\tpublic function ArrowShip(maskRect:DisplayObject) : void\r\n\t\t{\r\n\t\t\tsuper(maskRect);\r\n\t\t\tsuper.addShipImage(new ShipImg(),270);\r\n\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>The Ship class implements the animation direction, velocity, friction, and acceleration principles set out in Keith Peters&#8217; book, <a href=\"http:\/\/www.amazon.com\/gp\/product\/1590597915?ie=UTF8&amp;tag=hosfordusa&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590597915\">Foundation Actionscript 3.0 Animation: Making Things Move!.<\/a><img loading=\"lazy\" decoding=\"async\" style=\"border: none !important; margin: 0px !important;\" src=\"http:\/\/www.assoc-amazon.com\/e\/ir?t=hosfordusa&amp;l=as2&amp;o=1&amp;a=1590597915\" border=\"0\" alt=\"\" width=\"1\" height=\"1\" \/><br \/>\nInstead of including Keyboard movement in the class as many animators do, the accelerate and turn methods were included. The UI or any code can call these methods to control the ship. On a more advanced level you could create an interface to further specify these methods in all types of objects that move forward and turn.<\/p>\n<p>Ship.as<\/p>\n<pre class=\"brush: as3; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\npackage com.alh.ui.ships\r\n{\r\n\r\n\timport flash.display.DisplayObject;\r\n\timport flash.display.MovieClip;\r\n\timport flash.display.Sprite;\r\n\timport flash.events.Event;\r\n\r\n\t\/**\r\n\t * Generic class for a space ship moving through space\r\n\t * This class is intended to be abstract\r\n\t * *\/\r\n\tpublic class Ship extends MovieClip\r\n\t{\r\n\r\n\t\tprivate var _shipDirectionOffset:Number = 0; \t\/\/ Offset front of ship in artwork in degrees.\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/ Artwork may have the ship facing in different\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/ directions and this makes the adjustment\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/ 0 = artwork ship faces right. 270 faces up.\r\n\t\tprivate var _speed:Number = 0.3;\t\t\t\t\/\/ Acceleration increment\r\n\t\tprivate var _rotateSpeed:Number = 3;\t\t\t\/\/ Turning speed in degrees\r\n\t\tprivate var _vx:Number = 0;\t\t\t\t\t\t\/\/ Velocity for x (direction and speed)\r\n\t\tprivate var _vy:Number = 0;\t\t\t\t\t\t\/\/ Velocity for y(direction and speed)\r\n\t\tprivate var _friction:Number = 0.95;\t\t\t\/\/ Percent reduction in _vx and _vy\r\n\t\tprivate var _accelerate:Boolean = false;\t\t\/\/ True if increasing _vx and _vy, false if not\r\n\t\tprivate var _turnLeft:Boolean = false;\t\t\t\/\/ Right turn direction request\r\n\t\tprivate var _turnRight:Boolean = false;\t\t\t\/\/ Object has right turn direction request\r\n\r\n\t\tpublic static const START:int = 0;\t\t\t\t\/\/ Start moving or turning\r\n\t\tpublic static const STOP:int = 1;\t\t\t\t\/\/ Stop moving or turning\r\n\t\tpublic static const LEFT:int = 0;\t\t\t\t\/\/ Turn left\r\n\t\tpublic static const RIGHT:int = 1;\t\t\t\t\/\/ Turn right\r\n\r\n\t\t\/**\r\n\t\t * Constructor\r\n\t\t * param maskRect represents the container boundaries for the ship and its mask\r\n\t\t * *\/\r\n\t\tpublic function Ship(maskRect:DisplayObject) : void\r\n\t\t{\r\n\t\t\tmask = maskRect;\r\n\t\t\t\/\/ Register handler for Event.ENTER_FRAME\r\n\t\t\taddEventListener(Event.ENTER_FRAME, enterFrameEventHandler, false, 0, true);\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Add the ship image and its directional offset\r\n\t\t * param imgClass is the artwork\r\n\t\t * param shipDirectionOffset see _shipDirectionOffset for notes\r\n\t\t * *\/\r\n\t\tinternal function addShipImage(imgClass:DisplayObject, shipDirectionOffset:Number):void\r\n\t\t{\r\n\t\t\t_shipDirectionOffset = shipDirectionOffset;\r\n\t\t\t\/\/ Add in ship image\r\n\t\t\tvar shipSprite:Sprite = new Sprite();\r\n\t\t\tshipSprite.addChild(imgClass);\r\n\r\n\t\t\t\/\/ Add ship sprite and center\r\n\t\t\taddChild(shipSprite);\r\n\t\t\tshipSprite.x = shipSprite.width \/ 2* -1;\r\n\t\t\tshipSprite.y = shipSprite.height \/ 2 * -1;\r\n\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Accelerates ship or stops acceleration\r\n\t\t * param startStopState valid values START and STOP\r\n\t\t * *\/\r\n\t\tpublic function accelerate(startStopState:int):void\r\n\t\t{\r\n\t\t\t\/\/ Set the accelerating state\r\n\t\t\t_accelerate = startStopState == START;\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Turn ship\r\n\t\t * param turnDirection valid values LEFT and RIGHT\r\n\t\t * param startStopState valid values START and STOP\r\n\t\t * *\/\r\n\t\tpublic function turn(turnDirection:int, startStopState:int):void\r\n\t\t{\r\n\t\t\t\/\/ Set the left turn state\r\n\t\t\tif (turnDirection == LEFT)\r\n\t\t\t{\r\n\t\t\t\t_turnLeft = startStopState == START;\r\n\t\t\t}\r\n\t\t\t\/\/ Set the right turn state\r\n\t\t\tif (turnDirection == RIGHT)\r\n\t\t\t{\r\n\t\t\t\t_turnRight = startStopState == START;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Event.ENTER_FRAME event handler\r\n\t\t * *\/\r\n\t\tprotected function enterFrameEventHandler(e:Event) : void\r\n\t\t{\r\n\t\t\t\/\/ Acceleration is on\r\n\t\t\tif (_accelerate )\r\n\t\t\t{\r\n\t\t\t\t\/\/ Conversion of rotation degrees (rotation + _shipDirectionOffset) and speed to velocity\r\n\t\t\t\t_vy += Math.sin(degreesToRadians(rotation + _shipDirectionOffset)) * _speed;\r\n\t\t\t\t_vx += Math.cos(degreesToRadians(rotation + _shipDirectionOffset)) * _speed;\r\n\t\t\t}\r\n\t\t\t\/\/ Acceleration is off\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\t\/\/ reduce velocity by friction\r\n\t\t\t\t_vy *= _friction;\r\n\t\t\t\t_vx *= _friction;\r\n\t\t\t}\r\n\r\n\t\t\t\/\/ Change direction right\r\n\t\t\tif (_turnRight)\r\n\t\t\t{\r\n\t\t\t\trotation += _rotateSpeed;\r\n\t\t\t}\r\n\t\t\t\/\/ Change direction left\r\n\t\t\telse if (_turnLeft)\r\n\t\t\t{\r\n\t\t\t\trotation += -_rotateSpeed;\r\n\t\t\t}\r\n\r\n\t\t\t\/\/ Move position by velocity\r\n\t\t\ty += _vy;\r\n\t\t\tx += _vx;\r\n\r\n\t\t\t\/\/ Exiting right side of mask\r\n\t\t\tif (x - width \/ 2 &gt; mask.width)\r\n\t\t\t{\r\n\t\t\t\tx = 0;\r\n\t\t\t}\r\n\t\t\t\/\/ Exiting left side of mask\r\n\t\t\telse if (x + width \/ 2 &lt; 0)\r\n\t\t\t{\r\n\t\t\t\tx = mask.width;\r\n\t\t\t}\r\n\r\n\t\t\t\/\/ Exiting top of mask\r\n\t\t\tif (y - height \/ 2 &gt; mask.height)\r\n\t\t\t{\r\n\t\t\t\ty = 0;\r\n\t\t\t}\r\n\t\t\t\/\/ Exiting bottom of mask\r\n\t\t\telse if (y + height \/ 2 &lt; 0)\r\n\t\t\t{\r\n\t\t\t\ty = mask.height;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Change the default friction value\r\n\t\t * *\/\r\n\t\tprotected function set friction(friction:Number):void\r\n\t\t{\r\n\t\t\t_friction = friction;\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Change the default speed value\r\n\t\t * *\/\r\n\t\tprotected function set speed(speed:Number):void\r\n\t\t{\r\n\t\t\t_speed = speed;\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Change the default rotateSpeed value\r\n\t\t * *\/\r\n\t\tprotected function set rotateSpeed(rotateSpeed:Number):void\r\n\t\t{\r\n\t\t\t_rotateSpeed = rotateSpeed;\r\n\t\t}\r\n\t\t\/**\r\n\t\t * Utility to convert Actionscript degrees (0-360) to Trig radians (57.2958 degrees).\r\n\t\t * *\/\r\n\t\tprivate function degreesToRadians(degrees:Number) : Number\r\n\t\t{\r\n\t\t\treturn degrees * Math.PI \/ 180;\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n\r\n<\/pre>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#appId=105467682877384&amp;xfbml=1\"><\/script><fb:like href=\"https:\/\/www.lonhosford.com\/lonblog\/2010\/08\/07\/flex-asteriods-game-ship-animation\/\" send=\"true\" width=\"450\" show_faces=\"true\" font=\"\"><\/fb:like><\/p>\n<div id=\"fb-root\"><\/div>\n<p><script src=\"https:\/\/connect.facebook.net\/en_US\/all.js#xfbml=1\"><\/script><fb:comments href=\"https:\/\/www.lonhosford.com\/lonblog\/2010\/08\/07\/flex-asteriods-game-ship-animation\/\" num_posts=\"3\" width=\"500\"><\/fb:comments><\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Lon (Alonzo) Hosford This example is based on Keith Peters ground breaking book on animation for ActionScript 3, Foundation Actionscript 3.0 Animation: Making Things Move. Keith lays out the basic fundamentals of motion. A great start point example to understand velocity, friction, acceleration and direction is the Asteroids game style ship moving through space. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[19,30,3,9,31,49],"class_list":["post-452","post","type-post","status-publish","format-standard","hentry","category-general","tag-actionscript","tag-animation","tag-adobe-flash","tag-flex","tag-gaming","tag-keith-peters"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/comments?post=452"}],"version-history":[{"count":56,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/452\/revisions"}],"predecessor-version":[{"id":3303,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/452\/revisions\/3303"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}