Building a level editor for a shoot em up – JSON issue

We have a number of in-house tools written through a combination of Javascript and PHP. The data from the editors is written to a MySQL database and much of the workflow is handled within a single page – i.e. AJAX requests firing off to the back end to retrieve and update data.

Something that we hurl around a fair bit is JSON.

Currently the focus is on building an interface for designing levels for our forthcoming shoot ’em up; Akari: Battle Star.

What we’re after is precision. That is, we want to place entities within the game to be triggered at specific times during the game’s progress.

We call this tool Neo.

The Neo data is stored in a database table that is pretty straight forward in its design.

Within the editor we select the game and level to work on and an AJAX request pulls the data from the database. The result of which is a PHP array.

We then encode the array into a JSON format via PHP’s json_encode() method. This presents us with the Javascript that we can then use to write the front end.

Manipulating the JSON within the Neo front end is straight forward and we use jQuery for much of this.

Once we’re happy with the data we then fire off another AJAX call to post the data to the back end. This is were we ran into problems.

In short we were struggling to decode the JSON into a PHP array.

The JSON format we pass in looks something like this:

    {"gameid":1,"level":1,"trigger":100,"entityType":"formation",alienRow:1}

There’s much more to the data than that but essentially this is the format. The trigger value is the stage of the game (in ticks) at which point the entity data is triggered.

When we attempt to decode this JSON string and form the PHP array it’s successful.

But when we add another object to the string, it fails.

Something like this:

    {"gameid":1,"level":1,"trigger":100,"entityType":"formation",alienRow:1},
    {"gameid":1,"level":1,"trigger":150,"entityType":"island",alienRow:0}

We couldn’t for the life of us figure out why this wouldn’t work. So we employed PHP’s json_last_error() method which captures the last attempt at decoding JSON.

    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

We received the error

 - Syntax error, malformed JSON

Some of you seasoned eagle-eyed Javascript gurus will have already noticed the problem.

We were trying to construct a Javascript array by formatting it badly.

The JSON we should have been passing looks something like this:

    {"data":[{"gameid":1,"level":1,"trigger":100,"entityType":"formation",alienRow:1},
    {"gameid":1,"level":1,"trigger":150,"entityType":"island",alienRow:0}]}

Once we’d defined the Javascript properly in an array format the decoding worked.

Neo development is now moving forward at pace and we’re having a huge amount of fun designing the levels and graphics.

 

 

Adding dynamic tweet functionality to HTML5 games

My current focus is with the PlayStar Arcade. I’m keen to push it as a platform for playing my HTML5 games. A lot of work has been carried out “under the bonnet” as we say in the UK and now I’m in to the slightly more entertaining areas of adding bells and whistles.

Something I was always keen to pursue was the ability for players to share their scores via social media. Twitter was my first port of call.
Thanks to their Tweet button script placing a button inside the game was a fairly simple exercise.
The flow that I wanted would see the player complete the game and reach the “GAMEOVER” status. At this point I would present the <div> containing the Twitter code.
The player would then be prompted to share their score and tap the Twitter “Tweet” button. All I had to do at this point was switch the text inside of the code that Twitter gave me with my own text. This replaced text would be what appears in the dialogue box for the player to tweet.

tweet score from html5 game

But there was a problem.

The attribute that I need to change to achieve this is the data-text attribute of the <a> tag in the Twitter script. But dynamically changing this attribute proves useless. 

When the Twitter script executes it converts the <a> tag in to a <div>. Any subsequent calls that I make to amend the tag fail.

I appreciate that this is largely theory so rather than post my own code solutions I’m going to link a site that covers it neatly with code examples.

http://tumblr.christophercamps.com/post/4072517874/dynamic-tweet-button-text-using-jquery

This guy had the exact same problem and solved it beautifully. 
I now have the ability to let the player complete a game, rack up a score and then share it with the world courtesy of Twitter. Facebook is next.

A little side project and some thoughts on touch control in an HTML5 platform game

Screenshot

Screenshot from Bouncy

Spent a little time on a side project this last few days. It’s a pretty simple platform game that involves guiding a hedgehog / porcupine type animal around the screen collecting valuable items and avoiding the bad guys.

When I first came up with the control system I had intended for the game to not involve platforms at all. It seemed to be a lot of fun just hurling the spikey creature in to the air and have him pop balloons. But the more I developed the touch control the more it seemed to make sense that the player could jump and walk with ease.

