HTML5 Canvas - 用于将元素放置在网格中的循环

时间:2015-11-02 18:29:12

标签: javascript html5 canvas grid iteration

我正在HTML5画布中构建一个简单的级别放置脚本,我实际上无法放下每个元素。我已经编写了一个创建网格的for循环,然后我试图创建一个新的循环来迭代我的级别中的每个语句'用于为每个图像设置位置的数组。我之前没有用Canvas做过很多事情;因此,我不确定在放置这些图像方面我做错了什么;我在jQuery中编写了一些非常类似的东西,它运行得很好 - 实际上,我复制并粘贴了代码,但它似乎并不适用于Canvas。任何帮助将不胜感激!

这是代码的片段;原谅过度评论,当我无法理解为什么某些东西不起作用时,这只是我要做的事情。它就像一个内联橡皮鸭。

var $levelArray = [
  [0, 0, 0, "blue", "blue"], 
  [0, "gray", 0, 0, 0], 
  ["blue", "blue", "green", 0, "blue"], 
  ["blue", 0, "yellow", 0, 0], 
  [0, 0, 0, "gray", 0], 
  ["red", 0, 0, 0, 0]];

var border = 5, // set grid details
    spaceWidth = 80, 
    spaceAmount = 5;

    // create a tiled image
function makeTile(imageUrl, horizontalPosition, verticalPosition) {
  var tile = new Image();

  tile.onload = function() {
    context.drawImage(tile, horizontalPosition, verticalPosition);
  }
  tile.src = imageUrl;
}

    // place the image tiles on the board
for (var i=0; i < ($levelArray.length - 1); i++) {
  var row = $levelArray[i]; // set each row's iterative position
  var rowHeight = 5;

  for (var j=0; j < row[j].length; j++) {
    var rowPosition = 5; // set the left margin of each element

    if (row[j] == 0) {
      rowPosition += (spaceWidth + 5); // if an element does not exist, jump forwards to the next space
    } else {
      //if one DOES exist, place an image in this space
      makeTile("http://lorempixel.com/80/80", rowPosition, rowHeight);
      rowPosition += (spaceWidth + 5); // then move to the next space
    };
  };
  rowHeight += (spaceWidth + 5); // once a row is complete, drop to the next row's positions
};

我在这里的codepen中有这个:http://codepen.io/sarsparillo/pen/vNrWQG

我不确定为什么它一次只加载一个图像并将其放在我网格上的0,0空间中;在jQuery中使用非常相似的代码(当前代码,这是非常遍布整个地方,有点不洁,在这里 - http://codepen.io/sarsparillo/pen/GpdjYY)将元素放在正确的位置就好了。

更多,当我向那些for循环添加一个console.log语句时,老实说,我无法解决它从何处获取数据。就像,一次迭代给了我绿绿黄&#39;作为行[j]中的项目,另一个&#39;蓝灰色蓝色&#39; - Canvas在迭代数组时做了一些绝对奇怪的事吗?我看不出它是怎么回事,因为这只是Javascript,但是......?

有没有人知道为什么会这样,或者有关如何解决此问题的任何提示?理论上,它应该只是将空间宽度+边距宽度添加到每个方形的起点,所以我不确定为什么它只是......不是。

1 个答案:

答案 0 :(得分:2)

jsFiddle:https://jsfiddle.net/CanvasCode/4gr9apqm/

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var border = 5, // set grid details
    spaceWidth = 80,
    spaceAmount = 5;

var $levelArray = [
    ["blue", 0, 0, "blue", "blue"],
    [0, "gray", 0, 0, 0],
    ["blue", "blue", "green", 0, "blue"],
    ["blue", 0, "yellow", 0, 0],
    [0, 0, 0, "gray", 0],
    ["red", 0, 0, 0, 0]
];

canvas.width = (spaceWidth * spaceAmount) + (5 * spaceAmount) + 5; // and here's the canvas size
canvas.height = (spaceWidth * spaceAmount) + (5 * spaceAmount) + 5;

// make a rounded corner square; using a sizing hack to make sure that strokes don't effect the full size of the item
function square(originX, originY, size, corner, fill) {
    var startFromX = originX + (corner / 2);
    var startFromY = originY + (corner / 2);
    var extentsX = startFromX + (size - corner);
    var extentsY = startFromY + (size - corner);
    context.lineJoin = "round";
    context.lineWidth = corner;
    context.fillStyle = "#513574";
    context.strokeStyle = fill;

    context.beginPath();
    context.moveTo(startFromX, startFromY);
    context.lineTo(startFromX, extentsY);
    context.lineTo(extentsX, extentsY);
    context.lineTo(extentsX, startFromY);
    context.closePath();
    context.stroke();
    context.fill();
}

// build a grid of said squares
function squareGrid(spacing, size, corner, color, amount) {
    for (var x = 0; x < amount; x++) {
        // build rows
        for (var y = 0; y < amount; y++) {
            // build column spacing in each row
            square(5 + (size * x) + (spacing * x), 5 + (size * y) + (spacing * y), size, corner, color);
            // build each square
        }
    };
};

// actually parse the arguments for said square
squareGrid(border, spaceWidth, (border * 2), "#f13574", spaceAmount);

// create a tiled image
function makeTile(tile, horizontalPosition, verticalPosition) {
    switch (tile) {
        case "blue":
            context.fillStyle = "#00F";
            context.fillRect(horizontalPosition, verticalPosition, 80, 80);
            break;
        case "green":
            context.fillStyle = "#0F0";
            context.fillRect(horizontalPosition, verticalPosition, 80, 80);
            break;
        case "red":
            context.fillStyle = "#F00";
            context.fillRect(horizontalPosition, verticalPosition, 80, 80);
            break;
        case "gray":
            context.fillStyle = "#999";
            context.fillRect(horizontalPosition, verticalPosition, 80, 80);
            break;
        case "yellow":
            context.fillStyle = "#FF0";
            context.fillRect(horizontalPosition, verticalPosition, 80, 80);
            break;
    }
};

var gapHeight = 5;
var gapWidth = 5;

for (var y = 0; y < $levelArray.length - 1; y++) {
    var row = $levelArray[y];

    for (var x = 0; x < row.length; x++) {
        var newXPos = (gapWidth * (x + 1)) + (80 * x);
        var newYPos = (gapHeight * (y + 1)) + (80 * y)

        makeTile($levelArray[y][x], newXPos, newYPos);
    }
}

我所有改变的基本上是你如何访问2D阵列和位置计算。基本上,您访问的第一件事是您的Y位置,然后从Y位置查看该行上的所有块。所以我们首先找到&#34;在我的情况下&#34; blue, 0, 0, blue, blue。因此所有这些都将具有y位置0,然后它将从0,80,160等开始。但是因为你想要在块之间存在间隙,你还必须通过当时的x和y值来加倍间隙:)