1

I have developed a game using HTML5 and Javascript/JQuery. This game is a Tile based game and uses a Multi-dimensional array to save the map of the current level. The current array looks something like the code below for the first level:

var map = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
           [1, 3, 0, 0, 0, 0, 2, 4, 0, 1],
           [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]];

Just so you know:

0 = Floor
1 = Wall
2 = Block
3 = Player
4 = Goal

The map when rendered looks like the following:

enter image description here

So basically what i would like to do is create a Map Creator for the user.

I would like every block in the image above to be click-able and when the user clicks on the square it cycles through the possible blocks in the game (e.g 0,1,2,3 or 4).

I have been trying to get this to work using the KineticJS library but with no luck.

Could anyone give me any advice on what to use or any information on how i could do this using KineticJS.

Thanks

Glen Robson
  • 908
  • 2
  • 19
  • 42

1 Answers1

3

I can't comment on the KineticJS aspect of it, but couldn't you do something like: determine the click coordinates relative to the canvas, divide that by the size of your blocks (and round down) for each axis, and then you'd know which block was clicked. Edit that value in your map and redraw that block on the canvas?

This is what I mean:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Maker</title>
<style>
#can{display:block; background-color:#666;}
</style>
</head>

<body onload="init();">
<canvas id="can"></canvas>
</body>
<script>
var blocksize=30;
var map=[[1,1,1,1,1,1,1,1,1,1],[1,3,0,0,0,0,2,4,0,1],[1,1,1,1,1,1,1,1,1,1]];
var can=document.getElementById('can')
if(can){ctx=can.getContext('2d');}
function init(){
    can.width=map[0].length*blocksize; //adjusts canvas size to fit map
    can.height=map.length*blocksize;
    for(y=0;y<map.length;y++){
        for(x=0;x<map[y].length;x++){
            draw(y,x);
        }
    }
    can.addEventListener('click',builder);
}

function builder(e){
    if (e == null) {e = window.event;}
    x = e.clientX; //where the click was
    y = e.clientY;
    offsetX = ExtractNumber(can.offsetLeft)-window.scrollX;//where the canvas is
    offsetY = ExtractNumber(can.offsetTop)-window.scrollY;
    x_grid=Math.floor((x-offsetX)/blocksize); //which block in the canvas was clicked
    y_grid=Math.floor((y-offsetY)/blocksize);
    map[y_grid][x_grid]++;
    if(map[y_grid][x_grid]>4){map[y_grid][x_grid]=0;}
    draw(y_grid,x_grid);
}

function draw(y,x){
    kind=map[y][x];
    switch(kind){
        case 0:
            ctx.drawImage(floorimg,x*blocksize,y*blocksize);
        break;
        case 1:
            ctx.drawImage(wallimg,x*blocksize,y*blocksize);
        break;
        case 2:
            ctx.drawImage(blockimg,x*blocksize,y*blocksize);
        break;
        case 3:
            ctx.drawImage(playerimg,x*blocksize,y*blocksize);
        break;
        case 4:
            ctx.drawImage(goalimg,x*blocksize,y*blocksize);
        break;
    }
}