I’ve never wanted to overlay touch controls on to a game. I really don’t like them. So for this game I’m using touchMove() to guide the character around and touchEnd() to initiate playerJump().

The theory is quite simple. When I initiate TouchStart() I set a time with a straight forward function to return the number of milliseconds since some moment in 1970. (I think!)


function time()
{
var d = new Date();
return d.getTime();
};

I store this value in something like m.player.firstTouch.
Then when touchEnd() fires I do the same and store it in m.player.lastTouch.
A simple test to see whether lastTouch is significantly higher than firstTouch tells me whether or not the player has tapped the screen or tried to move the character.

With a bit of fine tuning I’ve also managed to make the character’s movement pretty smooth and of course relative to the player’s first touch on the touchscreen.

The effect is nice. If there’s one thing I’ve learned making these simple arcade games it’s that if your controls are a mess the game will have no appeal whatsoever. According to my Analytics I enjoy a high percentage of repeat plays. I see this as a target to maintain.

I don’t have a title for this game just yet so I call it Bouncy :)
It’s very much a work in progress with still a fair amount of place holder art. But it’s moving along nicely and has given me a valuable distraction from my work on Kyle Comet’s first adventure in space ! As with Kyle my intention is to develop game characters that I can expand on and potentially brand for future adventures.

You can check my dev page for notes and updates on the game’s progress.

Viewports and the scaling & positioning of the canvas

Having just spent a couple of hours poring over my code for scaling & positioning the game canvas I thought I’d share the experience.

Despite having made several HTML5 games over the last couple of years I’ve never experienced any real issues with scaling or positioning. Just recently however I’ve started to notice inconsistencies between browsers and OS versions.

In some cases the canvas would scale perfectly but not position properly. In other cases the canvas would not scale properly yet position well in the centre of the screen.

My criteria is simple – I want the games to be played in any orientation and to fit consistently in the centre of the screen.
Where full screen is available in either width (landscape orientation games) or height (portrait) I will also aim for that.

It’s 90% there. On Galaxy S2+ and iPhone4+ portrait games load and scale to fit fine in portrait and landscape games load fine and scale in landscape.
The problem arises on iOS when the games are loaded in the wrong orientation.

e.g. if the game is a portrait game and it loads up in portrait mode then it scales to fit just fine, as you would expect. (illustration 1)

ipadscale-portraitload

illustration 1 – game loads in portrait mode

But if the player then decides to play it in landscape it scales fine but doesn’t centre correctly. Just sits to the left of centre. (illustration 2)

illustration 2 - game loaded in portrait and rotated to landscape

illustration 2 – game loaded in portrait and rotated to landscape – note white space where HTML BODY is simply untouched.

If the game loads up in landscape then it centers beautifully and is playable (illustration 3)

iPad HTML5

illustration 3 – game loaded whilst tablet in landscape mode

If the player then rotates to portrait the game scales just fine on iPhone to fit the screen but on iPad it sits rather awkwardly to the right of the screen with about a third of the content out of sight. (illustration 4)

ipadscale-landscapeload-rotate

illustration 4 – loaded in landscape and rotated to portrait

This has an impact on my regional touchEvent code that I use for driving menus and other in-game features.

I no longer present a banner message instructing the player to rotate. It seems clunky and my clients hate it.

Of course it’s far too easy to suggest that as long as the games load up in their preferred orientation then surely I’ll be OK.
The reality is it needs to work and work properly.

So what’s my code doing?

Well surprisingly little.
I certainly don’t sniff the device. It’s 2013. So I don’t actually know I’m dealing with iOS any more than I know it’s a desktop or mobile browser.

The first thing I do is record the screen’s physical width less any scrollbars.

var w = window.innerWidth;
var h = window.innerHeight;

I also record the game’s intended canvas dimensions.

var rw =320;
var rh = 480;

Then to accurately scale the canvas I use the Math.min() method to first determine how best to scale the canvas to preserve the aspect ratio.

multiplier = Math.min((h / rh), (w / rw));
var actualCanvasWidth = rw * multiplier;
var actualCanvasHeight = rh * multiplier;

Fairly simple stuff there just to keep the aspect ratio of the game’s canvas intact and as previously stipulated aim for full screen in the preferred orientation.

To actually position the canvas on the screen I use CSS.

So first I’ve already got a handle on the canvas and stored it within my global namespace (g):

