HTML5 Writing a game: Step 3

Step 3: Spinning bears!

So again, like the iPhone game, I wanted the bear to spin in the direction he was flying. This meant a couple of things:
1. I needed to make him bounce off the mushroom depending on which part of the mushroom he hit.
2. I needed to get to grips with the HTML5 canvas transformations.

Where? There….There on mushroom…

So to keep things simple I decided to break the mushroom into 4 areas across the horizontal. very left, left, right, very right. Depending on which part the bear hit I would send him flying very left, left, right or very right!

<br />
	//Has bear hit mushroom<br />
	if((bearY&gt;(screenHeight - 60)) &amp;&amp; (bearX + bearEyesOpenImg.width &gt; mushroomX &amp;&amp; bearX &lt; (mushroomX + mushroomImg.width)))<br />
	{<br />
		if(bearX &lt; mushroomX + mushroomImg.width*0.25)<br />
		{<br />
			horizontalSpeed = -speed;<br />
		}<br />
		else if(bearX &lt; mushroomX + mushroomImg.width*0.5)<br />
		{<br />
			horizontalSpeed = -parseInt(speed/2);<br />
		}<br />
		else if(bearX &lt; mushroomX + mushroomImg.width*0.75)<br />
		{<br />
			horizontalSpeed = parseInt(speed/2);<br />
		}<br />
		else<br />
		{<br />
			horizontalSpeed = speed;<br />
		}<br />
		boing1.play();<br />
		mushroomStatus = MUSHROOM_BOING_STATUS;<br />
		verticalSpeed = -speed;<br />
	}<br />

So as can be seen above depending on where the bear hit the mushroom I would adjust the horizontal speed to:-
very left = -speed
left = -speed/2
right = speed/2
very right = speed

Not exactly a realistic physics engine, but serves the cialis purpose in giving a varied gameplay.

You make me dizzy!

So to make the bear spin we need to understand a few of points about transformation in HTML5 canvas element.
1. When ever you do any transformation it’s very wise to the save the current state of your 2d context. That way, when you’ve finished making the transformation you can return to the previous state before carrying on (in this case when each call of the game loop occurs).
2. Translate the canvas to a position in the center of the bear
3. Adjust the angle
4. Draw the bear but based on the new X,Y coordinates in relation to the translation performed earlier
5. Finally restore the canvas to its previous state.

<br />
	//Save the current state<br />
	ctx.save();  </p>
<p>	//Translate to the center of the bear (i.e. the point about which we are going to perform the rotation<br />
	ctx.translate(bearX + (bearEyesOpenImg.width/2), bearY + (bearEyesOpenImg.height/2));</p>
<p>	//Adjust the angle according to the horizontal speed<br />
	bearAngle += horizontalSpeed;<br />
	if(bearAngle &lt; 0) bearAngle=360;<br />
	else if(bearAngle&gt;360) bearAngle=0;</p>
<p>	//Perform the rotation based on the current bear angle<br />
	ctx.rotate(bearAngle * Math.PI/180);</p>
<p>	//Draw the bear (if he's going down open eyes!)<br />
	//Also note that the X,Y coordinates are based on the moving out from the center of the bear and not the original bearX and bearY<br />
	//This is because of the translate function we performed earlier<br />
	if(verticalSpeed&gt;0)<br />
	{<br />
		ctx.drawImage(bearEyesOpenImg, - (bearEyesOpenImg.width/2), - (bearEyesOpenImg.width/2));<br />
	}<br />
	else<br />
	{<br />
		ctx.drawImage(bearEyesClosedImg, - (bearEyesOpenImg.width/2), - (bearEyesOpenImg.width/2));<br />
	}</p>
<p>	//Phew, no back to normal after our rotation and the world is restored!<br />
	ctx.restore();<br />

An example is available here

So that’s step 3, I’ll add another post as I add more to the game.

Coming up: Roll up, roll up, collision detection for a prize every time…

HTML5 Writing a game: Step 2

Step 2: Putting the boing in the mushroom

So just like the iPhone game I wanted the mushroom to animate a bouncy moment as the animal hits it. For the iPhone I was able to use two images one slightly squashed version of the mushroom to give the impression of it bouncing :-/

So I decided to do the the same in HTML 5. However unlike the iPhone, I was unable to create a simple image array and animate between the 2. In this case I had to add some variables to monitor the mushroom state and animation.

<br />
var MUSHROOM_BOING_STATUS = 1;<br />
var MUSHROOM_NORMAL_STATUS = 2;<br />
var mushroomStatus = MUSHROOM_NORMAL_STATUS;<br />
var mushroomWobble = false;<br />
var mushroomWobbleCount = 0;<br />

Here I’ve declared a state for a normal mushroom and one that is currently boinging! Notice, also the addition of a wobble boolean (used to swap the image back and fourth) and a wobbleCount (used to count the number of times we want a wobble to occur). *note: probably a better solution would be to get the current time and wait for a specific time period to elapse.

Now instead of just drawing the mushroom as before we display the alternate images as required.

