in search of Space Monsters

exploring arcade game design with HTML5 and JavaScript

Touch screen and player movement

Posted on | February 2, 2012 | 3 Comments

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.

Comments

3 Responses to “Touch screen and player movement”

  1. Desert Dog
    February 3rd, 2012 @ 1:27 am

    Is A* out of the question?

    Here’s an example of something I did with iPhone in mind (but is on the PC!):
    http://desmond.imageshack.us/Himg689/scaled.php?server=689&filename=amazey.png&res=medium

    You click/tap on a square, and it draws a path to it. If the player likes the path (it doesn’t pass through any dangers) he taps again, and the robot then moves through the maze.

    This seemed the best solution for me. The player should easily be able to pick up& play. However, for you, it sounds like you want to have monsters? Moving around? That’ll make this sort of movement a little trickier to balance out.

  2. Mark
    February 3rd, 2012 @ 9:34 am

    I rather like the look of that. Do you have a working example of it ?
    It’s not the implementation that I’m after for this game but it might be pretty nice for a future one.

  3. Desert Dog
    February 4th, 2012 @ 2:03 am

    I use GameMaker, so the A* algorithm’s already set up for me, so it’s really easy to do something like this in that. Example, my code looks a little something like this:

    ///code
    my_grid=mp_grid_create(96,32,12,9,32,32) //the area I want to check+grid size
    mp_grid_add_instances(my_grid,obj_block,false); //an objects I want to avoid easy to add more if I want

    mp_grid_path(coords to, and from, returns a path if there is one)

    And then I use that paths coords to draw my fancy ‘movement’ line, and to move along. So pretty high-level stuff! But I know you like to get down to the code roots with your code. =D

    You could try googling around, it’s a pretty common algorithm in all languages. E.g. I found this implementation in Javascript:
    http://www.briangrinstead.com/blog/astar-search-algorithm-in-javascript

Leave a Reply





  • Categories

  • Recent Posts

  • Recent Comments