HTML

<body>
<div id="game">
<canvas class="canvas"></canvas>
</div>
</body>

JavaScript

g.gamecanvas = document.getElementById('game');

CSS

.canvas { width: 100%; height: 100%; }

I then make sure that the canvas parent is displaying as a block level element, assign a width to it and use the margin property to centre it. The canvas fits its parent to the pixel.

g.gamecanvas.style.display = "block";
g.gamecanvas.style.width = actualCanvasWidth + "px";
g.gamecanvas.style.height = actualCanvasHeight + "px";
g.gamecanvas.style.margin = "0px auto 0px auto";

My scaling function is called every time the onresize() or onorientationchange() events are fired. It is also called at the very top of the code before the assets are loaded.

So when we tie all this together we get a perfect presentation the first time the game is loaded.
The canvas scales to fit the orientation and centers perfectly in the centre of the screen.

So why on earth do I get that “dead” area when the tablet is rotated from portrait to landscape? (illustration 2 above)
Why does the canvas shift over to the right when the tablet is rotated from landscape to portrait? (illustration 4 above)
There has to be something else to look at.

The answer lay in the META description for the VIEWPORT.

Here’s what I used to present in the index.html of every game:

<meta name="viewport" content="width=320, height=440, user-scalable=no, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />

What a mess. I’d never touched this in almost two years.
Understanding the viewport is essential to understanding mobile presentation. Generally speaking the rule is if you don’t understand how it works don’t use it. The results can be undesirable.

Rather than go to the trouble of fully understanding what the viewport definitions are and do I decided to look at what I actually want to achieve. The answer here is very simple – a) stretch content to screen dimensions, b) suppress ability to pinch / zoom.

There is no need to specify the physical width or height in pixels of the device screen. There is also no need to restrict user scaling with the user-scalable attribute. Finally there is no need to set a maximum-scale, which I must admit I found surprising.

The only code I need here is:

<meta name="viewport" content="width=device-width, initial-scale=1">

The scaling of the canvas and positioning of the parent element within the document body are now perfect. No more “dead” regions and no more strange horizontal positioning.

There appears to be more sympathy for my lousy meta code within Android browsers than there is with iOS and Safari.

HTML5 framework update

  • added full Web Audio support (tested iOS6 / Chrome desktop)
    • fixed 404 errors on AJAX call that still resulting in the onLoad event firing (misleading bug)
  • added webkitvisibilitychange support
  • paused animations in pauseMode (some obstacle entities use their animation frame to trigger collision)
  • soundtrack supported independently from main sfx()
  • Rounded floating point positions on rotation
  • replaced context.clearRect with canvas.width = canvas.width (resulting in full support on Android browsers – previously full screen operation would return a blank screen)
  • added debug console switch to incoming variables (querystring)

Enhancements to my HTML5 game framework

The thrill for me in making these simple browser games is the challenge of a new feature. I’ve wanted for a long time to sit down and figure out just what I need to add to my game’s framework to ensure that future developments are made that bit easier.

There’s another driving factor: publishing the end product to the client. More often than not when I sit down to try and identify the bottlenecks in the process I see that publishing and all the associated / bespoke developments comes back to haunt me. Many of the new features I have added in the last week have been driven through necessity based on specific client requirements.

With every new game that I create there’s always a variety of things that I have to do to it for it to fit with the client’s contractual requirements. Such things as localisation, adding back-links to specific locations, the presence (or otherwise) of advertising, audio, scaling, screen-locking. The list grows.
Most recently I have done a fair amount of work in importing and exporting specific data from each game. The client wanted specific data both ingoing and outgoing from each game.

Again courtesy of the querystring the games accept a string of data, store them within an AJAX object and then pass them out to a .php (or whatever format you like) file at set intervals in the game.
The games also support MD5 for added protection.

Once written it naturally made sense to add this as a complete feature for future games. Not too difficult to code by any means but a fantastic feature to be able to sell.

So I implemented a bunch of new features that allow me to just focus on getting back to making games.

For example; at the start of the game’s initialisation it scans the querystring. If it finds returnURL and a corresponding value it paints a branded backlink icon to the screen in a pre-configured location that acts as a shortcut back to the parent site.

