使用 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 还比较陌生。
问题是,当连续有多种颜色时,
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>