Quite a delay in updates due to holidays and then being tied down with work deadlines but the game and tutorials go on!
This tutorial will cover applying a mouse over to tiles and updating the tile array when a specific one is clicked. We will be using the source code from the previous tile tutorial and updating where required (http://glacialflame.com/tutorials/tiles/01/). So let us go back to the fields Felderon and actually add some dynamic interaction to our developing world that has been lost in time.
Our previous tutorial didn’t require any sort of screen updating loop as there weren’t visual updates taking place, instead we basically built a static image using tiles.
In order to be able to apply a mouse effect over the current tile we will need to have canvas constantly update the visualisations, taking into consideration where the mouse is and calculating the coordinates accordingly.
By the end of this small tutorial you will have the basic interaction required to make a HTMl5 canvas map editor.
First thing we do in building our interactive map is initiate a timer for updating the display. In the previous tutorial we had our loadAll() function call drawMap() once all images where ready, this is changed to call gameUpdate() using a timer like so.
function loadAll(){
if(loaded == tileDict.length){
clearInterval(loadTimer);
loadTimer = setInterval(gameUpdate,100);
}
}
With the gameUpdate() looking like this:
function gameUpdate(){
ctx.clearRect(0,0,210,120)
drawMap();
}
Simple. Use clearRect with your game screen width and height in order to clear it and then redraw the map.
Next within the init() function place in the following line:
canvas.addEventListener("mousemove", mouseCheck, false);
This will allow us to take in mouse movement which we will use for the drawing of our tile roll over effect as well as updating the correct array position when clicked. Now we have to apply our mouse coordinates and for this we will be using these two global variables.
var ymouse; var xmouse;
We then create our mouseCheck() function to gather and update the location of the mouse within the canvas area. The logic for this is probably as complex as this tutorial will get.
function mouseCheck(e){
var x = e.pageX;
var y = e.pageY;
ymouse=(2*(y-canvas.offsetTop-mapY)-x+canvas.offsetLeft+mapX)/2;
xmouse=x+ymouse-mapX-25-canvas.offsetLeft;
ymouse=Math.round(ymouse/25);
xmouse=Math.round(xmouse/25);
}
var x and y are set as e.pageX and e.pageY which are simply the mouse coordinates within the browser screen.
We then set ymouse as the coordinate of the Y position first taking in the offsets of the canvas box within the browser and then taking in the offset of our tiles that we applied within the box.
Xmouse is setup the same way taking in the result of ymouse and subtracting the mapX offset. The 25 subtraction within this code is the width of our tiles and will need to be changed to match that of the sizes you are using.
Finally we then divide both outcomes by the tile width (25 in this case) in order to get the tile coordinate.
So to visually have a rollover effect in the field of Felderon we make canvas draw out a transparent diamond on top of the current tile hence the need for xmouse and ymouse to be global.
After your ctx.drawImage(tileImg[drawTile],xpos,ypos); within the drawMap() function we make it check if the current array position being drawn matches our newly generated xmouse and ymouse coordinates by adding the following:
if(i == xmouse && j == ymouse){
ctx.fillStyle = 'rgba(255, 255, 120, 0.7)';
ctx.beginPath();
ctx.moveTo(xpos, ypos+12.5);
ctx.lineTo(xpos+25, ypos);
ctx.lineTo(xpos+50, ypos+12.5);
ctx.lineTo(xpos+25, ypos+25);
ctx.fill();
}
Viewing your map now you should be able to rollover each tile and a yellow overlay will appear. If you are using different sized tiles you will need to alter the moveTo offsets accordingly, alternatively you could just use a transparent .png matching your tile size and have it drawn similar to the tile itself.
We will finish this up by adding some simple interaction to the map by making tiles clickable. First of all add the following swamp tile to your directory as well as including it in your array like so:
var tileDict = Array("water.png","land.png","swamp.png");
Now add the following event to your innit(){}
canvas.addEventListener("mousedown", mouseClick, false);
This will allow us to call the mouseClick function when a tile is clicked and using our global xmouse and ymouse coordinates not only update the screen visually but update the tile array at the same time.
function mouseClick(e){
map[xmouse][ymouse] = 2;
}
Extremely simple?
Further additions to this would be to add more images to your tile array and using a dropdown list allow the user to choose their tile.
Through a small clipping of code like the following you could have JS change the array value to that of the drop down value chosen.
var tile = document.getElementById('tile').value;
map[xmouse][ymouse] = tile;
The drop down would reflect the following:
<select id="tile">
<option value="0">Sand Simple</option>
<option value="1">Sand Path</option>
<option value="2">Sand Grill 1</option>
</select>
And there you have it, simple mouse interaction that will take in page and tile offsets allowing users to click and change tiles.
The source and product of this tutorial can be seen at:
http://glacialflame.com/tutorials/tiles/02/
Next tile based tutorial will cover saving and loading your map to a database via PHP using XML.