For fonts I use Google’s font library for my games. This is a wonderfully free method for introducing some variety to my game’s copy. But when it comes to translation in to a language such as French we soon find that the character set does not support the variety of accents and other language-specific features. In this scenario the game knows to revert to a safe font and will resize and position the text accordingly.
The data in my text arrays is always saved out in UTF-8 so presenting rich character sets in a standard system font is easy.

requestAnimationFrame (rAF) and Audio were the last two features to go in. rAF gives silky smooth movement in browsers that support it and audio, courtesy of the Web Audio API, simply brings the games to life.

I’m looking forward to being able to sit down and churn out more games. I always intended to aim for 2 – 3 new games a month. One of my key goals for 2012 was to increase my portfolio from 8 to 30 games. There’s chance of a late spurt in development, yet !

With this new framework for making games rapidly taking shape I’m confident I can achieve it.

Creating a very basic “Star Wars” style trench scene viewed from above

Prototyping new game ideas is a lot of fun. Thanks to some serious enhancements to my game framework it’s also pretty quick.

I enjoy day-dreaming new ideas and recently I was watching something on TV that put me in mind of the film Star Wars. It was a fast paced scene in a TV show with cars, helicopters and trucks all viewed from above. I was struck by how effective the shot was in portraying speed with the buildings that lined the streets.

The Star Wars link came with the closing scenes in the first film as the fighters raced down the trench. It occured to me that this scene viewed from above might work quite well for a (yet another !) shooting game. I quite liked the claustrophobia of it, amongst other things.

So I had a bash at putting together a short test.
The theory was quite simple. I would use a simple fillRect() to block out the 5 key areas of the trench. The lighter shades at the edge would of course be the top of the trench (the surface if you will of the Death Star) and the darker shades would represent the inner walls and the trench’s floor.
You can see the rectangular divisions highlighted in the image below.

All I needed to do was give the impression of movement.
For this I am using lines and paths.

I created a trenchLine() class and initiated it with 2 y values. Nothing more is needed at the moment.
The first y co-ordinate is for the first 2 points and the last 2 points (see the image below).
the second co-ordinate is for the middle points which will be moving that bit slower.

As the game begins I initiate around 4 trench lines to be drawn over the grey background at equidistant intervals down the screen. (In the illustration below the 4th line is just off the top of the canvas so not yet visible)
The key here is in how the trench line breaks up to represent the pseudo-3D nature of the trench.

click to enlarge

So I originate the line at x = 0.
The line itself is broken in to 5 shorter lines.
On a 320 wide play area I draw the line’s points at

1. x=0, // left hand side
2. x=32, // edge of trench – about to drop to floor
3. x=48, // left hand side of the 192px wide floor
4. x=240, // right hand side of trench floor
5. x=288 // edge of trench on right hand side

Each point moves at a set speed down the screen.
I set the trench speed to be, say, 4 pixels per frame.
This affects points 1,2, 5 and 6.

But the trench floor needs to move slower and for these points (3 and 4) I move them at 3 pixels per frame.

I have a simple line drawing routine:


function drawLine(x1,y1,x2,y2,c)
{
 try
 {
 g.ctx.beginPath();
 g.ctx.moveTo(x1, y1);
 g.ctx.lineTo(x2, y2);
 g.ctx.closePath();
 g.ctx.strokeStyle = c;
 g.ctx.stroke();
 }
 catch (e)
 {
 write("drawline: " + e.message);
 }
};

Quite straight forward in that it accepts the start and end points of the line and the colour that you wish to draw it.
I then pass the following 5 draw instructions to it to create my trench line:


drawLine(0,o.y,32,o.y,"#aaaaaa");
drawLine(32,o.y,64,o.y2,"#666666");
drawLine(64,o.y2,256,o.y2,"#444444");
drawLine(256,o.y2,288,o.y,"#666666");
drawLine(288,o.y,g.canvaswidth,o.y,"#aaaaaa");

The overall effect here is that the outer lines effectively overtake the inner lines and you get the impression of a moving trench from above – as per the screen shot.

I created some placeholder sprites and threw them around to see how effective playing the game in a narrow 192px corridor might be. So far so good.

Watch this space :)

Adding achievements to Distant Orbit

It struck me whilst developing Distant Orbit that the game was crying out for a more persistent challenge – for want of a better phrase.
I wanted people to be able to play the game for a little while and have progress saved after each phase. That’s a fairly standard thing and in a standalone sense using HTML5’s localStorage I can of course achieve this.
But I also wanted the player to have something to aim for that wasn’t directly part of the story within the game and that’s where achievements come in.