function ExtractNumber(value){
    var n = parseInt(value);
    return n == null || isNaN(n) ? 0 : n;
}
var floorimg=new Image();
floorimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE5JREFUeNpiNDU1ZaANYAHiadOmEaM0KysLSOaCSYJg8rRpTAw0A6NGjxo9avQIMJqRdiUfDV3NQlI5SVIJPJpCRo0eNXrU6EFaqAIEGABIow4bXRyDLQAAAABJRU5ErkJggg==';
var wallimg=new Image();
wallimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpirK+vZ8AGGhsbcUkRqYaJgWZg1Gj6AUZIFFOeHjDVjEbjcEoho2XIaAoZLUNGU8hoGTKaQmgAAAIMAJeMK58/yjg2AAAAAElFTkSuQmCC';
var blockimg=new Image();
blockimg.src='data:image/png;base64,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';
var playerimg=new Image();
playerimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATdJREFUeNpiNDU1ZaANYAHiadOm4ZLGZfGi+fPxmzt52jQWPNJAc/8rKSGLMN679//+ThBD0Z2g6UwMNAM0NJqFVA3AoCAmrAkbDQxcUiOQgNGQhGHc+QpTKi5RjMgEw4LVXKyGQgBE6my5GFwNkF1VW9vc0MDMzIwvGvGbi2wB0EQ4+8mTJ4kpKTRJIRDXFJWU4DSaSCdjOhzCffP2bVxiIk3SNZqzaJxlsrKyqGjiZFhhR2NX58JcjRwJZANIEQ0MiSFS8iGnRXSjgUUBmjR+g5BTG0Tj6dOnqexqiLknTpzAFyBEOhyteAKSJ0+eRCueWLCWkJCSE2umh1uM7ALkcCBQXkPKX6xFM1ZTyKllMGt0SC1BjAUk142wxoIpQdOHX2MBGJmMGKUKpLFATFgz0q45CRBgAHQ6gQd/qFgwAAAAAElFTkSuQmCC';
var goalimg=new Image();
goalimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFtJREFUeNpilJSUZKANYAFiGRkZqpv75MkTJgaagWFv9BMwGA2QUaNHttEsmPmCYMbBJYVWzNHR1XgKWIh7iS+BR1PIqNEjIaPjAaQ2V0bDGktYk9S6IB4ABBgADi4U6URvDncAAAAASUVORK5CYII=';
</script>
</html>
Robot Woods
  • 5,677
  • 2
  • 21
  • 30
  • Wow that looks great at first glance... Ill have a quick play around with it and see if i can get it to save within a XML file. – Glen Robson Aug 07 '12 at 14:39
  • meaning you'd want to export the `map` as XML? would you be sending it to some web service? I think JSON might be better for you given the structure: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify – Robot Woods Aug 07 '12 at 14:42
  • also, as written it doesn't dynamically resize if you were to add another row or column to the map, but that'd be a quick fix in the `init` function to reset the css and height/width of the canvas – Robot Woods Aug 07 '12 at 14:44
  • Yeah i am working on the size of the map right now. Ill post my result once i am done. I am currently using the following code to input my map how would i reverse this so it would save the map array to a XML file: req = new XMLHttpRequest(); req.open("GET", "/Scripts/TileMaps.xml", false); req.send(); xmlDoc = req.responseXML; map = JSON.parse(xmlDoc.getElementsByTagName('map') [level].firstChild.nodeValue); – Glen Robson Aug 07 '12 at 14:50
  • I think you'll need some server side script that will accept the JSON (also, am I interpreting your code correctly that you have JSON within XML?) and write it to some file. You'd probably also ultimately change the request as well so that you could ask for different files (such as sending a user, or map ID, that would then return the proper layout) – Robot Woods Aug 07 '12 at 14:58
  • To be honest im not exactly 100% sure what im doing with JSON. The code i provided above i received from someone online helping me out. Once i get this working how i want it ill start a new Question asking about the JSON stuff. Ill also post my results here in case you would like to see them. – Glen Robson Aug 07 '12 at 15:06
  • Hi Robot, I have sorted out most of my code to create the map with help from you. My problem now is that i would like to save the newly created map (array) to a XML file. Would you be able to help me with this? I have started another thread if you would like to take a look: http://stackoverflow.com/questions/11861527/saving-a-multidimensional-array-into-an-xml-using-javascript – Glen Robson Aug 08 '12 at 13:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/15060/discussion-between-robot-woods-and-glen-robson) – Robot Woods Aug 08 '12 at 13:37
  • Hi Robot, The code you supplied me with before works great apart from one thing. IF the map is large (bigger than the height of the screen). Then if the user scrolls down and tries to click on one of the blocks it does not change the right block. Im guessing this is because it is reletive to the top left of the broswer window. Is there anyway to fix this? – Glen Robson Aug 09 '12 at 15:25
  • I cannot work on it today, but there is a `scrollX` property (google it) that you could look at, and add that the the Y parameter somewhere. give that a try, and I'll look myself in about 9 hours – Robot Woods Aug 09 '12 at 15:43
  • Ahh ok ill have a look tomorrow when i get some time Thanks. – Glen Robson Aug 09 '12 at 16:01
  • Hi, i tried looking at scrolly but i couldnt find much information on it. I tried to use the following code to get the number of pixels that i had scrolled down so i could take it off the code where it filds the click area but the code didnt seem to work: var scrolledDown = window.scrollY; Could you give me any advice? – Glen Robson Aug 10 '12 at 09:04
  • look at the builder function now, the `offsetX` and `offsetY` calculations use `scrollX` and `scrollY` – Robot Woods Aug 10 '12 at 13:58
  • Im getting the error "Microsoft JScript runtime error: Unable to get value of the property 'NaN': object is null or undefined" when i add that code? – Glen Robson Aug 10 '12 at 14:17
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/15180/discussion-between-robot-woods-and-glen-robson) – Robot Woods Aug 10 '12 at 15:15