js / canvas populate map

ε祈祈猫儿з 提交于 2019-12-13 06:33:15

问题


I'm learning js and canvas.I'd like to populate a map with small tiles (eg. 20px by 20px) So far I've kind of populated it with characters but tiles would be better. Do I have to get a set of small images or is there a way of drawing the tiles? I guess I could create a lot of 20x20 canvases inside the main canvas but I guess that would be far from the optimal.

This is what I've got so far.

var mapArray = [
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
];

function popMap() {
    var canvas = document.getElementById('playground');
    var ctx = canvas.getContext('2d');

    ctx.font="18px Georgia";
    ctx.fillStyle="white";
    for (i=0;i<mapArray.length;i++) {
        for (j=0;j<mapArray.length;j++) {
            ctx.fillText(mapArray[i][j], i*20, j*20);
        }
    }
}

popMap();

By the way, eventually, I'd like to make a simple rpg game (a character controlled with keys moves over the map) out of it so please advise on the best approach on the map. Thank you.


回答1:


Here's how to draw tiles onto your game canvas.

Start with a tile spritesheet image like this:

The left (grass) tile is represented by the mapArray value 0. The right (clay) tile is represented by the value 1.

Then draw either tile at any position on the game canvas using the extended form of drawImage.

drawImage(

    // use the spritesheet image as the image source
    spritesheetImage, 

    // clip a portion from the spritesheet image
    clipAtX, clipAtY, clipWidth, clipHeight,

    // draw the clipped portion to the canvas
    canvasX, canvasY, scaledWidth, scaledHeight

);

Here's example code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var mapArray = [
  [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
];

var tw=20;
var th=20;
var spritesheet=new Image();
spritesheet.onload=function(){
  canvas.width=tw*mapArray[0].length;
  canvas.height=th*mapArray.length;
  popMap();
}
spritesheet.src='https://dl.dropboxusercontent.com/u/139992952/multple/gametiles.png';

function popMap() {
  for (i=0;i<mapArray.length;i++) {
    for (j=0;j<mapArray[i].length;j++){
      var tile=mapArray[i][j];
      ctx.drawImage(spritesheet,
                    tile*20,0,tw,th,
                    j*20,i*20,tw,th

                   );
    }
  }
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=500 height=500></canvas>



回答2:


One solution is to create a set of functions to draw the tiles, with one function for each tile type. Then create a lookup object to hold all these function. In your loop to populate the map, find the desired function from the lookup object and draw the tile using the found function.

For example, the following code draws tile type 0 as a light red square and tile type 1 as a light green square...

var mapArray = [
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
];

function fillTile0(ctx, x, y, width, height) {
    ctx.fillStyle = "#FF7777"
    ctx.fillRect(x, y, width, height);
}

function fillTile1(ctx, x, y, width, height) {
    ctx.fillStyle = "#77FF77"
    ctx.fillRect(x, y, width, height);
}

var fillTileFunctions = {
    "0": fillTile0,
    "1": fillTile1
};

function popMap() {
    var canvas = document.getElementById('playground');
    var ctx = canvas.getContext('2d');
    for (i=0;i<mapArray.length;i++) {
        for (j=0;j<mapArray[i].length;j++) {
            var fillTile = fillTileFunctions[mapArray[i][j]];
            if (fillTile) {
                fillTile(ctx, i*20, j*20, 20, 20);
            }
        }
    }
}

popMap();

Another solution would be to create a separate image (e.g. png, svg, etc) for each tile type. Then create a lookup object to hold these images. In your loop to populate the map, find the desired image from the lookup object and draw the tile using ctx->drawImage() function.



来源:https://stackoverflow.com/questions/33713487/js-canvas-populate-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!