<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>21st Century game development</title>
	<atom:link href="http://astronautz.com/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://astronautz.com/wordpress</link>
	<description>iPhone Game Development</description>
	<lastBuildDate>Sat, 18 May 2013 14:02:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Performance update</title>
		<link>http://astronautz.com/wordpress/performance-update/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=performance-update</link>
		<comments>http://astronautz.com/wordpress/performance-update/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 13:12:19 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=899</guid>
		<description><![CDATA[I&#8217;ve incorporated my new shader code into the game I&#8217;m working on. My goal for this game is to get full dynamic shadows on all devices (even old iPhone3GS). However, trying it out I found a scene with 41,000 triangles, &#8230; <a href="http://astronautz.com/wordpress/performance-update/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve incorporated my new shader code into the game I&#8217;m working on. My goal for this game is to get full dynamic shadows on all devices (even old iPhone3GS). However, trying it out I found a scene with 41,000 triangles, including 7 skinned meshes took more than 100ms to render. By optimizing the meshes and removing conditional statements from shaders I got that down to 93ms &#8211; still way too much. Then, tried pre-calculating all matrices before sending to shader and the render time suddenly dropped to 38ms &#8211; that&#8217;s about 26 FPS, nearly acceptable. I hadn&#8217;t quite realised how important it is to precalculate.<br />
<a href="http://astronautz.com/wordpress/wp-content/uploads/2013/02/screenShot4.jpg"><img src="http://astronautz.com/wordpress/wp-content/uploads/2013/02/screenShot4.jpg" alt="" title="screenShot4" width="478" height="320" class="aligncenter size-full wp-image-900" /></a><br />
I used <a href="http://code.google.com/p/vcacne/">vcacne</a> to optimise the meshes. Vcacne reorders the triangle groups to take advantage of the GPU vertex cache. This gives a small, but noticable increase in performance (about 4%).</p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/performance-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving to OpenGL ES 2.0</title>
		<link>http://astronautz.com/wordpress/moving-to-opengl-es-2-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=moving-to-opengl-es-2-0</link>
		<comments>http://astronautz.com/wordpress/moving-to-opengl-es-2-0/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 20:09:46 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[opengl es]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=881</guid>
		<description><![CDATA[I spent last week converting my game engine to use OpenGL ES 2.0 (from 1.1) and this is the result: It took a lot of grief but I finally got shadow mapping working. The shadow mapping code is based on &#8230; <a href="http://astronautz.com/wordpress/moving-to-opengl-es-2-0/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I spent last week converting my game engine to use OpenGL ES 2.0 (from 1.1) and this is the result:<br />
<a href="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/09/racoon2.jpg"><img src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/09/racoon2.jpg" alt="" title="racoon2" width="311" height="245" class="aligncenter size-full wp-image-882" /></a><br />
It took a lot of grief but I finally got shadow mapping working. The shadow mapping code is based on the tutorial code from the PowerVR SDK.<br />
Performance is not that good, it basicaly makes the scene twice as slow to render.<br />
For example, a scene with 6 skinned meshes, 28,000 triangles runs at 45 fps with no shadow mapping and 24.2 fps with shadows (on iPhone 3GS). I tried optimising various things like reducing the amount of meshes that cast shadows. (Only 6 meshes cast shadows and one receives shadows.) But really, I suspect the second frame buffer for depth is the primary cause of the performance hit.</p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/moving-to-opengl-es-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Porting a iPhone OpenGL ES Game to OS X</title>
		<link>http://astronautz.com/wordpress/porting-a-iphone-opengl-es-game-to-os-x/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=porting-a-iphone-opengl-es-game-to-os-x</link>
		<comments>http://astronautz.com/wordpress/porting-a-iphone-opengl-es-game-to-os-x/#comments</comments>
		<pubDate>Wed, 23 May 2012 10:28:58 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[iPhone development]]></category>
		<category><![CDATA[GLUT]]></category>
		<category><![CDATA[iOS development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=850</guid>
		<description><![CDATA[I needed to show a demo of my game to some one who has a Mac, but no iPhone. There are two ways you can do this: Just run the iPhone game via the emulator. This is quite messy because &#8230; <a href="http://astronautz.com/wordpress/porting-a-iphone-opengl-es-game-to-os-x/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I needed to show a demo of my game to some one who has a Mac, but no iPhone. There are two ways you can do this: </p>
<ol>
<li>Just run the iPhone game via the emulator. This is quite messy because you need to get a non technical person to download and install xcode and install the game in the correct directory.</li>
<li>The second way is to actually port the code to OS X. This turned out to be easier than expected, thanks to the fact that the game is already built to be portable, mainly using OpenGL ES and OpenAL.</li>
</ol>
<p>The secret here is to use GLUT. I started by making a blank GLUT project using <a href="http://blog.onesadcookie.com/2007/12/xcodeglut-tutorial.html">these instructions</a>. Then, I converted my touch handling code using glutMouseFunc and glutMotionFunc. Using GLUT is actually a lot simpler than the standard OpenGL initialisation code used in EAGLView.<br />
Then, I had to convert my PVR textures to normal textures. (Funnily enough the PVR code compiles fine &#8211; but obviously does not run). Finally, OpenGL functions ending with &#8216;x&#8217; have to be changed to &#8216;i&#8217;, e.g.: glTexParameterx becomes glTexParameteri. Also, glOrthof becomes glOrtho and glFrustumf becomes glFrustum.<br />
I didn&#8217;t need to make any changes at all to OpenAL, that just worked.</p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/porting-a-iphone-opengl-es-game-to-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why PNGs are a poor choice for games</title>
		<link>http://astronautz.com/wordpress/why-pngs-are-a-poor-choice-for-games/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-pngs-are-a-poor-choice-for-games</link>
		<comments>http://astronautz.com/wordpress/why-pngs-are-a-poor-choice-for-games/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 14:05:43 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[graphics]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[png]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=751</guid>
		<description><![CDATA[Optimising game load time is something often neglected by developers, but still it is quite important. It&#8217;s quite tedious for players waiting several seconds each time a new level loads. Quite a lot of this load time is caused by &#8230; <a href="http://astronautz.com/wordpress/why-pngs-are-a-poor-choice-for-games/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Optimising game load time is something often neglected by developers, but still it is quite important. It&#8217;s quite tedious for players waiting several seconds each time a new level loads. Quite a lot of this load time is caused by the PNG format.</p>
<p>Recently, in the course of releasing our <a href="http://www.codeproject.com/Articles/330742/Texture-Atlas-Maker">Texture Atlas Maker</a> tool, I benchmarked the loading time of various PNG and Targa images on both PC and iPhone platforms. The images were loaded via libpng on the PC and via UIImage on the iPhone. The image tested is a complex 1024&#215;1024 texture with alpha transparency.</p>
<table border="1" style="white-space:nowrap">
<tr>
<th></th>
<th>Load iPhone</th>
<th>Load PC</th>
<th>size</th>
<th>Size Zipped</th>
</tr>
<tr>
<th>32-bit RLE Targa</th>
<td>87 ms</td>
<td>8 ms</td>
<td>1.79 MB</td>
<td>1.10 MB</td>
</tr>
<tr>
<th>PNG uncompressed</th>
<td>350 ms</td>
<td>32 ms</td>
<td>4.00 MB</td>
<td>1.14 MB</td>
</tr>
<tr>
<th>PNG no filter</th>
<td>379 ms</td>
<td>59 ms</td>
<td>1.13 MB</td>
<td>1.12 MB</td>
</tr>
<tr>
<th>PNG adaptive filter</th>
<td>529 ms</td>
<td>129 ms</td>
<td>1.01 MB</td>
<td>1.01 MB</td>
</tr>
</table>
<p>Targa uses a much simpler method of compression &#8211; run-length encoding &#8211; and hence is much faster to decode. As you can see from the chart it&#8217;s 5 times faster to load on the iPhone and 16 times faster on the PC, while being 77% larger. While the size difference is important for a web page, in a game it&#8217;s pretty inconsequential. Disk space is cheap, and a few kilobytes more won&#8217;t make much of a difference. Besides that games are normally distributed in zipped form and when the images are zipped they are all about the same size. </p>
<p>These benchmarks highlighted another interesting fact. PNGs are compressed in two phases, first a filtering phase, then it&#8217;s compressed by zlib. Most programs, including Photoshop and the Gimp, use adaptive filtering. The filter phase results in better PNG compression, but it also results in a much slower decode time. PNGs with adaptive, or paeth filtering load 40% slower on the iPhone, and 118% slower on the PC. </p>
<p>Using <a href="http://advsys.net/ken/utils.htm">PNGOUT</a> the filtering can be easily removed. In fact, <strong>we can potentially double the load speed of a game simply by calling this line on all the PNGs:</strong><br />
<pre><code>
pngout /f0 /force 
</code></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/why-pngs-are-a-poor-choice-for-games/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The real reason Firefox lost to Chrome: Firefox 4</title>
		<link>http://astronautz.com/wordpress/the-real-reason-firefox-lost-to-chrome-firefox-4/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-real-reason-firefox-lost-to-chrome-firefox-4</link>
		<comments>http://astronautz.com/wordpress/the-real-reason-firefox-lost-to-chrome-firefox-4/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 17:31:48 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[browser wars]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[firefox]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=739</guid>
		<description><![CDATA[In November last year Chrome overtook Firefox in market share for the first time. Part of the reason was the declining IE user base and the simplicity of the Chrome user interface, but what people don&#8217;t realise is that the &#8230; <a href="http://astronautz.com/wordpress/the-real-reason-firefox-lost-to-chrome-firefox-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In November last year Chrome overtook Firefox in market share for the first time. Part of the reason was the declining IE user base and the simplicity of the Chrome user interface, but what people don&#8217;t realise is that the release of Firefox 4 played a large part in it.<br />
Firefox 4 was a major new release and came with a brand new Javascript engine and HTML5 parser. Unfortunately, these new features came with <a href="http://blog.mozilla.com/nnethercote/2012/01/17/notes-on-reducing-firefoxs-memory-consumption/">major memory leaks and performance bugs</a>. The result was that if you used Firefox 4 for an extended period of time the browser would eventually become unresponsive, making it virtually unusable.<br />
The performance bugs were either ignored, or not considered important by the Mozilla development team, so it wasn&#8217;t until the release Firefox 7 &#8211; 5 months later &#8211; that they were <a href="http://www.gadgetvenue.com/firefox-7-to-use-up-to-50-percent-less-memory-08114900/">properly resolved</a>.<br />
<a href="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/01/trends.jpg"><img src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/01/trends.jpg" alt="" title="trends" width="841" height="475" class="aligncenter size-full wp-image-740" /></a><br />
The outcome was that users switched browsers in frustration. From the graph you can see from the release of Firefox 4 at end of March there is a notable downward trend.<br />
Ironically, Firefox 4 was being marketed as being much faster, because of it&#8217;s new Javascript engine. This made the users even more frustrated as they were experiencing the very opposite to what they were being promised and there was a loss of trust.<br />
Eventually, the <a href="https://wiki.mozilla.org/Performance/MemShrink">MemShrink</a> team resolved the performance bugs introduced by Firefox 4, but by that time it was too late. Once you start a trend like this it&#8217;s very hard to reverse it. Users that switched to Chrome are unlikely to return, as Chrome offers basically the same features. </p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/the-real-reason-firefox-lost-to-chrome-firefox-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HTML5 animation using a texture atlas</title>
		<link>http://astronautz.com/wordpress/html5-animation-using-texture-atlas/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=html5-animation-using-texture-atlas</link>
		<comments>http://astronautz.com/wordpress/html5-animation-using-texture-atlas/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 20:38:51 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=693</guid>
		<description><![CDATA[Your browser has no canvas control support! In last week&#8217;s tutorial we used the canvas control to make a character&#8217;s eyes follow the mouse. This week Nelly the elephant is back again. This time we will add some animations and &#8230; <a href="http://astronautz.com/wordpress/html5-animation-using-texture-atlas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><script type="text/javascript" src="http://astronautz.com/wordpress/animateNelly.js"></script><br />
<canvas width="160" height="160" style="float: left; margin: 10px;" id="nelly"><em>Your browser has no canvas control support!</em></canvas><br />
In last week&#8217;s tutorial we used the canvas control to make a character&#8217;s eyes follow the mouse. This week Nelly the elephant is back again. This time we will add some animations and use a texture atlas.  </p>
<h2>Texture atlas</h2>
<p>Combining all the graphics in one texture atlas gives a performance boost and makes things more managable. (A texture atlas is a similar idea to a sprite sheet, except the the images are better packed to used less space.) I used our <a href="http://www.codeproject.com/Articles/330742/Texture-Atlas-Maker">in-house tool</a> to create the atlas from the original artwork and this is the result:<br />
<a href="http://astronautz.com/wordpress/wp-content/uploads/2012/01/images0.png"><img onload="init()" src="http://astronautz.com/wordpress/wp-content/uploads/2012/01/images0-270x300.png" alt="" title="images0" width="270" height="300" class="aligncenter size-medium wp-image-775" /></a><br />
Each image is packed into one big image. The tool also creates a xml file which tells us where in the atlas each image is located:<br />
<pre><pre class="brush: xml; gutter: false; tab-size: 2;">
&nbsp;&nbsp;&lt;texture file=&quot;images0.tga&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;image name=&quot;base&quot; x=&quot;212&quot; y=&quot;0&quot; width=&quot;97&quot; height=&quot;150&quot; xOffset=&quot;39&quot; yOffset=&quot;1&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;image name=&quot;blink02&quot; x=&quot;306&quot; y=&quot;150&quot; width=&quot;96&quot; height=&quot;149&quot; xOffset=&quot;39&quot; yOffset=&quot;1&quot;/&gt;
&nbsp;&nbsp; ....
&nbsp;&nbsp;&lt;/texture&gt;
</pre></pre><br />
Each the location and size of each image is stored as well as an &#8220;offset&#8221;. The offset is used to &#8220;pad out&#8221; each frame, without wasting any space. <a href="http://astronautz.com/wordpress/wp-content/uploads/2012/01/offset2.png"><img src="http://astronautz.com/wordpress/wp-content/uploads/2012/01/offset2.png" alt="" title="offset" width="260" height="155" class="aligncenter size-full wp-image-737" /></a><br />
The atlas xml file is parsed using XMLHttpRequest:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
var client = new XMLHttpRequest();
client.onreadystatechange = xmlHandler;
client.open(&quot;GET&quot;, &quot;http://astronautz.com/wordpress/atlas.xml&quot;);
client.send();
...
function xmlHandler() 
{
&nbsp;&nbsp;if (this.readyState == 4) 
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;if (this.status == 200 || this.status == 0) 
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.responseXML != null)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var x = this.responseXML.getElementsByTagName(&quot;image&quot;); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (x == null ) return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; x.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var atlasImage = new AtlasImage();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atlasImage.load(x[n]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atlasMap[x[n].getAttribute(&quot;name&quot;)] = atlasImage;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init2();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;this.responseXML == null&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} 
&nbsp;&nbsp;&nbsp;&nbsp;else 
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;this.status = &quot; + this.status);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}
</pre></pre><br />
We create an <em>AtlasImage</em> object for each image and store it in an map, with the image name as a key.<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function AtlasImage()
{
&nbsp;&nbsp;this.m_x;
&nbsp;&nbsp;this.m_y;
&nbsp;&nbsp;this.m_width;
&nbsp;&nbsp;this.m_height;
&nbsp;&nbsp;this.m_xOffset;
&nbsp;&nbsp;this.m_yOffset;
&nbsp;&nbsp;this.load = function(elem)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = parseInt(elem.getAttribute(&quot;x&quot;)); 
&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = parseInt(elem.getAttribute(&quot;y&quot;)); 
&nbsp;&nbsp;&nbsp;&nbsp;this.m_width = parseInt(elem.getAttribute(&quot;width&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;this.m_height = parseInt(elem.getAttribute(&quot;height&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;// offset is an optional parameter
&nbsp;&nbsp;&nbsp;&nbsp;if (elem.getAttribute(&quot;xOffset&quot;))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_xOffset = parseInt(elem.getAttribute(&quot;xOffset&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_xOffset = 0;
&nbsp;&nbsp;&nbsp;&nbsp;if (elem.getAttribute(&quot;yOffset&quot;))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_yOffset = parseInt(elem.getAttribute(&quot;yOffset&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_yOffset = 0;
&nbsp;&nbsp;}
&nbsp;&nbsp;this.render = function(x, y)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;context.drawImage(atlas, this.m_x, this.m_y,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_width, this.m_height, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_xOffset+x, this.m_yOffset+y, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_width, this.m_height);&nbsp;&nbsp;
&nbsp;&nbsp;}
};
</pre></pre></p>
<p>There are 4 animations: ear flap, trunk swing, blink and standing still. The <em>Animation </em> class controls the individual animations:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function Animation()
{
&nbsp;&nbsp;this.m_currFrame;
&nbsp;&nbsp;this.m_age;
&nbsp;&nbsp;this.m_listFrame = [];
&nbsp;&nbsp;this.m_moveEyes = true;

&nbsp;&nbsp;this.isFinished = function()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;return this.m_age &gt;= this.m_listFrame.length*1000/12;
&nbsp;&nbsp;}
&nbsp;&nbsp;this.start = function()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_age = 0;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_currFrame = 0;
&nbsp;&nbsp;}
&nbsp;&nbsp;this.init = function(listIndex)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.start();
&nbsp;&nbsp;&nbsp;&nbsp;var image;
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; listIndex.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image = atlasMap[listIndex[n]];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (image)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listFrame.push(image);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else alert(&quot;missing image:&quot;+listIndex[n]);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;this.update = function(timeElapsed)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_age += timeElapsed;
&nbsp;&nbsp;&nbsp;&nbsp;// 12 frames per second
&nbsp;&nbsp;&nbsp;&nbsp;this.m_currFrame = Math.floor(this.m_age/1000*12);
&nbsp;&nbsp;&nbsp;&nbsp;if (this.m_currFrame &gt;= this.m_listFrame.length)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_currFrame = this.m_listFrame.length-1;
&nbsp;&nbsp;}
&nbsp;&nbsp;this.render = function()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_listFrame[this.m_currFrame].render(0, 0);&nbsp;&nbsp;
&nbsp;&nbsp;}
};
</pre></pre><br />
You need to pass it a list of images that compose the animation sequence:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
var earFlap = new Animation();
&nbsp;&nbsp;earFlap.init([&quot;base&quot;, &quot;earflap02&quot;, &quot;earflap04&quot;, &quot;earflap06&quot;, 
&nbsp;&nbsp;&nbsp;&nbsp;&quot;earflap08&quot;, &quot;earflap06&quot;, &quot;earflap04&quot;, &quot;earflap02&quot;, &quot;base&quot;]);
&nbsp;&nbsp;earFlap.m_moveEyes = false;
&nbsp;&nbsp;listAnim.push(earFlap);
</pre></pre><br />
Note: sometimes we use the same images several times in the same animation to save space.<br />
For some animation we don&#8217;t want the eyes to move, because the head moves in the animation. For these cases we set <em>m_moveEyes = false</em>.</p>
<p>The current animation is stored in a global variable <em>currAnim</em>. In the main game loop once an animation stops we randomly select a new one, by setting <em>currAnim</em> to a new animation:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function render() 
{&nbsp;&nbsp;
&nbsp;&nbsp;var timeElapsed = new Date().getTime() - lastRender;
&nbsp;&nbsp;lastRender = new Date().getTime();
&nbsp;&nbsp;if (currAnim.isFinished())
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;var randNum = Math.floor(Math.random()*100);
&nbsp;&nbsp;&nbsp;&nbsp;if (randNum &lt; listAnim.length)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currAnim = listAnim[randNum];
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else 
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// make it show stand still animation most of the time
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currAnim = standStill;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;currAnim.start();
&nbsp;&nbsp;}
&nbsp;&nbsp;context.clearRect(0, 0, canvasWidth, canvasHeight);
&nbsp;&nbsp;currAnim.update(timeElapsed);
&nbsp;&nbsp;currAnim.render();&nbsp;&nbsp;
&nbsp;&nbsp;if (currAnim.m_moveEyes == true)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.update();
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.update();
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.render();
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.render();
&nbsp;&nbsp;}
&nbsp;&nbsp;requestAnimFrame(render);&nbsp;&nbsp;
}&nbsp;&nbsp;
</pre></pre><br />
That&#8217;s all. Full source code can be found <a href="http://astronautz.com/wordpress/animateNelly.js">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/html5-animation-using-texture-atlas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Eyes that follow the mouse</title>
		<link>http://astronautz.com/wordpress/html5-eyes-that-follow-the-mouse/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=html5-eyes-that-follow-the-mouse</link>
		<comments>http://astronautz.com/wordpress/html5-eyes-that-follow-the-mouse/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 22:59:53 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=657</guid>
		<description><![CDATA[Your browser has no canvas control support! I made a cute flash movie of an elephant ages ago. Among other things the eyes of the elephant followed the cursor. Unfortunately subsequent flash security updates broke the functionality (if you want &#8230; <a href="http://astronautz.com/wordpress/html5-eyes-that-follow-the-mouse/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><script type="text/javascript" src="http://astronautz.com/wordpress/nelly.js"></script><br />
<canvas width="100" height="150" style="float: left; margin: 10px;" id="nelly"><em>Your browser has no canvas control support!</em></canvas><br />
I made a cute flash movie of an elephant ages ago. Among other things the eyes of the elephant followed the cursor. Unfortunately subsequent flash security updates broke the functionality (if you want mouse move events <em>outside </em>the flash control you need special permissions). So, I decided to convert it to HTML5. The result you can see to the left of this paragraph. (Note: if you see nothing, it&#8217;s because you have an old version of IE.).</p>
<h2>How it&#8217;s done</h2>
<p>I use an onload event handler somewhere in the html file which calls the <em>init()</em> function. E.g.:<br />
<pre><code>
&lt;body onload=&quot;init()&quot;&gt;
</code></pre><br />
In the <em>init()</em> function the images are loaded and the canvas resized and then the render loop is started via <em>requestAnimFrame</em>. All images are stored in the one png (this is known as an image atlas).<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function init()
{
&nbsp;&nbsp;canvas = document.getElementById(&#039;nelly&#039;);
&nbsp;&nbsp;if (canvas.getContext)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;context = canvas.getContext(&#039;2d&#039;);
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;}
&nbsp;&nbsp;logElement = document.getElementById(&#039;log&#039;);
&nbsp;&nbsp;atlas = new Image();&nbsp;&nbsp;
&nbsp;&nbsp;atlas.src = &#039;http://astronautz.com/wordpress/nelly0.png&#039;;
&nbsp;&nbsp;atlas.onload = function()
&nbsp;&nbsp;{ 
&nbsp;&nbsp;&nbsp;&nbsp;window.addEventListener (&quot;mousemove&quot;, getCoords, true);
&nbsp;&nbsp;&nbsp;&nbsp;xCanvas = canvas.offsetLeft;
&nbsp;&nbsp;&nbsp;&nbsp;yCanvas = canvas.offsetTop;
&nbsp;&nbsp;&nbsp;&nbsp;var elem = canvas.offsetParent;
&nbsp;&nbsp;&nbsp;&nbsp;while (elem)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xCanvas += elem.offsetLeft;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yCanvas += elem.offsetTop;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elem = elem.offsetParent;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;backWidth = 97;
&nbsp;&nbsp;&nbsp;&nbsp;backHeight = 150;
&nbsp;&nbsp;&nbsp;&nbsp;canvas.width = backWidth;
&nbsp;&nbsp;&nbsp;&nbsp;canvas.height = backHeight;
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.setSize(4, 4);
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.setMin(44, 30);
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.setMax(54, 52);
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.setAtlas(97, 0);
&nbsp;&nbsp;&nbsp;&nbsp;eyeRight.init();
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.setSize(4, 4);
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.setMin(34, 30);
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.setMax(39, 52);
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.setAtlas(97, 0);
&nbsp;&nbsp;&nbsp;&nbsp;eyeLeft.init();
&nbsp;&nbsp;&nbsp;&nbsp;requestAnimFrame(render);
&nbsp;&nbsp;};&nbsp;&nbsp;
}
</pre></pre><br />
Note, that I create a event handler which stores the mouse coordinates in two global variables:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
var xMouse = 0;
var yMouse = 0;
...
function getCoords(event) 
{
&nbsp;&nbsp;xMouse = event.clientX;
&nbsp;&nbsp;yMouse = event.clientY + window.pageYOffset;
};
...
window.addEventListener (&quot;mousemove&quot;, getCoords, true);

</pre></pre><br />
Each eye is controlled by an Eye object. It takes a min, max as parameters:<br />
<a href="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/01/minMax.png"><img onload="init()" src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2012/01/minMax.png" alt="" title="minMax" width="307" height="279" class="aligncenter size-full wp-image-666" /></a><br />
It also needs the size of the eye image and it&#8217;s position within the image atlas before you initialise:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
eyeRight.setSize(4, 4);
eyeRight.setMin(44, 30);
eyeRight.setMax(54, 52);
eyeRight.setAtlas(97, 0);
eyeRight.init();
</pre></pre><br />
The eye movement is calculated by getting the slope of the angle between the eyeball center and the current mouse position. Then you need to calculate the position taking into account the quadrant:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
&nbsp;&nbsp;this.update = function()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;var xDiff = xMouse-(xCanvas+this.m_xOrig);
&nbsp;&nbsp;&nbsp;&nbsp;var yDiff = yMouse-(yCanvas+this.m_yOrig);
&nbsp;&nbsp;&nbsp;&nbsp;// first calculate x pos
&nbsp;&nbsp;&nbsp;&nbsp;if (yDiff == 0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (xDiff &gt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = this.m_xMax;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = this.m_xMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = this.m_yOrig;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var slope = xDiff/yDiff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (yDiff &gt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = slope*(this.m_xMax-this.m_xMin) + this.m_xMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = -slope*(this.m_xMax-this.m_xMin) + this.m_xMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;// then calculate y pos
&nbsp;&nbsp;&nbsp;&nbsp;if (xDiff == 0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (yDiff &gt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = this.m_yMax;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = this.m_yMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = this.m_xOrig;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var slope = yDiff/xDiff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (xDiff &gt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = slope*(this.m_yMax-this.m_yMin) + this.m_yMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = -slope*(this.m_yMax-this.m_yMin) + this.m_yMin;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (this.m_x &gt; this.m_xMax)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = this.m_xMax;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else if (this.m_x &lt; this.m_xMin)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = this.m_xMin;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (this.m_y &gt; this.m_yMax)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = this.m_yMax;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else if (this.m_y &lt; this.m_yMin)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = this.m_yMin;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
</pre></pre><br />
The full source code can be downloaded <a href="http://astronautz.com/wordpress/nelly.js" title="nelly.js">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/html5-eyes-that-follow-the-mouse/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Creating realistic particle effect with HTML5 canvas</title>
		<link>http://astronautz.com/wordpress/creating-realistic-particle-effect-with-html5-canvas/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-realistic-particle-effect-with-html5-canvas</link>
		<comments>http://astronautz.com/wordpress/creating-realistic-particle-effect-with-html5-canvas/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 19:26:03 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[particle effect]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=590</guid>
		<description><![CDATA[This is my first experiment with the HTML5 canvas &#8211; the so-called replacement for Flash. I tried to create a realistic smoke particle effect to go in the background of my war zone scene. As you can see above it&#8217;s &#8230; <a href="http://astronautz.com/wordpress/creating-realistic-particle-effect-with-html5-canvas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><script type="text/javascript" src="http://astronautz.com/wordpress/peffect.js">
</script><br />
<img onload="init()" src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/12/aftermath.jpg" alt="" title="aftermath" id="background" class="aligncenter size-full"/><br />
<canvas id="tutorial"></canvas></p>
<p>This is my first experiment with the HTML5 canvas &#8211; the so-called replacement for Flash. I tried to create a realistic smoke particle effect to go in the background of my war zone scene. As you can see above it&#8217;s worked out pretty well (unless you are using an old version of IE &#8211; which doesn&#8217;t support the canvas control).</p>
<h2>Tips</h2>
<ul>
<li>Copy from real life</li>
<p>To figure out how smoke behaves I first studied a video clip frame by frame. I found that the smoke is made up of individual puffs of smoke, which expand rapidly emerging from the fire and then slowly drift upwards expanding much slower and fading out. If you want realism I recommend observing the effect in real life, rather than creating it purely from your head, or copying some one else&#8217;s particle effect.</p>
<li>The further from camera, the slower</li>
<p>It&#8217;s important to take into account the distance the particle effect is from the camera. The further away, the <i>slower</i> the particles will move. For instance, the fireball of a huge spaceship exploding will almost appear to expand in slow motion. If you make the fireball expand too fast it will look like a tiny explosion to the viewer.
</ul>
<h2>Technical details</h2>
<p>I embed  a normal image in my html page as the background and then overlaid the canvas control on top of it, as follows:<br />
<pre><code>
&lt;html&gt;
...
&lt;body&gt;
&nbsp;&nbsp;&lt;img onload=&quot;init()&quot; src=&quot;aftermath.jpg&quot; id=&quot;background&quot;/&gt;
&nbsp;&nbsp;&lt;canvas id=&quot;tutorial&quot;&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><br />
On loading the image the <em>init()</em> function is called which positions the canvas control to lie exactly on top of the background image.</p>
<p>To animate the canvas we use the same render loop as we do in games. This is what it looks like:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
var lastRender = new Date().getTime();
var context;
var smokeRight = new ParticleEmitter();
function render()
 {
&nbsp;&nbsp;&nbsp;&nbsp; // time in milliseconds
&nbsp;&nbsp;&nbsp;&nbsp; var timeElapsed = new Date().getTime() - lastRender;
&nbsp;&nbsp;&nbsp;&nbsp; lastRender = new Date().getTime();
&nbsp;&nbsp;&nbsp;&nbsp; smokeRight.update(timeElapsed);
&nbsp;&nbsp;&nbsp;&nbsp; smokeRight.render(context);
&nbsp;&nbsp;&nbsp;&nbsp; requestAnimFrame(render);
 }
</pre></pre><br />
<em>requestAnimFrame </em>is an improved version of <em>setTimeout</em>. It calls our render function once every 16.66 ms ( i.e. 60 FPS). Every object typically has an <em>update</em> and <em>render</em> method. <em>update</em> is called with a <em>timeElapsed </em>parameter.  <em>timeElapsed</em> is the time in milliseconds since the last call. If you want everything to animate smoothly it is important that you make all movement calculations relative to this parameter.</p>
<p>There are two &#8220;classes&#8221; (really function objects, because javascript does not have classes, as such), <em>ParticleEmitter</em> and <em>Particle</em>.  <em>ParticleEmitter</em> creates an array of Particles and animates them:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function ParticleEmitter()
{
&nbsp;&nbsp;this.m_x;
&nbsp;&nbsp;this.m_y;
&nbsp;&nbsp;this.m_dieRate;
&nbsp;&nbsp;this.m_image;
&nbsp;&nbsp;this.m_speed = 0.02;
&nbsp;&nbsp;this.m_alpha = 1.0;

&nbsp;&nbsp;this.m_listParticle = [];

&nbsp;&nbsp;// ParticleEmitter().init function
&nbsp;&nbsp;// xScale = number between 0&nbsp;&nbsp;and 1. 0 = on left side 1 = on top
&nbsp;&nbsp;// yScale = number between 0&nbsp;&nbsp;and 1. 0 = on top 1 = on bottom
&nbsp;&nbsp;// particles = number of particles
&nbsp;&nbsp;// image = smoke graphic for each particle
&nbsp;&nbsp;this.init = function(xScale, yScale, particles, image)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = CANVAS_WIDTH*xScale;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = CANVAS_HEIGHT*yScale;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_image = image;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_dieRate = 0.95;
&nbsp;&nbsp;&nbsp;&nbsp;// start with smoke already in place
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; particles; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle.push(new Particle());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].init(this, n*50000*this.m_speed);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;this.update = function(timeElapsed)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; this.m_listParticle.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].update(timeElapsed);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;this.render = function(context)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; this.m_listParticle.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].render(context);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
};
</pre></pre></p>
<p>Each Particle initialises itself around the location of the emitter. The update method cause the particle to expand, fade in, then fade out and move upwards depending on the age. Each particle has a random direction, velocity and lifespan. When <em>m_age &gt; m_timeDie</em> the particle is considered to be dead, at which case it is &#8220;reborn&#8221; at the location of the emitter again. This provides a continuous trail of smoke. (Well actually, I make it so that eventually the smoke stops according to the <em>m_dieRate </em>parameter).</p>
<p>The <em>init</em> function mentioned previously, loads the smoke puff graphic and the foreground character graphic and initialises the ParticleEmitters:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2;">
function init()
{
&nbsp;&nbsp;var canvas = document.getElementById(&#039;tutorial&#039;);
&nbsp;&nbsp;if (canvas.getContext)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;context = canvas.getContext(&#039;2d&#039;);
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;}
&nbsp;&nbsp;var imgBack = document.getElementById(&#039;background&#039;);
&nbsp;&nbsp;CANVAS_WIDTH = imgBack.width;
&nbsp;&nbsp;CANVAS_HEIGHT = imgBack.height;
&nbsp;&nbsp;canvas.width = imgBack.width;
&nbsp;&nbsp;canvas.height = imgBack.height;
&nbsp;&nbsp;var xImage = imgBack.offsetLeft;
&nbsp;&nbsp;var yImage = imgBack.offsetTop;
&nbsp;&nbsp;var elem = imgBack.offsetParent;
&nbsp;&nbsp;while (elem)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;xImage += elem.offsetLeft;
&nbsp;&nbsp;&nbsp;&nbsp;yImage += elem.offsetTop;
&nbsp;&nbsp;&nbsp;&nbsp;elem = elem.offsetParent;
&nbsp;&nbsp;}
&nbsp;&nbsp;canvas.style.position = &#039;absolute&#039;;
&nbsp;&nbsp;canvas.style.left = xImage + &quot;px&quot;;
&nbsp;&nbsp;canvas.style.top = (yImage) + &quot;px&quot;;
&nbsp;&nbsp;var imgSmoke = new Image();&nbsp;&nbsp;
&nbsp;&nbsp;imgSmoke.src = &#039;puffBlack.png&#039;;
&nbsp;&nbsp;imgSmoke.onload = function()
&nbsp;&nbsp;{ 
&nbsp;&nbsp;&nbsp;&nbsp;smokeRight.init(.9, .531, 20, imgSmoke);
&nbsp;&nbsp;&nbsp;&nbsp;smokeLeft.m_alpha = 0.3;
&nbsp;&nbsp;&nbsp;&nbsp;smokeLeft.init(.322, .453, 30, imgSmoke);
&nbsp;&nbsp;&nbsp;&nbsp;requestAnimFrame(render);
&nbsp;&nbsp;};&nbsp;&nbsp;
}
</pre></pre><br />
Only when the smoke image is finished loading is the first <em>requestAnimFrame</em> called, which kicks off the animation.</p>
<p>This is the graphic I used for the smoke particle:<br />
<a href="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/12/puffBlack.png"><img title="puffBlack" src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/12/puffBlack.png" alt="" width="32" height="31" /></a></p>
<p>You may notice there is also a wind effect controlled by the global <em>windVelocity</em> variable. This changes slightly every frame, simulating puffs of wind.</p>
<h2>Optimisation</h2>
<p>Finally, there is a drawing optimisation. The <em>clearRect</em> method clears all, or part of the canvas. We are being smart and we only clear the smallest rectangle that is needed. We keep track of this with the global variables: <em>dirtyLeft, dirtyTop, dirtyRight, dirtyBottom</em>. This optimisation may not actually be necessary in our case &#8211; depends on what platforms you are targetting.  The canvas control is quite fast on PCs (even older browsers like Firefox 3.6), however mobile browsers will struggle. This example works on the iPhone (albeit with slightly jittery animation)</p>
<h2>Integration into WordPress</h2>
<p>To get the particle effect to work in WordPress insert the following into the post:<br />
<pre><code>
&lt;script type=&quot;text/javascript&quot; src=&quot;...peffect.js&quot;&gt;&lt;/script&gt;
&lt;img onload=&quot;init()&quot; id=&quot;background&quot; src=&quot;....background.jpg&quot; alt=&quot;&quot; title=&quot;aftermath&quot; 
class=&quot;aligncenter size-full&quot;/&gt;
&lt;canvas id=&quot;tutorial&quot;&gt;&lt;/canvas&gt;
</code></pre><br />
Then you need to upload the script via ftp and specify the full url for all file references (i.e <em>src=&#8221;http://mydomain.com/wordpress/peffect.js&#8221;</em> </p>
<h2>References</h2>
<p>I found the tutorial at <a href="https://developer.mozilla.org/en/Canvas_tutorial" target="_blank">Mozilla.org</a> to be very useful source on the canvas control. Also, <a href="http://www.html5rocks.com/en/tutorials/canvas/performance/" target="_blank">this article</a> has some great optimisation tips. </p>
<h2>Full listing</h2>
<p>Finally, here is a full listing of the code used:<br />
<pre><pre class="brush: javascript; gutter: false; tab-size: 2; ">
function ParticleEmitter()
{
&nbsp;&nbsp;this.m_x;
&nbsp;&nbsp;this.m_y;
&nbsp;&nbsp;this.m_dieRate;
&nbsp;&nbsp;this.m_image;
&nbsp;&nbsp;this.m_speed = 0.02;
&nbsp;&nbsp;this.m_alpha = 1.0;

&nbsp;&nbsp;this.m_listParticle = [];

&nbsp;&nbsp;// ParticleEmitter().init function
&nbsp;&nbsp;// xScale = number between 0&nbsp;&nbsp;and 1. 0 = on left side 1 = on top
&nbsp;&nbsp;// yScale = number between 0&nbsp;&nbsp;and 1. 0 = on top 1 = on bottom
&nbsp;&nbsp;// particles = number of particles
&nbsp;&nbsp;// image = smoke graphic for each particle
&nbsp;&nbsp;this.init = function(xScale, yScale, particles, image)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;// the effect is positioned relative to the width and height of the canvas
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = CANVAS_WIDTH*xScale;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = CANVAS_HEIGHT*yScale;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_image = image;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_dieRate = 0.95;
&nbsp;&nbsp;&nbsp;&nbsp;// start with smoke already in place
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; particles; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle.push(new Particle());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].init(this, n*50000*this.m_speed);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;this.update = function(timeElapsed)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; this.m_listParticle.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].update(timeElapsed);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;this.render = function(context)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;for (var n = 0; n &lt; this.m_listParticle.length; n++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_listParticle[n].render(context);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
};

function Particle()
{
&nbsp;&nbsp;this.m_x;
&nbsp;&nbsp;this.m_y;
&nbsp;&nbsp;this.m_age;
&nbsp;&nbsp;this.m_xVector;
&nbsp;&nbsp;this.m_yVector;
&nbsp;&nbsp;this.m_scale;
&nbsp;&nbsp;this.m_alpha;
&nbsp;&nbsp;this.m_canRegen;
&nbsp;&nbsp;this.m_timeDie;
&nbsp;&nbsp;this.m_emitter;
&nbsp;&nbsp;
&nbsp;&nbsp;this.init = function(emitter, age)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_age = age;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_emitter = emitter;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_canRegen = true;
&nbsp;&nbsp;&nbsp;&nbsp;this.startRand();
&nbsp;&nbsp;}

&nbsp;&nbsp;this.isAlive = function () 
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;return this.m_age &lt; this.m_timeDie;
&nbsp;&nbsp;}

&nbsp;&nbsp;this.startRand = function()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;// smoke rises and spreads
&nbsp;&nbsp;&nbsp;&nbsp;this.m_xVector = Math.random()*0.5 - 0.25;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_yVector = -1.5 - Math.random();
&nbsp;&nbsp;&nbsp;&nbsp;this.m_timeDie = 20000 + Math.floor(Math.random()*12000);

&nbsp;&nbsp;&nbsp;&nbsp;var invDist = 1.0/Math.sqrt(this.m_xVector*this.m_xVector 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ this.m_yVector*this.m_yVector);
&nbsp;&nbsp;&nbsp;&nbsp;// normalise speed
&nbsp;&nbsp;&nbsp;&nbsp;this.m_xVector = this.m_xVector*invDist*this.m_emitter.m_speed;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_yVector = this.m_yVector*invDist*this.m_emitter.m_speed;
&nbsp;&nbsp;&nbsp;&nbsp;// starting position within a 20 pixel area 
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x = (this.m_emitter.m_x + Math.floor(Math.random()*20)-10);
&nbsp;&nbsp;&nbsp;&nbsp;this.m_y = (this.m_emitter.m_y + Math.floor(Math.random()*20)-10);
&nbsp;&nbsp;&nbsp;&nbsp;// the initial age may be &gt; 0. This is so there is already a smoke trail in 
&nbsp;&nbsp;&nbsp;&nbsp;// place at the start
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x += (this.m_xVector+windVelocity)*this.m_age;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_y += this.m_yVector*this.m_age;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_scale = 0.01;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_alpha = 0.0;
&nbsp;&nbsp;}

&nbsp;&nbsp;this.update = function(timeElapsed)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;this.m_age += timeElapsed;
&nbsp;&nbsp;&nbsp;&nbsp;if (!this.isAlive()) 
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// smoke eventually dies
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Math.random() &gt; this.m_emitter.m_dieRate)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_canRegen = false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!this.m_canRegen)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// regenerate
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_age = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.startRand();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;// At start the particle fades in and expands rapidly (like in real life)
&nbsp;&nbsp;&nbsp;&nbsp;var fadeIn = this.m_timeDie * 0.05;
&nbsp;&nbsp;&nbsp;&nbsp;var startScale;
&nbsp;&nbsp;&nbsp;&nbsp;var maxStartScale = 0.3;
&nbsp;&nbsp;&nbsp;&nbsp;if (this.m_age &lt; fadeIn)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_alpha = this.m_age/fadeIn;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startScale = this.m_alpha*maxStartScale; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// y increases quicker because particle is expanding quicker
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y += this.m_yVector*2.0*timeElapsed;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_alpha = 1.0 - (this.m_age-fadeIn)/(this.m_timeDie-fadeIn);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startScale = maxStartScale;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.m_y += this.m_yVector*timeElapsed;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;// the x direction is influenced by wind velocity
&nbsp;&nbsp;&nbsp;&nbsp;this.m_x += (this.m_xVector+windVelocity)*timeElapsed;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_alpha *= this.m_emitter.m_alpha;
&nbsp;&nbsp;&nbsp;&nbsp;this.m_scale = 0.001 + startScale + this.m_age/4000.0;
&nbsp;&nbsp;}

&nbsp;&nbsp;this.render = function(ctx)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;if (!this.isAlive()) return;
&nbsp;&nbsp;&nbsp;&nbsp;ctx.globalAlpha = this.m_alpha;
&nbsp;&nbsp;&nbsp;&nbsp;var height = this.m_emitter.m_image.height*this.m_scale;
&nbsp;&nbsp;&nbsp;&nbsp;var width = this.m_emitter.m_image.width*this.m_scale;
&nbsp;&nbsp;&nbsp;&nbsp;// round it to a integer to prevent subpixel positioning
&nbsp;&nbsp;&nbsp;&nbsp;var x = Math.round(this.m_x-width/2);
&nbsp;&nbsp;&nbsp;&nbsp;var y = Math.round(this.m_y+height/2);
&nbsp;&nbsp;&nbsp;&nbsp;ctx.drawImage(this.m_emitter.m_image, x, y, width, height);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (x &lt; dirtyLeft)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirtyLeft = x;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (x+width &gt; dirtyRight)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirtyRight = x+width;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (y &lt; dirtyTop)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirtyTop = y;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;if (y+height &gt; dirtyBottom)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirtyBottom = y+height;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
};

var lastRender = new Date().getTime();
var context;
var smokeRight = new ParticleEmitter();
var smokeLeft = new ParticleEmitter();
var CANVAS_WIDTH = 960;
var CANVAS_HEIGHT = 640;
// only redraw minimimum rectangle
var dirtyLeft = 0;
var dirtyTop = 0;
var dirtyRight = CANVAS_WIDTH;
var dirtyBottom = CANVAS_HEIGHT;
var windVelocity = 0.01;
var count = 0;

function init()
{
&nbsp;&nbsp;var canvas = document.getElementById(&#039;tutorial&#039;);
&nbsp;&nbsp;if (canvas.getContext)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;context = canvas.getContext(&#039;2d&#039;);
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;}
&nbsp;&nbsp;var imgBack = document.getElementById(&#039;background&#039;);
&nbsp;&nbsp;// make canvas same size as background image
&nbsp;&nbsp;CANVAS_WIDTH = imgBack.width;
&nbsp;&nbsp;CANVAS_HEIGHT = imgBack.height;
&nbsp;&nbsp;canvas.width = imgBack.width;
&nbsp;&nbsp;canvas.height = imgBack.height;
&nbsp;&nbsp;// get absolute position of background image
&nbsp;&nbsp;var xImage = imgBack.offsetLeft;
&nbsp;&nbsp;var yImage = imgBack.offsetTop;
&nbsp;&nbsp;var elem = imgBack.offsetParent;
&nbsp;&nbsp;while (elem)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;xImage += elem.offsetLeft;
&nbsp;&nbsp;&nbsp;&nbsp;yImage += elem.offsetTop;
&nbsp;&nbsp;&nbsp;&nbsp;elem = elem.offsetParent;
&nbsp;&nbsp;}
&nbsp;&nbsp;// position canvas on top of background
&nbsp;&nbsp;canvas.style.position = &#039;absolute&#039;;
&nbsp;&nbsp;canvas.style.left = xImage + &quot;px&quot;;
&nbsp;&nbsp;canvas.style.top = yImage + &quot;px&quot;;
&nbsp;&nbsp;var imgSmoke = new Image();&nbsp;&nbsp;
&nbsp;&nbsp;imgSmoke.src = &#039;puffBlack.png&#039;;
&nbsp;&nbsp;imgSmoke.onload = function()
&nbsp;&nbsp;{ 
&nbsp;&nbsp;&nbsp;&nbsp;smokeRight.init(.9, .531, 20, imgSmoke);
&nbsp;&nbsp;&nbsp;&nbsp;smokeLeft.m_alpha = 0.3;
&nbsp;&nbsp;&nbsp;&nbsp;smokeLeft.init(.322, .453, 30, imgSmoke);
&nbsp;&nbsp;&nbsp;&nbsp;requestAnimFrame(render);
&nbsp;&nbsp;};&nbsp;&nbsp;
}

// shim layer with setTimeout fallback
&nbsp;&nbsp;&nbsp;&nbsp;window.requestAnimFrame = (function(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;window.requestAnimationFrame&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.webkitRequestAnimationFrame || 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.mozRequestAnimationFrame&nbsp;&nbsp;&nbsp;&nbsp;|| 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.oRequestAnimationFrame&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.msRequestAnimationFrame&nbsp;&nbsp;&nbsp;&nbsp; || 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function( callback ){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.setTimeout(callback, 17);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;})();

&nbsp;&nbsp;
function render() 
{&nbsp;&nbsp;
&nbsp;&nbsp;// time in milliseconds
&nbsp;&nbsp;var timeElapsed = new Date().getTime() - lastRender;
&nbsp;&nbsp;lastRender = new Date().getTime();
&nbsp;&nbsp;context.clearRect(dirtyLeft, dirtyTop, dirtyRight-dirtyLeft, dirtyBottom-dirtyTop);
&nbsp;&nbsp;dirtyLeft = 1000;
&nbsp;&nbsp;dirtyTop = 1000;
&nbsp;&nbsp;dirtyRight = 0;
&nbsp;&nbsp;dirtyBottom = 0;
&nbsp;&nbsp;smokeRight.update(timeElapsed);
&nbsp;&nbsp;smokeRight.render(context);
&nbsp;&nbsp;smokeLeft.update(timeElapsed);
&nbsp;&nbsp;smokeLeft.render(context);
&nbsp;&nbsp;windVelocity += (Math.random()-0.5)*0.002;
&nbsp;&nbsp;if (windVelocity &gt; 0.015)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;windVelocity = 0.015;
&nbsp;&nbsp;}
&nbsp;&nbsp;if (windVelocity &lt; 0.0)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;windVelocity = 0.0;
&nbsp;&nbsp;}
&nbsp;&nbsp;requestAnimFrame(render);&nbsp;&nbsp;
}&nbsp;&nbsp;
</pre></pre></p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/creating-realistic-particle-effect-with-html5-canvas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Protected: Warlord game design: a brief skim through</title>
		<link>http://astronautz.com/wordpress/warlord-game-design/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=warlord-game-design</link>
		<comments>http://astronautz.com/wordpress/warlord-game-design/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 23:28:06 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=508</guid>
		<description><![CDATA[There is no excerpt because this is a protected post.]]></description>
				<content:encoded><![CDATA[<form action="http://astronautz.com/wordpress/wp-login.php?action=postpass" method="post">
<p>This post is password protected. To view it please enter your password below:</p>
<p><label for="pwbox-508">Password: <input name="post_password" id="pwbox-508" type="password" size="20" /></label> <input type="submit" name="Submit" value="Submit" /></p>
</form>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/warlord-game-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML: Killing the Bloat</title>
		<link>http://astronautz.com/wordpress/xml-killing-the-bloat/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xml-killing-the-bloat</link>
		<comments>http://astronautz.com/wordpress/xml-killing-the-bloat/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 19:52:45 +0000</pubDate>
		<dc:creator>Ed Welch</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://astronautz.com/wordpress/?p=27</guid>
		<description><![CDATA[Many people criticise XML for being unnecessarily verbose, which is true. What they may not realise is that the bloat can be easily be slimmed down by storing the data in attributes instead of elements. Example of bloated XML: The &#8230; <a href="http://astronautz.com/wordpress/xml-killing-the-bloat/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Many people criticise XML for being unnecessarily verbose, which is true. What they may not realise is that the bloat can be easily be slimmed down by storing the data in attributes instead of elements.</p>
<p>Example of bloated XML:</p>
<blockquote><p><a href="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/01/bloatedXML.png"><img class="aligncenter size-full wp-image-28" title="bloated XML" src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/01/bloatedXML.png" alt="" width="649" height="181" /></a></p></blockquote>
<p>The same info can be stored in a much more compact fashion:</p>
<p><img class="aligncenter size-full wp-image-30" title="slim XML" src="http://79.170.44.133/astronautz.com/wordpress/wp-content/uploads/2011/01/slimXML1.png" alt="slim XML example" width="813" height="127" />The slimmed down version has many advantages:</p>
<ul>
<li>Easier to read</li>
<li>Faster to load</li>
<li>Uses up less disk space and bandwidth</li>
</ul>
<p>Of coarse, you could achieve the same results by just using JSON, but then you lose out on the XML buzzword <img src='http://astronautz.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://astronautz.com/wordpress/xml-killing-the-bloat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