Distant Orbit screenshot

Distant Orbit

Achievements (or awards ) are a great way to give the gamer a reason to come back and have another go beyond actually completing the immediate task. In this case blasting the aliens to pieces and knocking out the tower.

I recently played Shuffle Party on the XBox Live Arcade on my Windows Phone. It’s a fun and very tidy little game that sees you spending most of your time trying to unlock content and gain achievements. I liked it so much I wanted to implement it.
So last night I spent a good couple of hours doing just that.
The results are certainly very rewarding and I think the overall appeal of the game has shot up 10 fold.

The plot of the game as stated is simple: destroy the enemy tower installations in each stage. That’s your primary goal. But within that, thanks to the introduction of achievements, you now have the added challenge of not losing your wingman, not taking any hits, completing the stage with full energy.. so on and so forth.

There are four planets to fly between each with 10 stages. Within each planet there are 6 awards to aim for with a special award handed out for destroying every tower on the planet. Currently (and most likely finally) moving between stages on each planet is sequential. Once the player has completed a set amount of stages and / or unlocked a set amount of achievements the next planet becomes available.

Each planet has its own name, tower range and of course its own look and feel. Again this gives the player something more to aim for. We are all naturally curious as to what the unlocked content actually looks like and how it plays !

I intend to create a little badge icon for each achievement. Furthermore I intend to structure the code such that the achievements can be portable and implement easily with a cloud service such as clay.io.

So far Distant Orbit has taken around 6 weeks. That’s 2 weeks longer than I’d anticipated. Thankfully the addition of the new features means that I get that in future titles and should hopefully rein the dev times back to a manageable month.

Distant Orbit screenshot

Playing with fillStyle to create some neat game effects and text

Creating games using HTML5 and the Canvas isn’t always all about using drawImage(). For the most part it is of course because we want to display our lovingly drawn sprites and environments but there are plenty of legitimate cases where we might opt for using the primitive drawing methods such as fillRect().

I use fillRect and fillText consistently in my games and have never found it to be a performance killer. At least not using the canvas dimensions 320 x 480 which I use for mobile gaming. But you should be careful. The more you ask the API to do the more of a load you place on it and at some point something has to give. Namely your framerate !
But with a bit of planning and some consideration for what you are actually presenting it can be very visually rewarding.

Distant Orbit screenshot

Distant Orbit

In Distant Orbit I’m actually using rectangles to construct the pseudo 3D tumbling landscape. It’s a very old and well-used method of creating a moving terrain.
The theory is quite simple in that the lower half of the game screen is first filled with a solid colour and the striped terrain is then a series of rectangular ‘sprites’ that scale upwards as they fall down the screen. The effect is quite nice and I save on having to draw two sets of stripes by having the underlying layer as the alternate colour.
So the underlying layer is drawn in the lighter shade and then the striped layers are drawn over the top.

I refer to the stripes as sprites since they are derived from my base sprite class. That is they inherit specific behaviours and attributes that allow me to position and present them on the screen.
It’s just that when I get to actually drawing them I’m using fillRect instead of drawImage.

Here’s an example of how you would display a rectangle.

function drawRectangle(o) // o is the incoming sprite object from which I shall derive co-ordinates and size
{
 g.ctx.fillStyle = '#bf0000';
 g.ctx.fillRect(o.x,o.y,o.w,o.h);
};

(You can see that I store the canvas context within the global namespace g)
So g.ctx.fillStyle has a hex colour value assigned to it and the following draw instruction honours it.
When I draw the rectangle I have already passed through a move() function to return the new position and dimensions of the stripe.
It is also important to note that the fillRect method uses width and height as opposed to locations in terms of scaling your shape.

Example

g.ctx.fillRect(20,20,30,30);

produces a 30×30 square with its origin at 20,20 NOT as you might expect a 10×10 square that starts at 20,20 and finishes at 30,30.

To achieve the scaling terrain effect in Distant Orbit I initialise each stripe with a height attribute of 1 pixel. As it falls down the canvas it scales until by the time it falls off the bottom it’s around 48 pixels deep.
Rather than scale the stripes by a fixed number of pixels each time (e.g. 2px) I use a modifier. This stops the stripes looking horribly uniform. By incrementing the height attribute by a modifier that itself increments with smaller numbers I get the effect that the stripe remains quite narrow for a while as if it where lost toward the horizon:

