二维数组位图阅读器不支持 p5.js 中同一行中的重复颜色

问题描述 投票:0回答:1

使用 p5.js,我构建了一个函数,该函数读取二维数组,并使用与每个位置中

colors
对象的字符串对应的颜色将其绘制到画布上。这是我的代码:

let colors = {
  r: "red",
  g: "green",
  b: "blue",
  y: "yellow",
  o: "orange",
  bl: "black",
  w: "white",
  t: "transparent",
  i: "indigo",
  v: "violet",
  c: "cyan",
};

let myMap = [
  ["r", "o", "y", "g"],
  ["b", "i", "o", "v"],
  ["o", "y", "g", "b"],
  ["i", "v", "r", "o"],
];

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(0);
  rectMode(CENTER)
  readMap(myMap, 50, 50, 150, 150);
}

function readMap(bitmap, x = 0, y = 0, w = null, h = null) {
  for (let block of bitmap) {
    for (let block2 of block) {
      fill(colors[block2]);
      noStroke();
      push();
      translate(x, y);
      // If a width and height are specified, render it as a rectangle with that size.
      if (w && h) scale(w/width, h/height);
      rect(
        block.indexOf(block2) * (width / block.length),
        bitmap.indexOf(block) * (height / bitmap.length),
        width / block.length,
        height / bitmap.length
      );
      pop();
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

如果你运行这段代码,它工作得很好。它绘制了正确大小和颜色的矩形,但是当一行中有两个或多个相同颜色时 -

let myMap = [
  // ...
  ["r", "o", "v", "v"],
];

—第一个重复项被正确渲染,但第二个及其后面的所有重复项仅被渲染为黑色。如果有人能提供帮助,那将是一个救星。请注意,我对 JavaScript 还比较陌生。

javascript multidimensional-array bitmap p5.js
1个回答
0
投票

问题是,当连续有多种颜色时,

indexOf
总是找到第一个 - 这是一个线性搜索,从数组的第一个元素到最后一个元素逐个索引,直到找到匹配项。

解决方法是在循环中使用实际的计数器索引,可以使用传统的 C 风格

for
循环,
forEach
,或使用手动索引变量:

const colors = {
  r: "red",
  g: "green",
  b: "blue",
  y: "yellow",
  o: "orange",
  bl: "black",
  w: "white",
  t: "transparent",
  i: "indigo",
  v: "violet",
  c: "cyan",
};

const map = [
  ["r", "o", "r", "g"],
  ["b", "i", "o", "v"],
  ["o", "y", "g", "b"],
  ["i", "v", "r", "o"],
];

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(0);
  rectMode(CENTER);
  drawMap(map, 50, 50, 150, 150);
}

function drawMap(bitmap, x = 0, y = 0, w, h) {
  bitmap.forEach((row, i) => {
    row.forEach((block, j) => {
      push();
      fill(colors[block]);
      noStroke();
      translate(x, y);

      // If a width and height are specified, render it as a rectangle with that size.
      if (w && h) {
        scale(w / width, h / height);
      }

      rect(
        j * (width / bitmap.length),
        i * (height / row.length),
        width / row.length,
        height / bitmap.length
      );
      pop();
    });
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.