Question

The basis for the code is from John E. Graham's blog http://johnegraham2.com/blog/2010/09/25/project-javascript-2d-tile-engine-with-html5-canvas-part-4-using-zones-for-further-optimization/

It works perfectly for drawing a screen's worth of tiles, but I cannot for the life of me figure out how to adjust it 1 row/column at a time based on pressing up, down, left, or right keys.

Here is an example with the transparency to help visualize the zones http://simplehotkey.com/Javascript/canvas.html (loading positions of 1,188 tiles but only draws a couple hundred to fill the screen) I had it loading an array with 70,000 entries and it was still quick because it's only drawing whats on the screen, but cannot figure out how to slide everything based on input...

I've come up with a couple ideas and am not sure what's the best way.

One screen worth of tiles is shown here:

 tilesArray = [ 
              0,0,0,0,0,0,0,1,2,9,6,0,0,7,0,0,1,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,9,0,
              0,9,9,9,9,9,9,0,7,2,0,0,0,0,0,1,2,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,9,0,7,2,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,
              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
              ];

Where 0 is a wall tile (around perimeter), 9 a floor tile, 7 a door and a couple other random tiles.

That is exactly what is loaded to the screen, but I cannot figure out how to shift everything 1 tile in either direction based on input, up, down, left, right.

The one idea I'm leaning towards now, is just to use that array above as the basis for rendering, and somehow feeding the new values into it based on keyboard input, from another array. Maybe slicing from another, much larger array (holding all the tiles for the entire level) and using that slice to populate the array that's actually rendered???

That's replacing every tile every frame though...

for getting player input I was using:

//Key listener 
document.onkeydown = function(e){
e = e?e:window.event;
console.log(e.keyCode + "Down");
switch (e.keyCode){
    case 38:
    //UP KEY
    Game.inputReaction('up');   
    //Game.moveDir('up');
    break;
    case 40:
    //DOWN KEY  
    //Game.inputReaction(40);
    //Game.moveDir('down');
    break;
    case 37:
    //Left Key  
    //Game.inputReaction(37);
    break;
    }
}

The other alternative is to try to adjust the tiles already on the screen and add new tiles but this engine isn't using global variables so I'm not sure how to affect the tile engine programatically based on input....like I can add another method (inputReaction(num)) and trigger some actions from my keyboard input (console.log()) but I can't access the other methods actually drawing the tiles. Or maybe I have to make a copy of the object, change it and return it? but it's pretty complex.

I think it might be easier to adjust the array values that are being fed into the "engine" (array above) rather than changing around how the engine is calculating what's being drawn. Can you confirm this?

Was it helpful?

Solution

Add a camera abstraction that you can move around on the map, then shift the drawing positions according to the camera position. When the camera moves south 10px, all tiles move north 10px, same with east and west. Since you only draw the tiles that are visible, there won't be much of a performance loss.

The renderer looks at the camera to figure out what needs to be drawn and you can expose the camera object to the outside to manipulate it. That way you only need to change the camera position to change what is shown on the screen.

I did this in a proof of concept tiling engine a year ago and I was able to smoothly scroll and scale huge tilemaps.

If you start changing the array itself, your performance will suffer and you won't be able to scroll smoothly since you can only go in steps of one tile and not one pixel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top