HTML5 Canvas [56]
NOTE
The row, column referencing might seem slightly confusing because row is the y direction and column is the x direction. We do this because our tiles are organized into a two-dimensional array. The row is always the first subscript when accessing a 2D array.
for (var rowCtr=0;rowCtr var tileId = tileMap[rowCtr][colCtr]+mapIndexOffset; var sourceX = Math.floor(tileId % 8) *32; var sourceY = Math.floor(tileId / 8) *32; context.drawImage(tileSheet, sourceX, sourceY,32,32,colCtr*32,rowCtr*32,32,32); } } We use the mapRows and the mapCols variables to loop through the data and to paint it to the canvas. This makes it relatively simple to modify the height and width of the tile map without having to find the hardcoded values in the code. We could have also done this with other values such as the tile width and height, as well as the number of tiles per row in the tile sheet (8). The sourceX and sourceY values for the tile to copy are found in the same way as in the previous examples. This time, though, we find the tileId using the [rowCtr][colCtr] two-dimensional lookup, and then adding the mapIndexOffset. The offset is a negative number (-1), so this effectively subtracts 1 from each tile map value, resulting in 0-relative map values that are easier to work with. Example 4-10 shows this concept in action, and Figure 4-10 illustrates the results. Example 4-10. Rotation, animation, and movement var tileSheet = new Image(); tileSheet.addEventListener('load', eventSheetLoaded , false); tileSheet.src = "tanks_sheet.png"; var mapIndexOffset = -1; var mapRows = 10; var mapCols = 10; var tileMap = [ [32,31,31,31,1,31,31,31,31,32] , [1,1,1,1,1,1,1,1,1,1] , [32,1,26,1,26,1,26,1,1,32] , [32,26,1,1,26,1,1,26,1,32] , [32,1,1,1,26,26,1,26,1,32] , [32,1,1,26,1,1,1,26,1,32] , [32,1,1,1,1,1,1,26,1,32] , [1,1,26,1,26,1,26,1,1,1] , [32,1,1,1,1,1,1,1,1,32] , [32,31,31,31,1,31,31,31,31,32] ]; function eventSheetLoaded() { drawScreen() } function drawScreen() { for (var rowCtr=0;rowCtr var tileId = tileMap[rowCtr][colCtr]+mapIndexOffset; var sourceX = Math.floor(tileId % 8) *32; var sourceY = Math.floor(tileId / 8) *32; context.drawImage(tileSheet, sourceX, sourceY,32,32,colCtr*32,rowCtr*32,32,32); } } } Figure 4-10. The tile map painted on the canvas Next, we are going to leave the world of tile-based Canvas development (see Chapter 9 for an example of a small game developed with these principles). The final section of this chapter discusses building our own simple tile map editor. But before we get there, let’s look at panning around and zooming in and out of an image. Zooming and Panning an Image In this section, we will examine some methods to zoom and pan an image on the canvas. The image we are going to use is from a recent vacation to Central California. It is a large .jpg file, measuring 3648×2736. Obviously, this is far too large to view in a single canvas, so we will build a simple application allowing us to zoom and pan the image on our 500×500 canvas. Figure 4-11 is a scaled-down version of this image. Figure 4-11. A scaled-down version of the image we will zoom and pan Creating a Window for the Image var windowWidth = 500; var windowHeight = 500; We will also create two variables to define the current top-left corner for the window. When we move on to the panning examples, we will modify these values to redraw the image based on this location: var windowX = 0; var windowY = 0; Drawing the Image Window context.drawImage(photo, windowX, windowY, windowWidth, windowHeight,
The first thing we are going to do is create a logical window, the size of the canvas, where our image will reside. We will use the following two variables to control the dimensions of this window:
To draw the image window, we will simply modify the standard context.drawImage() function call using the values in the four variables we just defined: