js / canvas 填充地图

js / canvas populate map

我正在学习 js,canvas.I 想用小图块填充地图(例如 20px x 20px)到目前为止,我已经用字符填充了它,但图块会更好。我是否必须获得一组小图像或是否有绘制图块的方法? 我想我可以在主 canvas 中创建很多 20x20 canvases,但我想这远非最佳。

这就是我目前所知道的。

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();

顺便说一句,最终,我想用它制作一个简单的角色扮演游戏(一个用键控制的角色在地图上移动),所以请就地图上的最佳方法提出建议。谢谢。

一个解决方案是创建一组函数来绘制图块,每个图块类型都有一个函数。然后创建一个查找对象来保存所有这些功能。在填充地图的循环中,从查找对象中找到所需的函数并使用找到的函数绘制图块。

例如,以下代码将瓦片类型 0 绘制为浅红色正方形,将瓦片类型 1 绘制为浅绿色正方形...

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();

另一种解决方案是为每种图块类型创建单独的图像(例如 png、svg 等)。然后创建一个查找对象来保存这些图像。在填充地图的循环中,从查找对象中找到所需的图像并使用 ctx->drawImage() 函数绘制图块。

以下是在游戏中绘制图块的方法 canvas。

从像这样的拼贴 spritesheet 图像开始:

左侧(草)方块由 mapArray 值 0 表示。右侧(粘土)方块由值 1 表示。

然后使用 drawImage.

的扩展形式在游戏 canvas 的任意位置绘制任一方块
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

);

这是示例代码和演示:

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>