HTML5画布-用于在网格中放置元素的循环

HTML5 Canvas - For loop to place elements in grid

本文关键字:元素 循环 网格 画布 用于 HTML5      更新时间:2023-09-26

我正在HTML5画布中构建一个简单的级别放置脚本,在实际放置每个元素时遇到了问题。我已经编写了一个创建网格的for循环,然后我试图创建一个新的循环,它迭代我的"level"数组中的每个语句,为每个图像设置位置。我以前没有用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
};

我把这个放在代码笔里:http://codepen.io/sarsparillo/pen/vNrWQG

我不知道为什么它一次只加载一个图像,并将其放在我网格上的0,0空间中;在jQuery中使用非常相似的代码(当前的代码到处都是,有点不干净,在这里-http://codepen.io/sarsparillo/pen/GpdjYY)把元素放在正确的位置很好。

此外,当我在for循环中添加console.log语句时,我真的不知道它是从哪里获取数据的。比如,一次迭代给了我"绿-绿-黄"作为第[j]行中的项目,另一次迭代是"蓝-灰-蓝"——Canvas在迭代数组时会做一些非常奇怪的事情吗?我看不出它怎么可能,因为这只是Javascript,但是。。。?

有人知道为什么会发生这种情况吗,或者有什么关于我如何解决的建议吗?理论上,它应该只是在每个"正方形"的起点加上空格宽度+边距宽度,所以我不确定为什么它只是。。。不是。

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方向看那一行上的所有块。因此,我们首先找到"在我的情况下"blue, 0, 0, blue, blue。所以所有这些块的y位置都是0,然后从0、80、160等等。但是,因为你想在块之间有一个间隙,所以你还必须将间隙乘以当时的x和y值:)