{"id":2519,"date":"2011-10-24T14:38:03","date_gmt":"2011-10-24T19:38:03","guid":{"rendered":"http:\/\/www.lonhosford.com\/lonblog\/?p=2519"},"modified":"2015-07-31T18:25:49","modified_gmt":"2015-07-31T23:25:49","slug":"html5-canvas-based-animation-asteriods-space-ship-movement","status":"publish","type":"post","link":"https:\/\/www.lonhosford.com\/lonblog\/2011\/10\/24\/html5-canvas-based-animation-asteriods-space-ship-movement\/","title":{"rendered":"HTML5 Canvas Based Animation Asteriods Space Ship Movement"},"content":{"rendered":"<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\/2011\/10\/24\/html5-canvas-based-animation-asteriods-space-ship-movement\/\" send=\"true\" width=\"450\" show_faces=\"true\" font=\"\"><\/fb:like><\/p>\n<p>This is an example of an asteroids game space ship using the HTML5 canvas and JQuery. <img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"https:\/\/lh6.googleusercontent.com\/-HQ-d4flzJ88\/TqWjIdLbINI\/AAAAAAAAGLM\/YhpTaVeiR8A\/s800\/spaceship_html_canvas_published.jpg\" class=\"alignleft\" width=\"288\" height=\"288\" \/> <\/p>\n<p><strong><a  href=\"\/content\/html5\/canvas\/spaceship_movement\/spaceship_movement01\/spaceship_movement.html\" target = \"_blank\">Demo<\/a><\/strong><\/p>\n<p><strong><a onclick=\"javascript: pageTracker._trackPageview('\/downloads\/html5\/canvas\/spaceship_movement\/spaceship_movement01\/spaceship_movement.html.zip'); \" href=\"https:\/\/www.lonhosford.com\/content\/html5\/canvas\/spaceship_movement\/spaceship_movement01\/spaceship_movement.html.zip\">Download Source<\/a><\/strong><\/p>\n<p>The goal here was to reproduce the same example i posted for Actionscript 3 here: <a href= \"https:\/\/www.lonhosford.com\/lonblog\/2010\/08\/07\/flex-asteriods-game-ship-animation\/\">Actionscript 3 Animation Following the Mouse to Show Velocity at an Angle<\/a><figure style=\"width: 100px\" class=\"wp-caption alignright\"><a href=\"http:\/\/www.amazon.com\/gp\/product\/1430236655\/ref=as_li_ss_il?ie=UTF8&#038;tag=hosfordusa&#038;linkCode=as2&#038;camp=217145&#038;creative=399373&#038;creativeASIN=1430236655\"><img decoding=\"async\" border=\"0\" src=\"http:\/\/ws.assoc-amazon.com\/widgets\/q?_encoding=UTF8&#038;Format=_SL110_&#038;ASIN=1430236655&#038;MarketPlace=US&#038;ID=AsinImage&#038;WS=1&#038;tag=hosfordusa&#038;ServiceVersion=20070822\" ><\/a><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.assoc-amazon.com\/e\/ir?t=hosfordusa&#038;l=as2&#038;o=1&#038;a=1430236655&#038;camp=217145&#038;creative=399373\" width=\"1\" height=\"1\" border=\"0\" alt=\"\" style=\"border:none !important; margin:0px !important;\" \/><a href=\"http:\/\/www.amazon.com\/gp\/product\/1430236655\/ref=as_li_ss_tl?ie=UTF8&#038;tag=hosfordusa&#038;linkCode=as2&#038;camp=217145&#038;creative=399373&#038;creativeASIN=1430236655\">Foundation HTML5 Animation with JavaScript<\/a><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.assoc-amazon.com\/e\/ir?t=hosfordusa&#038;l=as2&#038;o=1&#038;a=1430236655&#038;camp=217145&#038;creative=399373\" width=\"1\" height=\"1\" border=\"0\" alt=\"\" style=\"border:none !important; margin:0px !important;\" \/><figcaption class=\"wp-caption-text\">Learn More<\/figcaption><\/figure><\/p>\n<p>That example as well as this is not a full asteroids game. I am posting it for the basic principles of velocity, acceleration and force. In this case the velocity, direction with speed, is computed for x, y and rotation. <\/p>\n<p>JQuery is used for keystroke capture. Our space ship has a thruster for forward motion and ability to turn left or right. The up key is used for thrusting forward and the left and right keys for the turning as you should expect. The ship enters the opposite side of the canvas if it leaves the canvas.<\/p>\n<p>The ship is a basic triangle and also has a flame when thrusting.<\/p>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\nYou can view the full html file at the end of the post. To explain what is going on inside excerpts of the code are broken out.<\/p>\n<p><strong>The Canvas and Basic Animation Framework<\/strong><\/p>\n<p>This snippet defines basic constants and variables to simplify code later.<\/p>\n<pre class=\"brush: jscript; first-line: 12; title: ; notranslate\" title=\"\">\r\n\tvar CANVAS_WIDTH = 480;\t\t\/\/ Canvas width\r\n\tvar CANVAS_HEIGHT = 480;\t\/\/ Canvas height\r\n\tvar FPS = 30;\t\t\t\t\/\/ Frames per second\r\n\t\/\/ Canvas center points.\r\n\tvar canvasCenterX = CANVAS_WIDTH \/ 2;\r\n\tvar canvasCenterY = CANVAS_HEIGHT \/ 2;\r\n<\/pre>\n<p>The canvas element is created dynamically in JavaScript and appended to the body element.  I like to name the canvas drawing context canvas as you can see on line 29.<\/p>\n<pre class=\"brush: jscript; first-line: 25; title: ; notranslate\" title=\"\">\r\n\t\/\/ Create html syntax for canvas element.\r\n\tvar canvasElement = $(&quot;&lt;canvas width='&quot; + CANVAS_WIDTH + \r\n\t  &quot;' height='&quot; + CANVAS_HEIGHT + &quot;'&gt;&lt;\/canvas&quot;);\r\n\t\/\/ Reference to the canvas 2d context.\r\n\tvar canvas = canvasElement.get(0).getContext(&quot;2d&quot;);\r\n\t\/\/ Dynamically append a canvas element to the body tag.\r\n\tcanvasElement.appendTo('body');\t\r\n<\/pre>\n<p>These next few snippets represent the animation framework. I have used this in other HTML5 canvas examples. <\/p>\n<p>Three framework functions are init, update and draw. The init function is the initialization of the animation framework and any components. The only components are the canvas and the ship.<\/p>\n<p>For the init method you see some keys being identified for the document to process via JQuery. You could call JQuery that part of the framework.<\/p>\n<p>The init method also initializes the ship object. Without the bounds set, the ship will leave the canvas and may never be seen again.<\/p>\n<pre class=\"brush: jscript; first-line: 143; title: ; notranslate\" title=\"\">\r\n\t\/\/ Initialize game\r\n\tfunction init()\r\n\t{\r\n\t\t\/\/ Set keys for play\r\n\t\t$(document).bind('keyup', KEY_NAME_THRUSTER, keyEvent); \r\n\t\t$(document).bind('keydown', KEY_NAME_THRUSTER, keyEvent); \r\n\t\t\/\/ Initialize the ship start position and boundaries.\r\n\t\tship.x = canvasCenterX;\r\n\t\tship.y = canvasCenterY;\r\n\t\tship.bounds.left = 0;\r\n\t\tship.bounds.right = CANVAS_WIDTH;\r\n\t\tship.bounds.top = 0;\r\n\t\tship.bounds.bottom = CANVAS_HEIGHT;\r\n\t}\r\n<\/pre>\n<p>Here is the key processing function. I am taking the JQuery key names and converting them to name I set in constants for more readable code. <\/p>\n<p>The keyEvent function also would call animation object keyEvent methods and here we call the ship object;s keyEvent method.<\/p>\n<pre class=\"brush: jscript; first-line: 157; title: ; notranslate\" title=\"\">\r\n\t\/\/ Evaluate key input\r\n\tfunction keyEvent(evt)\r\n\t{\r\n\t\t\/\/ Animation name for the key pressed assumed to be the char name.\r\n\t\tvar keyName = String.fromCharCode(evt.keyCode).toLowerCase();\r\n\t\t\/\/ Left arrow key\r\n\t\tif (evt.keyCode == 37)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_LEFT;\r\n\t\t}\r\n\t\t\/\/ Right arrow key\r\n\t\tif (evt.keyCode == 39)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_RIGHT;\r\n\t\t}\r\n\t\t\/\/ Up arrow key\r\n\t\tif (evt.keyCode == 38)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_THRUSTER;\t\r\n\t\t}\r\n\t\t\/\/ Call animation object keyEvent methods.\r\n\t\tship.keyEvent(evt.type,keyName);\r\n\t}\r\n<\/pre>\n<p>The animation framework update method is called for updating model data. The draw method refreshes the view. <\/p>\n<p>These two methods are called for each frame in the animation.<\/p>\n<pre class=\"brush: jscript; first-line: 180; title: ; notranslate\" title=\"\">\r\n\t\/\/ Update the model data.\r\n\tfunction update() \r\n\t{\r\n\t\tship.update();\r\n\t}\r\n\t\/\/ Draw the view.\r\n\tfunction draw() \r\n\t{\r\n\t\tcanvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);\r\n\t\tcanvas.strokeStyle = &quot;blue&quot;;\r\n\t\tcanvas.strokeRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);\r\n\t\tcanvas.fillStyle = &quot;black&quot;;\r\n\t\tcanvas.fillRect(.5, .5, CANVAS_WIDTH-1, CANVAS_HEIGHT-1);\r\n\t\tship.draw();\r\n\t}\r\n<\/pre>\n<p>This is the heart of the animation. Once JQuery loads the animation framework is initialized and then the timer starts to fire for each frame in the animation.<\/p>\n<pre class=\"brush: jscript; first-line: 195; title: ; notranslate\" title=\"\">\r\n\t\/\/ JQuery ready - start here\r\n\t$(function() \r\n\t{\r\n\t\t\/\/ Initialization.\r\n\t\tinit();\r\n\t\t\/\/ Timer for animation.\r\n\t\tsetInterval(function() \r\n\t\t{\r\n\t\t\tupdate();\r\n\t\t\tdraw();\r\n\t\t}, 1000\/FPS);\r\n\t});\r\n<\/pre>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\n<strong>The Ship Object<\/strong><br \/>\nThe ship object has all the needed data and logic to run in the animation framework.<\/p>\n<p>This first snippet of code show the public and private properties. The underscore is indicate a private property. They should be easy to follow with the comment included or their name.<\/p>\n<pre class=\"brush: jscript; first-line: 32; title: ; notranslate\" title=\"\">\r\n\tvar ship = \r\n\t{\r\n\t\tshipStrokeColor: &quot;#8ED6FF&quot;,\r\n\t\tshipFillColor: &quot;#0000ff&quot;,\r\n\t\tflameStrokeColor: &quot;#ff0000&quot;,\r\n\t\tflameFillColor: &quot;#ff0000&quot;,\r\n\t\tx: 0,  \t\t\t\/\/ Canvas x.\r\n\t\ty: 0,\t\t\t\/\/ Canvas y.\r\n\t\tleftThrust: -5, \/\/ Number of degrees for each left turn request.\r\n\t\trightThrust: 5, \/\/ Number of degrees for each right turn request.\r\n\t\tbounds: {top:-1,bottom:-1,left:-1,right:-1}, \/\/ Boundaries. -1 = no boundary.\r\n\t\t_drawStartX: 10,\/\/ Drawing starting x.\r\n\t\t_drawStartY: 0,\t\/\/ Drawing starting y.\r\n\t\t_radians:0,\t\t\/\/ Rotation value required for the canvas rotate method.\r\n\t\t_vx:0,\t\t\t\/\/ Velocity for x.\r\n\t\t_vy:0,\t\t\t\/\/ Velocity for y.\r\n\t\t_vr:0,\t\t\t\/\/ Velocity for rotation.\r\n\t\tthrust:.2,\t\t\/\/ Incremental force added to acceleration.\r\n\t\t_thrust:0,\t\t\/\/ Force added to acceleration.\r\n\t\trotation:0,\t\t\/\/ Degrees of rotation.\r\n\t\t_radians:0,\t\t\/\/ Degrees of rotation converted to radians for canvas.rotate method.\r\n<\/pre>\n<p>This is the ship object&#8217;s update method required by the animation framework. Here we get into trigonometry and physics. Its fairly easy to follow when you think we need to compute a velocity for the x and y properties and a rotation for direction. Velocity is direction with speed. Then there is force applied to the x and y velocity when the ship&#8217;s thruster is used. <\/p>\n<p>First the direction of the ship is computed on line 57. However we added a velocity for rotation. This is the _vr property and basically represents how much we turn with the left and right keys. The leftThrust and rightThrust properties provide an external interface to _vr. We do not have acceleration with rotation, so you can assume the ship automatically compensates for turning to avoid spinning like a top.<\/p>\n<p>Our x and y velocities are represented by _vx and _vy. They are adjusted by force represented by the thrust property. Lines 61 and 62 compute the acceleration based on thrust for both x and y. Then we apply the acceleration to the x and y velocities on lines 64 and 65. <\/p>\n<p>The last step is to set the drawing x and y properties for the ship. Lines 67 &#8211; 70 are for the x position and you can see there is a boundary check. This is repeated for the y property on lines 72 &#8211; 75.<\/p>\n<pre class=\"brush: jscript; first-line: 54; title: ; notranslate\" title=\"\">\r\n\t\tupdate: function() \/\/ Update model data\r\n\t\t{\r\n\t\t\t\/\/ Increase rotation by rotation velocity\r\n\t\t\tthis.rotation += this._vr;\r\n\t\t\t\/\/ Calculate rotation in radians\r\n\t\t\tthis._radians = this.rotation * Math.PI \/ 180;\r\n\t\t\t\/\/ Acceleration for x and y velocity increases\r\n\t\t\tvar ax = Math.cos(this._radians) * this._thrust;\r\n\t\t\tvar ay = Math.sin(this._radians) * this._thrust;\r\n\t\t\t\/\/ Velocity for x and y\r\n\t\t\tthis._vx += ax;\r\n\t\t\tthis._vy += ay;\r\n\t\t\t\/\/ New x position.\r\n\t\t\tthis.x += this._vx;\r\n\t\t\t\/\/ Check for x boundaries\r\n\t\t\tif (this.x &gt; this.bounds.right &amp;&amp; this.bounds.right &gt;= 0) this.x = this.bounds.left;\r\n\t\t\tif (this.x &lt; this.bounds.left &amp;&amp; this.bounds.left &gt;= 0) this.x = this.bounds.right;\r\n\t\t\t\/\/ New y position.\r\n\t\t\tthis.y += this._vy;\r\n\t\t\t\/\/ Check for y boundaries\r\n\t\t\tif (this.y &gt; this.bounds.bottom &amp;&amp; this.bounds.bottom &gt;= 0) this.y = this.bounds.top;\r\n\t\t\tif (this.y &lt; this.bounds.top &amp;&amp; this.bounds.top &gt;= 0) this.y = this.bounds.bottom;\r\n\t\t},\r\n<\/pre>\n<p>The draw method is the next animation framework requirement. Here we get into the HTML5 canvas method and techniques to draw the ship with and without a thruster flame.<\/p>\n<p>The procedure is simplified by drawing the ship without regard to its position on the canvas and then translating that to the canvas position. The canvas save and restore methods on lines 80 and 112 respectively give us that ability. <\/p>\n<p>In between the work is done by first specifying the translation point on line 82. Then canvas rotation is done. Then we draw the ship. Line 86 determines if we need to draw a flame for thrusters firing. Finally the ship, a basic triangle, is draw.<\/p>\n<p>Note the beginPath methods on lines 88 and 98. These keep the drawing fresh and distinct. Without them you would see the colors and lines overlap and each time the ship is rotated, you would see the previous ship. <\/p>\n<pre class=\"brush: jscript; first-line: 77; title: ; notranslate\" title=\"\">\r\n\t\tdraw: function() \/\/ Draw.\r\n\t\t{\r\n\t\t\t\/\/ Draw off canvas\r\n\t\t\tcanvas.save();\r\n\t\t\t\/\/Translate canvas next draw position\r\n\t\t\tcanvas.translate(this.x,this.y);\r\n\t\t\t\/\/ Rotate\r\n\t\t\tcanvas.rotate(this._radians);\r\n\t\t\t\/\/ Thrusters on draw flame\r\n\t\t\tif (this._thrust &gt; 0)\r\n\t\t\t{\r\n\t\t\t\tcanvas.beginPath();\r\n\t\t\t\tcanvas.moveTo(this._drawStartX - 12.5, this._drawStartY - 5);\t\r\n\t\t\t\tcanvas.lineTo(this._drawStartX - 25 , this._drawStartY);\t\r\n\t\t\t\tcanvas.lineTo(this._drawStartX - 12.5 , this._drawStartY + 5);\t\r\n\t\t\t\tcanvas.fillStyle = this.flameStrokeColor;\r\n\t\t\t\tcanvas.fill();\r\n\t\t\t\tcanvas.strokeStyle = this.flameFillColor;\t\t\r\n\t\t\t\tcanvas.stroke();\r\n\t\t\t}\r\n\t\t\t\/\/ Begin drawing the ship\r\n\t\t\tcanvas.beginPath();\r\n\t\t\t\/\/ Start.\r\n\t\t\tcanvas.moveTo(this._drawStartX, this._drawStartY);\t\r\n\t\t\t\/\/ \tShip body\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -20 , this._drawStartY + 10);\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -15 , this._drawStartY);\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -20 , this._drawStartY - 10);\t\r\n\t\t\t\/\/ Close.\t\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX, this._drawStartY);\t\r\n\t\t\tcanvas.fillStyle = this.shipStrokeColor;\r\n\t\t\tcanvas.fill();\r\n\t\t\tcanvas.strokeStyle = this.shipFillColor;\t\t\r\n\t\t\tcanvas.stroke();\r\n\t\t\t\/\/ Put it on the canvas\r\n\t\t\tcanvas.restore();\r\n\t  \t},\r\n<\/pre>\n<p>The last integrating for the ship object into the animation framework is handling the keystrokes.<\/p>\n<p>First take a look back at line 18 and you see we set up constants for the key names and key types. These are translated from the keys pressed in the main framework keyEvent function on line 159 shown earlier.<\/p>\n<pre class=\"brush: jscript; first-line: 18; title: ; notranslate\" title=\"\">\r\n\t\/\/ Keyname constants\r\n\tvar KEY_NAME_THRUSTER = &quot;up&quot;;\r\n\tvar KEY_NAME_LEFT = &quot;left&quot;;\r\n\tvar KEY_NAME_RIGHT = &quot;right&quot;;\r\n\t\/\/ Constants to match JQuery Hotkeys event value type.\r\n\tvar KEY_TYPE_UP = &quot;keyup&quot;;\r\n\tvar KEY_TYPE_DOWN = &quot;keydown&quot;;\r\n\r\n<\/pre>\n<p>Then the ship keyEvent method needs to evaluate the key name and key type to update data. For example when the left or right key is released, the rotation velocity is set to zero on lines 136 to 140 to zero. This is our automatic adjustment for acceleration when turning. Consider it an advanced feature.<\/p>\n<p>For turning left or right, the rotation velocity is set to the leftThrust and rightThrust properties in lines 126 to 135. This only happens when the key type is down.<\/p>\n<p>For forward motion is covered on lines 121 to 125. Simply the internal thrust property is set with the public interface thrust property. Here we are applying force.<\/p>\n<p>To stop applying forward force, lines 117 to 121 set the internal thrust back to zero. <\/p>\n<p>You can see the<\/p>\n<pre class=\"brush: jscript; first-line: 114; title: ; notranslate\" title=\"\">\r\n\t\tkeyEvent: function(keyType, keyName)\r\n\t\t{\r\n\t\t\t\/\/ Thruster is off\r\n\t\t\tif (keyName == KEY_NAME_THRUSTER &amp;&amp; keyType == KEY_TYPE_UP)\r\n\t\t\t{\r\n\t\t\t\tthis._thrust = 0;\r\n\t\t\t\tthis._vr = 0;\t\r\n\t\t\t}\r\n\t\t\t\/\/ Thruster off\r\n\t\t\telse if(keyName == KEY_NAME_THRUSTER &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._thrust = this.thrust;\r\n\t\t\t}\r\n\t\t\t\/\/ Turning left\r\n\t\t\tif (keyName == KEY_NAME_LEFT &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = this.leftThrust;\r\n\t\t\t}\r\n\t\t\t\/\/ Turning right\r\n\t\t\tif (keyName == KEY_NAME_RIGHT &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = this.rightThrust;\r\n\t\t\t}\r\n\t\t\t\/\/ Stop turning\r\n\t\t\tif ((keyName == KEY_NAME_RIGHT || keyName == KEY_NAME_LEFT ) &amp;&amp; keyType == KEY_TYPE_UP)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = 0;\r\n\t\t\t}\r\n\t\t}\r\n\r\n<\/pre>\n<p>[ad name=&#8221;Google Adsense&#8221;]<br \/>\nThe entire HTML document for your convenience to view and copy.<\/p>\n<pre class=\"brush: xml; collapse: true; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;meta charset=&quot;UTF-8&quot;&gt;\r\n&lt;script language=&quot;javascript&quot; src=&quot;https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.6.4\/jquery.min.js&quot; type=&quot;text\/javascript&quot;&gt;&lt;\/script&gt;\r\n&lt;title&gt;HTML5 Canvas Based Animation Asteriods Space Ship Movement&lt;\/title&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n&lt;div&gt;&lt;a href=&quot;https:\/\/www.lonhosford.com\/lonblog\/2011\/10\/22\/html5-canvas-bobbing-circle-animation-demonstrating-sine-wave-movement\/&quot;&gt;Article Posted By Lon Hosford - HTML5 Canvas Based Animation Asteriods Space Ship Movement&lt;\/a&gt;\r\n&lt;p&gt;Use up key to move. Left and right keys to turn.&lt;\/div&gt;\r\n&lt;script type='text\/javascript'&gt;\r\n\tvar CANVAS_WIDTH = 480;\t\t\/\/ Canvas width\r\n\tvar CANVAS_HEIGHT = 480;\t\/\/ Canvas height\r\n\tvar FPS = 30;\t\t\t\t\/\/ Frames per second\r\n\t\/\/ Canvas center points.\r\n\tvar canvasCenterX = CANVAS_WIDTH \/ 2;\r\n\tvar canvasCenterY = CANVAS_HEIGHT \/ 2;\r\n\t\/\/ Keyname constants\r\n\tvar KEY_NAME_THRUSTER = &quot;up&quot;;\r\n\tvar KEY_NAME_LEFT = &quot;left&quot;;\r\n\tvar KEY_NAME_RIGHT = &quot;right&quot;;\r\n\t\/\/ Constants to match JQuery Hotkeys event value type.\r\n\tvar KEY_TYPE_UP = &quot;keyup&quot;;\r\n\tvar KEY_TYPE_DOWN = &quot;keydown&quot;;\r\n\t\/\/ Create html syntax for canvas element.\r\n\tvar canvasElement = $(&quot;&lt;canvas width='&quot; + CANVAS_WIDTH + \r\n\t  &quot;' height='&quot; + CANVAS_HEIGHT + &quot;'&gt;&lt;\/canvas&quot;);\r\n\t\/\/ Reference to the canvas 2d context.\r\n\tvar canvas = canvasElement.get(0).getContext(&quot;2d&quot;);\r\n\t\/\/ Dynamically append a canvas element to the body tag.\r\n\tcanvasElement.appendTo('body');\t\r\n\t\/\/ The ship\r\n\tvar ship = \r\n\t{\r\n\t\tshipStrokeColor: &quot;#8ED6FF&quot;,\r\n\t\tshipFillColor: &quot;#0000ff&quot;,\r\n\t\tflameStrokeColor: &quot;#ff0000&quot;,\r\n\t\tflameFillColor: &quot;#ff0000&quot;,\r\n\t\tx: 0,  \t\t\t\/\/ Canvas x.\r\n\t\ty: 0,\t\t\t\/\/ Canvas y.\r\n\t\tbounds: {top:-1,bottom:-1,left:-1,right:-1}, \/\/ Boundaries. -1 = no boundary.\r\n\t\t_drawStartX: 10,\/\/ Drawing starting x.\r\n\t\t_drawStartY: 0,\t\/\/ Drawing starting y.\r\n\t\t_radians:0,\t\t\/\/ Rotation value required for the canvas rotate method.\r\n\t\t_vx:0,\t\t\t\/\/ Velocity for x.\r\n\t\t_vy:0,\t\t\t\/\/ Velocity for y.\r\n\t\t_vr:0,\t\t\t\/\/ Velocity for rotation.\r\n\t\tthrust:.2,\t\t\/\/ Incremental force added to acceleration.\r\n\t\t_thrust:0,\t\t\/\/ Force added to acceleration.\r\n\t\trotation:0,\t\t\/\/ Degrees of rotation.\r\n\t\t_radians:0,\t\t\/\/ Degrees of rotation converted to radians for canvas.rotate method.\r\n\t\tupdate: function() \/\/ Update model data\r\n\t\t{\r\n\t\t\t\/\/ Increase rotation by rotation velocity\r\n\t\t\tthis.rotation += this._vr;\r\n\t\t\t\/\/ Calculate rotation in radians\r\n\t\t\tthis._radians = this.rotation * Math.PI \/ 180;\r\n\t\t\t\/\/ Acceleration for x and y velocity increases\r\n\t\t\tvar ax = Math.cos(this._radians) * this._thrust;\r\n\t\t\tvar ay = Math.sin(this._radians) * this._thrust;\r\n\t\t\t\/\/ Velocity for x and y\r\n\t\t\tthis._vx += ax;\r\n\t\t\tthis._vy += ay;\r\n\t\t\t\/\/ New x position.\r\n\t\t\tthis.x += this._vx;\r\n\t\t\t\/\/ Check for x boundaries\r\n\t\t\tif (this.x &gt; this.bounds.right &amp;&amp; this.bounds.right &gt;= 0) this.x = this.bounds.left;\r\n\t\t\tif (this.x &lt; this.bounds.left &amp;&amp; this.bounds.left &gt;= 0) this.x = this.bounds.right;\r\n\t\t\t\/\/ New y position.\r\n\t\t\tthis.y += this._vy;\r\n\t\t\t\/\/ Check for y boundaries\r\n\t\t\tif (this.y &gt; this.bounds.bottom &amp;&amp; this.bounds.bottom &gt;= 0) this.y = this.bounds.top;\r\n\t\t\tif (this.y &lt; this.bounds.top &amp;&amp; this.bounds.top &gt;= 0) this.y = this.bounds.bottom;\r\n\t\t},\r\n\t\tdraw: function() \/\/ Draw.\r\n\t\t{\r\n\t\t\t\/\/ Draw off canvas\r\n\t\t\tcanvas.save();\r\n\t\t\t\/\/Translate canvas next draw position\r\n\t\t\tcanvas.translate(this.x,this.y);\r\n\t\t\t\/\/ Rotate\r\n\t\t\tcanvas.rotate(this._radians);\r\n\t\t\t\/\/ Thrusters on draw flame\r\n\t\t\t\/\/if (this._thrust &gt; 0)\r\n\t\t\t\/\/{\r\n\t\t\t\tcanvas.beginPath();\r\n\t\t\t\tcanvas.moveTo(this._drawStartX - 12.5, this._drawStartY - 5);\t\r\n\t\t\t\tcanvas.lineTo(this._drawStartX - 25 , this._drawStartY);\t\r\n\t\t\t\tcanvas.lineTo(this._drawStartX - 12.5 , this._drawStartY + 5);\t\r\n\t\t\t\tcanvas.fillStyle = this.flameStrokeColor;\r\n\t\t\t\tcanvas.fill();\r\n\t\t\t\tcanvas.strokeStyle = this.flameFillColor;\t\t\r\n\t\t\t\tcanvas.stroke();\r\n\t\t\t\/\/}\r\n\t\t\t\/\/ Begin drawing the ship\r\n\t\t\tcanvas.beginPath();\r\n\t\t\t\/\/ Start.\r\n\t\t\tcanvas.moveTo(this._drawStartX, this._drawStartY);\t\r\n\t\t\t\/\/ \tShip body\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -20 , this._drawStartY + 10);\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -15 , this._drawStartY);\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX -20 , this._drawStartY - 10);\t\r\n\t\t\t\/\/ Close.\t\t\t\r\n\t\t\tcanvas.lineTo(this._drawStartX, this._drawStartY);\t\r\n\t\t\tcanvas.fillStyle = this.shipStrokeColor;\r\n\t\t\tcanvas.fill();\r\n\t\t\tcanvas.strokeStyle = this.shipFillColor;\t\t\r\n\t\t\tcanvas.stroke();\r\n\t\t\t\/\/ Put it on the canvas\r\n\t\t\tcanvas.restore();\r\n\t  \t},\r\n\t\tkeyEvent: function(keyType, keyName)\r\n\t\t{\r\n\t\t\t\/\/ Thruster is off\r\n\t\t\tif (keyName == KEY_NAME_THRUSTER &amp;&amp; keyType == KEY_TYPE_UP)\r\n\t\t\t{\r\n\t\t\t\tthis._thrust = 0;\r\n\t\t\t\tthis._vr = 0;\t\r\n\t\t\t}\r\n\t\t\t\/\/ Thruster off\r\n\t\t\telse if(keyName == KEY_NAME_THRUSTER &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._thrust = this.thrust;\r\n\t\t\t}\r\n\t\t\t\/\/ Turning left\r\n\t\t\tif (keyName == KEY_NAME_LEFT &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = -5;\r\n\t\t\t}\r\n\t\t\t\/\/ Turning right\r\n\t\t\tif (keyName == KEY_NAME_RIGHT &amp;&amp; keyType == KEY_TYPE_DOWN)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = 5;\r\n\t\t\t}\r\n\t\t\t\/\/ Stop turning\r\n\t\t\tif ((keyName == KEY_NAME_RIGHT || keyName == KEY_NAME_LEFT ) &amp;&amp; keyType == KEY_TYPE_UP)\r\n\t\t\t{\r\n\t\t\t\tthis._vr = 0;\r\n\t\t\t}\r\n\t\t}\r\n\t};\t\r\n\t\/\/ Initialize game\r\n\tfunction init()\r\n\t{\r\n\t\t\/\/ Set keys for play\r\n\t\t$(document).bind('keyup', KEY_NAME_THRUSTER, keyEvent); \r\n\t\t$(document).bind('keydown', KEY_NAME_THRUSTER, keyEvent); \r\n\t\t\/\/ Initialize the ship start position and boundaries.\r\n\t\tship.x = canvasCenterX;\r\n\t\tship.y = canvasCenterY;\r\n\t\tship.bounds.left = 0;\r\n\t\tship.bounds.right = CANVAS_WIDTH;\r\n\t\tship.bounds.top = 0;\r\n\t\tship.bounds.bottom = CANVAS_HEIGHT;\r\n\t}\r\n\t\/\/ Evaluate key input\r\n\tfunction keyEvent(evt)\r\n\t{\r\n\t\t\/\/ Animation name for the key pressed assumed to be the char name.\r\n\t\tvar keyName = String.fromCharCode(evt.keyCode).toLowerCase();\r\n\t\t\/\/ Left arrow key\r\n\t\tif (evt.keyCode == 37)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_LEFT;\r\n\t\t}\r\n\t\t\/\/ Right arrow key\r\n\t\tif (evt.keyCode == 39)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_RIGHT;\r\n\t\t}\r\n\t\t\/\/ Up arrow key\r\n\t\tif (evt.keyCode == 38)\r\n\t\t{\r\n\t\t\tkeyName = KEY_NAME_THRUSTER;\t\r\n\t\t}\r\n\t\t\/\/ Call animation object keyEvent methods.\r\n\t\tship.keyEvent(evt.type,keyName);\r\n\t}\r\n\t\/\/ Update the model data.\r\n\tfunction update() \r\n\t{\r\n\t\tship.update();\r\n\t}\r\n\t\/\/ Draw the view.\r\n\tfunction draw() \r\n\t{\r\n\t\tcanvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);\r\n\t\tcanvas.strokeStyle = &quot;blue&quot;;\r\n\t\tcanvas.strokeRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);\r\n\t\tcanvas.fillStyle = &quot;black&quot;;\r\n\t\tcanvas.fillRect(.5, .5, CANVAS_WIDTH-1, CANVAS_HEIGHT-1);\r\n\t\tship.draw();\r\n\t}\r\n\t\/\/ JQuery ready - start here\r\n\t$(function() \r\n\t{\r\n\t\t\/\/ Initialization.\r\n\t\tinit();\r\n\t\t\/\/ Timer for animation.\r\n\t\tsetInterval(function() \r\n\t\t{\r\n\t\t\tupdate();\r\n\t\t\tdraw();\r\n\t\t}, 1000\/FPS);\r\n\t});\r\n&lt;\/script&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\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\/2011\/10\/24\/html5-canvas-based-animation-asteriods-space-ship-movement\/\" 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\/2011\/10\/24\/html5-canvas-based-animation-asteriods-space-ship-movement\/\" num_posts=\"3\" width=\"500\"><\/fb:comments><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is an example of an asteroids game space ship using the HTML5 canvas and JQuery. Demo Download Source The goal here was to reproduce the same example i posted for Actionscript 3 here: Actionscript 3 Animation Following the Mouse to Show Velocity at an Angle That example as well as this is not a [&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":[74,75,76],"class_list":["post-2519","post","type-post","status-publish","format-standard","hentry","category-general","tag-html","tag-html5-2","tag-html5-canvas"],"_links":{"self":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2519","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=2519"}],"version-history":[{"count":24,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2519\/revisions"}],"predecessor-version":[{"id":3667,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/posts\/2519\/revisions\/3667"}],"wp:attachment":[{"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/media?parent=2519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/categories?post=2519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lonhosford.com\/lonblog\/wp-json\/wp\/v2\/tags?post=2519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}