<br />
	//Draw the mushroom (depending on its current status)<br />
	if(mushroomStatus == MUSHROOM_NORMAL_STATUS)<br />
	{<br />
		ctx.drawImage(mushroomImg, mushroomX, mushroomY);<br />
	}<br />
	else<br />
	{<br />
		//toggle the wobble!<br />
		mushroomWobble = !mushroomWobble;</p>
<p>		//increment wobble count<br />
		mushroomWobbleCount++;</p>
<p>		if(mushroomWobbleCount &gt; 50)<br />
		{<br />
			//alert(&quot;reset&quot;);<br />
			mushroomStatus = MUSHROOM_NORMAL_STATUS;<br />
			mushroomWobbleCount = 0;<br />
			mushroomWobble = false;<br />
		}</p>
<p>		//Mushroom has just been hit so make it wobble!<br />
		if(mushroomWobble)<br />
			ctx.drawImage(mushroomWobbleImg, mushroomX, mushroomY);<br />
		else<br />
			ctx.drawImage(mushroomImg, mushroomX, mushroomY);</p>
<p>	}<br />

Now when the animal hits the mushroom we set the status to MUSHROOM_BOING_STATUS

<br />
	//Has bear hit mushroom<br />
	if((bearY&gt;(screenHeight - <a href='http://viagra365.org/' title='buy viagra online'>buy viagra online</a> 60)) &amp;&amp; (bearX + bearEyesOpenImg.width &gt; mushroomX &amp;&amp; bearX &lt; (mushroomX + mushroomImg.width)))<br />
	{</p>
<p>		boing1.play();<br />
		mushroomStatus = MUSHROOM_BOING_STATUS;<br />
		verticalSpeed = -speed;<br />
	}<br />

An example is available here

So that’s the second step, I’ll add another post as I add to the game.

UPDATE: A note on sounds

Those of you using firefox may notice that the game is a little quiet. This is because it doesn’t support mp3, instead they opted for .wav. See here for more information on native audio support in browsers.

HTML5 Writing a game: Step 1

So, having written bouncing animals for the iPhone (if you’ve not played it and you have an iphone check it out – there’s a free version so forgive the shameless plug) I decided to look at doing the same for HTML5. Not sure why, except it seemed like fun at the time. I got so far and thought I’d share my findings with the interweb!

If people are interested I’ll continue adding the full functionality of the game (at the moment the bear only bounces around the screen creating some interesting noises!) and use that as a specification to learn HTML5. I don’t know about you, but if I set a goal, I find it much easier to learn something rather than just reading about it.

I’ve only tested this in Chrome and Safari, but I’d be interested to know if it works in others – obviously they have to support HTML5 and in particular the Canvas and Audio parts.

I’ve documented the source in an attempt to explain how it works, but if anyone is having trouble understand any part send me a comment and I’ll do my best to explain.

An example is available here

The current working version will be posted here, but read on if you want to understand the process of building the game parts.

Step1: A prototype bear, background woods and some noises!

The HTML bit is very simple

1. There’s a button to start and stop the game loop
2. A surrounding DIV with some styling (shown inline) to hide the cursor
3. The canvas element itself

<br />
&lt;body&gt;<br />
    &lt;input id=&quot;ss&quot; type=&quot;button&quot; value=&quot;start/stop&quot;/&gt;<br />
    &lt;div id=&quot;container&quot; style=&quot;border:1px solid; cursor:none; width:480px; height:320px;&quot;&gt;<br />
        &lt;canvas id=&quot;canvas&quot; width=&quot;480&quot; height=&quot;320&quot; &gt;<br />
        &lt;/canvas&gt;<br />
    &lt;/div&gt;<br />
&lt;/body&gt;<br />

I decided to use the mouse as a way to control the mushroom movement (left and right) to catch and bounce the animals. Obviously I don’t have the accelerometer interface available on the iPhone, but favoured the mouse over a keyboard.

The Javascript is quite straight forward but there’s a bit more of it.

<br />
//Variables <div style="display: none"><a href='http://cialisss.com/' title='buy cialis online'>buy cialis online</a></div> to handle game parameters<br />
var gameloopId;<br />
var speed=2;<br />
var horizontalSpeed = speed;<br />
var verticalSpeed = speed;<br />
var bearX=100;<br />
var bearY=100;<br />
var screenWidth;<br />
var screenHeight<br />
var gameRunning = false;<br />
var mushroomX;<br />
var mushroomY;<br />
var ctx;</p>
<p>//Create images<br />
var mushroomImg = new Image();<br />
var backgroundForestImg = new Image();<br />
var bearEyesOpenImg = new Image();<br />
var bearEyesClosedImg = new Image();</p>
<p>//Create and load sounds<br />
var boing1 = new Audio(&quot;sounds/boing_1.mp3&quot;);<br />
var boing2 = new Audio(&quot;sounds/boing_2.mp3&quot;);<br />
var boing3 = new Audio(&quot;sounds/boing_3.mp3&quot;);<br />
var boing4 = new Audio(&quot;sounds/boing_4.mp3&quot;);<br />
var boing5 = new Audio(&quot;sounds/boing_5.mp3&quot;);<br />
var awwwww = new Audio(&quot;sounds/crowdgroan.mp3&quot;);</p>
<p>//Wait for DOM to load and init game<br />
$(document).ready(function(){<br />
	init();<br />
});</p>
<p>function init(){<br />
	initSettings();<br />
	loadImages();</p>
<p>	//add event handler to surrounding DIV to monitor mouse move and update mushroom's x position<br />
	$(&quot;#container&quot;).mousemove(function(e){<br />
    	mushroomX = e.pageX;<br />
	});</p>