o.modifier += 0.1;
o.h += o.modifier;

So the height of the stripe would change something like this:

0.1
0.3
0.6
1.0
1.5

which gives a far nicer effect than a uniform increment such as 1, 2, 3 etc.

The beauty of this approach to drawing on screen is that it is reflected in other forms of presentation such as writing text. Instead of fillRect you just use fillText but the style is set in the exact same way.

Take a look at this code.

<!doctype html>
<html lang=en>
<head>
	<title> fillRect() </title>
	<meta charset=utf-8>
	<script>

		var g = {};
		function init()
		{
			g.ctx = document.querySelector('canvas').getContext('2d');
			fill(0,0,320,480,"#0000ff"); // Blue background
			fill(20,20,30,30,"#ffff00"); // Yellow square (10x10)
			filla(0,80,320,20,"255,255,0",0.6); // Yellow stripe with 0.6 alpha
			write("Hello, World !",160,94,"center","#ffffff",12,null,"bold");
		};

		function fill(x,y,w,h,c)
		{
			c = c ? c : "#000000";
			g.ctx.fillStyle = c;
			g.ctx.fillRect(x,y,w,h);
		};

		function filla(x,y,w,h,c,a)
		{
			c = c ? c : "0,0,0";
			a = a ? a : 0.5;
			g.ctx.fillStyle = "rgba(" + c + "," + a + ")";
			g.ctx.fillRect(x,y,w,h);
		};

		function write(t,x,y,a,c,s,f,w)
		{
			c = c ? c : "#ffffff";
			a = a ? a : "left";
			s = s ? s : 10;
			f = f ? f : "Sans-Serif";
			w = w ? w : "normal";
			g.ctx.font = w + " " + s + "px " + f;
			g.ctx.textAlign = a;
			g.ctx.fillStyle = c;
			g.ctx.fillText(t,x,y);
		};

	</script>
</head>
<body onload="init();">

	<canvas width="320" height="480"></canvas>

</body>
</html>

The basic rectangle drawing is there along with a slightly different version that allows us to provide an alpha value. This alpha range is from 0 (100% transparency, i.e. non-existant) to 1 (opaque). So for example if you provided a value of 0.5 you’d see a 50/50 blend of the background colour and your rectangle’s colour.
The key thing to remember here is that for rgba values you must specify your colours numerically.
So for White rather than #ffffff you’d specify 255,255,255.
For White with 50% alpha opacity you’d use rgba(255,255,255,0.5);

Visit this link: fillrect.html to see the above code in action.

You can see that the text also has the standard CSS attributes of alignment, font-size, font-family and font-weight. This is extremely useful when you consider that you can pull fonts from Google’s web font repository for use in your games.

By simply adding the following line to my markup I can use the “Bangers” web font family in my game.

<link href='http://fonts.googleapis.com/css?family=Bangers' rel='stylesheet' type='text/css'>

Visit this link to see the change: fillrect-newfont.html

You can see that in my code the order in which the items are drawn is important.
Starting with the blue background is important since it allows subsequent items to be drawn over the top. If the blue background were drawn last it would simply overlay everything else.
That said there is an instance where you may wish to present a solid block of colour over your content and that’s when you wish to fade your content in and/or out.
To do this we simply draw a rectangle with progressive alpha opacity as the last draw item in our draw order.

Take a look at this code for the necessary adaptations:

