HTML and CSS Reference
For this, I introduce the concept of a view-rect . The view-rect is a rectangle that defines what part of the map,
in world coordinates, is currently visible in canvas coordinates. To put it differently, you use the view-rect to map
world-space to view-space:
var tPKT = gMap.getTilePacket(tID);
//test if gMap tile is within our world bounds
var worldX = Math.floor(tileIDX % gMap.numXTiles) * gMap.tileSize.x;
var worldY = Math.floor(tileIDX / gMap.numXTiles) * gMap.tileSize.y;
if ((worldX + gMap.tileSize.x) < gMap.viewRect.x || (worldY + gMap.tileSize.y) < gMap.
viewRect.y || worldX > gMap.viewRect.x + gMap.viewRect.w || worldY > gMap.viewRect.y + gMap.
//adjust all the visible tiles to draw at canvas origin.
worldX -= gMap.viewRect.x;
worldY -= gMap.viewRect.y;
// Nine arguments: the element, source (x,y) coordinates, source width and
// height (for cropping), destination (x,y) coordinates, and destination width
// and height (resize).
ctx.drawImage(tPKT.img, tPKT.px, tPKT.py, gMap.tileSize.x, gMap.tileSize.y, worldX,
worldY, gMap.tileSize.x, gMap.tileSize.y);
An added benefit of the view-rect is that it allows you to do visibility culling on your tiles, such that you render only
the tiles that are visible to the user rather than drawing every tile in the map, regardless of whether it's on-screen or not.
To use the view-rect properly, you instruct the update function of your simple example to modify the view-rect,
based on the position of the player in the world:
//....other drawing functions here
//make sure the player is at the center of the screen
gMap.viewRect.x = (pPos.x - ( canvas_width / 2 ) );
gMap.viewRect.y = (pPos.y - ( canvas_height / 2 ));
gMap.viewRect.w = canvas_width;
gMap.viewRect.h = canvas_height;
Fast Canvas Rendering with Precaching
One of the big problems with the forward rendering method for two-dimensional maps is that it easily becomes a
performance bottleneck once the number of layers, tiles, and overlapping tiles increases. Each draw call can have
subsequent overhead associated with it, and if you're not careful, you can end up redrawing massive portions of your
screen, thus wasting cycles on pixels that will never be visible to the user.
For instance, if each tile area on the screen had four or five image tiles placed on it, your draw count per frame
will, in effect, have quadrupled with the new map (see Figure 17-3 ).