<p>	//add event handler for clicking on start/stop button and toggle the game play<br />
	$(&quot;#ss&quot;).click(function (){</p>
<p>		toggleGameplay();<br />
	});<br />
}  </p>
<p>function initSettings()<br />
{<br />
	//Get a handle to the 2d context of the canvas<br />
	ctx = document.getElementById('canvas').getContext('2d'); </p>
<p>	//Calulate screen height and width<br />
	screenWidth = parseInt($(&quot;#canvas&quot;).attr(&quot;width&quot;));<br />
	screenHeight = parseInt($(&quot;#canvas&quot;).attr(&quot;height&quot;));</p>
<p>	//center mushroom on the horizontal axis<br />
	mushroomX = parseInt(screenWidth/2);</p>
<p>	mushroomY = screenHeight - 40;<br />
}</p>
<p>//load all images for game<br />
function loadImages()<br />
{</p>
<p>	mushroomImg.src = &quot;images/mushroom.png&quot;;<br />
	backgroundForestImg.src = &quot;images/forest1.jpg&quot;;<br />
	bearEyesOpenImg.src = &quot;images/bear_eyesopen.png&quot;;<br />
	bearEyesClosedImg.src = &quot;images/bear_eyesclosed.png&quot;;</p>
<p>}</p>
<p>//Main game loop, it all happens here!<br />
function gameLoop(){  </p>
<p>	//Clear the screen (i.e. a draw a clear rectangle the size of the screen)<br />
	ctx.clearRect(0, 0, screenWidth, screenHeight);</p>
<p>	ctx.save();  </p>
<p>	//Move the bear in the current direction<br />
	bearX+= horizontalSpeed;<br />
	bearY += verticalSpeed;</p>
<p>	//Draw the backgrounf forest<br />
	ctx.drawImage(backgroundForestImg, 0, 0);</p>
<p>	//Draw the mushroom<br />
	ctx.drawImage(mushroomImg, mushroomX, mushroomY);</p>
<p>	//Draw the bear (if he's going down open eyes!)<br />
	if(verticalSpeed&gt;0)<br />
	{<br />
		ctx.drawImage(bearEyesOpenImg, bearX, bearY);<br />
	}<br />
	else<br />
	{<br />
		ctx.drawImage(bearEyesClosedImg, bearX, bearY);<br />
	}</p>
<p>	ctx.restore(); </p>
<p>	//Has the bear reached the far right hand side?<br />
	if(bearX&gt;screenWidth - bearEyesOpenImg.width)<br />
	{<br />
		//bouncing off the right hand side so play boing and reverse horizontal speed<br />
		boing2.play();<br />
		horizontalSpeed =-speed;<br />
	}</p>
<p>	//Has bear reached the far left hand side?<br />
	if(bearX&lt;0)<br />
	{<br />
		//bouncing off the left hand side so play boing and reverse horizontal speed<br />
		boing3.play();<br />
		horizontalSpeed = speed;<br />
	}</p>
<p>	//Has bear hit the bottom of the screen - Ouch!<br />
	if(bearY&gt;screenHeight - bearEyesOpenImg.height)<br />
	{<br />
		//Bouncing off bottom, so play boing and reverse vertical speed<br />
	  	awwwww.play();<br />
	 	verticalSpeed = -speed;<br />
		toggleGameplay();<br />
	}</p>
<p>	//Has bear hit to the top of the screen<br />
	if(bearY&lt;0)<br />
	{<br />
		//Bouncing off top, so play boing and reverse vertical speed<br />
	  	boing4.play();<br />
		verticalSpeed = speed;<br />
	}</p>
<p>	//Has bear hit mushroom<br />
	if((bearX&gt;mushroomX &amp;&amp; bearX&lt; (mushroomX + mushroomImg.width)) &amp;&amp; (bearY&gt;(screenHeight - 80)))<br />
	{<br />
		boing1.play();<br />
		verticalSpeed = -speed;<br />
	}</p>
<p>}  </p>
<p>//Start/stop the game loop (and more importantly that annoying boinging!)<br />
function toggleGameplay()<br />
{<br />
	gameRunning = !gameRunning;</p>
<p>	if(gameRunning)<br />
	{<br />
		clearInterval(gameloopId);<br />
		gameloopId = setInterval(gameLoop, 10);<br />
	}<br />
	else<br />
	{<br />
		clearInterval(gameloopId);<br />
	}<br />
}<br />

An example is available here

So that’s the first step, I’ll add another post as I add more to the game.