<!doctype html>
<html lang=en>
<head>
	<title> Fade In/Out </title>
	<meta charset=utf-8>
	<link href='http://fonts.googleapis.com/css?family=Bangers' rel='stylesheet' type='text/css'>
	<script>

		var g = {};
		function init()
		{
			g.ctx = document.querySelector('canvas').getContext('2d');
			load();
		};

		function load()
		{
			g.img = new Image();
			g.img.onload = function() {
				g.fade = 0;
				g.ticker = setTimeout("loop()", 40); 
			};
			g.img.src = "sun.jpg";
		};
		
		function loop()
		{
			clearTimeout(g.ticker);

			g.ctx.drawImage(g.img,0,0);
			filla(0,0,320,480,"0,0,0",g.fade);
			writea("Hello, World !",160,110,"center","255,255,255",32,"Bangers","normal",g.fade);
			if (g.fade < 1) { g.fade += 0.01; }

			setTimeout("loop()", 40);
		};

		function fill(x,y,w,h,c)
		{
			c = c ? c : "#000000";
			g.ctx.fillStyle = c;
			g.ctx.fillRect(x,y,w,h);
		};

		function filla(x,y,w,h,c,a)
		{
			c = c ? c : "0,0,0";
			a = a ? a : 0.5;
			g.ctx.fillStyle = "rgba(" + c + "," + a + ")";
			g.ctx.fillRect(x,y,w,h);
		};

		function write(t,x,y,a,c,s,f,w)
		{
			c = c ? c : "#ffffff";
			a = a ? a : "left";
			s = s ? s : 10;
			f = f ? "'" + f + "'" : "Sans-Serif";
			w = w ? w : "normal";
			g.ctx.font = w + " " + s + "px " + f;
			g.ctx.textAlign = a;
			g.ctx.fillStyle = c;
			g.ctx.fillText(t,x,y);
		};

		function writea(t,x,y,a,c,s,f,w,alpha)
		{
			c = c ? c : "255,255,255";
			a = a ? a : "left";
			s = s ? s : 10;
			f = f ? f : "Sans-Serif";
			w = w ? w : "normal";
			alpha = alpha ? alpha : 1;
			g.ctx.font = w + " " + s + "px " + f;
			g.ctx.textAlign = a;
			g.ctx.fillStyle = "rgba(" + c + "," + alpha + ")";
			g.ctx.fillText(t,x,y);
		};

	</script>
</head>
<body onload="init();">

	<canvas width="320" height="480"></canvas>

</body>
</html>

Very straight forward. You can see that I set a variable called fade and have it increment slowly from zero to 1. By assigning this value to the new text writing function I achieve the effect of the background fading out whilst the foreground text fades in.

Visit this link to see it in action: fadeinout.html

This was only ever intended to be a basic introduction to using shapes and text. I’d like to elaborate on it a bit in a future post and cover gradients and arcs. Anyone familiar with my games will have seen me use gradients for sky transitions in a couple of cases. I am a big fan of them as I think they offer a useful programmatic solution to something that is typically controlled by the artist.

When Distant Orbit is complete I hope to offer a bit more of an insight in to the game’s structure with regard to the drawing.

Touch screen and player movement

Today I have spent a hopeless amount of time playing with the touch screen interface for a new game.
The game is a maze game, similar in many respects to Pac-Man in the way that it executes, but quite different in its content.

When I started to assemble the code for the player’s sprite behaviour I knew I was going to be faced with a tough decision regarding movement control.
In previous games this has never really been much of an issue since I’m generally dealing with movement in a fairly basic way. Galactians for example was a simple slide left and slide right affair. Wizard Wars was a touch-to-go-here game and Danger Ranger was a case of sliding your thumb or finger to turn the ranger to walk left or right. Everything else in that game was about jumping. In any case I’d taken the movement code from Dragons and not added much more to it.

But with this maze game it’s important to me that the whole thing feels natural. I really didn’t want the player to be concerned with where he has to put his finger in order to move. I really do loath the idea of semi-transparent virtual d-pads. It’s just that the touch screen interface can be used to great effect without them.

But, I had to explore all options.

Before I prattle on about the theory of implementing player movement let me show you how I set up and manage the touch code.

function initTouch()
{
	if(checkForTouch()) {
		if (document.body.addEventListener)
		{
			document.body.addEventListener('touchmove', touchMove, false);
			document.body.addEventListener('touchstart', touchStart, false);
			document.body.addEventListener('touchend', touchEnd, false);
		} else {
			window.addEventListener('touchmove', touchMove, false);
			window.addEventListener('touchstart', touchStart, false);
			window.addEventListener('touchend', touchEnd, false);
		}
	} else {
		window.addEventListener('mousedown', mouseDown, false);
		window.addEventListener('mousemove', mouseMove, false);
		window.addEventListener('mouseup', mouseUp, false);
		write("No touch capability.");
	}
};

function checkForTouch() {		
	var d = document.createElement("div");
	d.setAttribute("ontouchmove", "return;");
	return typeof d.ontouchmove == "function" ? true : false;
};

As you can see I perform a fairly basic test to see whether touch is supported as a function and if not fall back to mouse control. If you were to play any of my games on the desktop with diags switched on you’d see the line “No touch capability.” every time.
The point here is the level of control that we have over touch start, move and end. It’s pretty powerful and gives us a ton of options for controlling our games.

So how do we do anything with touch ?
It’s quite simple. Every time a touch event fires I store the co-ords in the touch object. Something like this..

var touch = {};
function touchStart(event)
{
	var xy = getXY(event.touches[0]);
	touch.startx = xy.x;
	touch.starty = xy.y;
};

function getXY(event)
{
	try
	{
		var xy = {};
		xy.x = (event.pageX - (g.canvas.offsetParent ? g.canvas.parentNode.offsetLeft : 0));
		xy.y = (event.pageY - (g.canvas.offsetParent ? g.canvas.parentNode.offsetTop : 0));
		return xy;
	}
	catch (e)
	{
		write("getXY: " + e.message);
	}
};

I generally wrap most functions in try / catch. Just pretend I did that with the touchStart() function ;-)
So again it’s all fairly straight forward. Returning an object with just the x and y parameters I get some control over how to handle my player movement. Notice that I use the offsets to determine the true position since I’m positioning my game canvas in the centre of the document with margin: 0px auto and a width of 320px; On the desktop this is an issue. Generally on mobile it isn’t since I’m handling the display with the viewport.

So now I’ve got some co-ordinates and I can start to explore options for controlling the player.

The game itself is a maze crawling affair. I want my character to walk the maze avoid monsters and collecting goodies. There will be a little more to it than that but essentially this gives me something to go on when considering the player’s control of his character.

Option 1 is all about a virtual overlaid d-pad. You will have seen them. God awful things that just don’t feel natural at all. They’re generally plonked in the lower corner of the screen and you are forced to control your game in a small space.
I created a simple d-pad graphic and placed it in the lower right corner.
I then wrote some code to track which edge of the d-pad had been pressed, uploaded the game and hit the refresh on the phone.
( Note: my X/Y detection code is primitive. I’m checking the screen to see if the touch event was recorded at the same location as the location of the d-pad graphic. )
To cut a long story short I must have spent 50% of my time looking at the blessed d-pad and not even enjoying watching my character march around the maze.
I ditched this idea swiftly.

Option 2 saw me drawing thin arrow graphics at the top, right, bottom and left most edges of the game screen.
The theory was sound. I’d just let the player touch some fairly large areas of the screen in order to move the player up, right, down or left.
Again I uploaded and refreshed on the phone.
Initially it felt OK. I was able to smoothly move the character around and it felt pretty good having more than a couple of cm flexibility in the movement.
But I soon tired of having my hand obscuring the lower corners of the screen when the player character was down there and I was in need of some finer movement.
I ditched the idea.

Option 3 was actually fairly similar to option 1 but with greater scope.
I switched the phone off and just touched the screen. I played the imaginary game and tried to feel for what was right.
As I moved my thumb around I realised that the kind of control I was after was in fact quite similar to option 1. But I wanted the d-pad to be positioned based upon where I first tapped the screen. A kind of user-definable d-pad location.
So I set about creating a sequence that went something like:
touchStart: record the centre of the d-pad co-ordinates
touchMove: throw the event at a d-pad handler and update touch x and y

With the centre of the d-pad recorded as my origin I then needed to figure out how the co-ordinates of touchMove translated in to a new direction for the player.
Something like..

if (touch.newx > touch.startx) moveright; 

There are some complications here.
Imagine that the finger is swiping to the right from an origin of say 128,128.
As the touchMove event continues to fire the x is incrementing through 129, 130, 131 and this is great. I’m clearly looking to move to the right.
But then my thumb flicks up or down the slightest amount.
My y value is also incrementing 128,129,130,131…
So which is true ?
Does the player want to move right or down ?

I’m actually still working this bit out and will blog about it once I’ve got it working.

Overall the movement is fairly smooth just now and I’m working hard to make it as smooth as possible.
User feedback and a logical touch interface is vital in these games. If you mess this bit up you kill the entire game and your player will just go looking for something else to play.

Other things that I’m curious about are walking DOWN a corridor, effectively “hugging” the wall to turn RIGHT or LEFT at the next available exit.
To this end I’ve played Pac-Man quite a bit just lately and learned some valuable design lessons.
I’m also mucking about setting touch.testx and touch.testy in an attempt to sniff the wall for available exits.
Actually this code works pretty good right now.

When there is more to see I will return to this subject.
Thanks for listening to me waffle ;)
Please feel free to share your own thoughts, ideas words of wisdom on the subject.