canvas 为什么不绘制多张图片
Why doesn't canvas draw multiple images
我有一个问题,canvas 只画了一张我让他画的图像。我已经看过代码并检查了所有内容,一切都很好,但 drawImage 或 image.onload 函数没有。 idk 为什么它这样做导致它应该在每次调用时绘制图像但它没有。它只是绘制了 1 次然后就完成了。也许我做错了什么,但在我看到它应该工作之后;
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
this.bomb = false
this.revealed = false
}
show() {
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width
const h = canvas.height
const ColumnRow = w / 15
const cells = []
const bombs = 5
const bombPosition = []
let checked = true
const arr = [
[-1, 1],
[0, 1],
[1, 1],
[1, 0],
[1, -1],
[0, -1],
[-1, -1],
[-1, 0]
]
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow))
}
}
}
function drawCells() {
for (let c of cells) {
c.show()
}
}
function numOfBombs() {
for (let i = 0; i < bombs; i++) {
if (bombPosition.length < bombs) {
let randomX = Math.floor(Math.random() * w / ColumnRow) * ColumnRow
let randomY = Math.floor(Math.random() * h / ColumnRow) * ColumnRow
for (let j = 0; j < bombPosition.length; j++) {
if (bombPosition[j].x == randomX && bombPosition[j].y == randomY) {
numOfBombs()
}
}
bombPosition.push({ x: randomX, y: randomY });
} else {
break;
}
}
}
function drawBomb() {
let img = new Image();
img.onload = function () {
for (let i = 0; i < bombPosition.length; i++) {
ctx.drawImage(img, bombPosition[i].x, bombPosition[i].y, ColumnRow, ColumnRow)
}
};
img.src = "https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/mine.png";
//set cell bomb to true
for (let i = 0; i < cells.length; i++) {
for (let j = 0; j < bombPosition.length; j++) {
if (cells[i].x == bombPosition[j].x && cells[i].y == bombPosition[j].y)
cells[i].bomb = true
}
}
}
function drawNumbers() {
for (let i = 0; i < cells.length; i++) {
let totalBombs = 0;
if (!cells[i].bomb) {
for (let j = 0; j < arr.length; j++) {
tmpx = cells[i].x + arr[j][0] * ColumnRow // 0 x
tmpy = cells[i].y + arr[j][1] * ColumnRow // 1 y
// console.log(tmpx);
for (let k = 0; k < cells.length; k++) {
if (cells[k].x == tmpx && cells[k].y == tmpy) {
if (cells[k].bomb) {
totalBombs++;
}
break;
}
}
}
}
if (totalBombs > 0) {
test(totalBombs, cells[i].x, cells[i].y)
}
}
}
let images = []
for (let i = 1; i < 9; i++) {
let img = new Image()
images.push(img)
}
function test(totalBombs, x, y) {
images[totalBombs].onload = function () {
ctx.drawImage(images[totalBombs], x, y, ColumnRow, ColumnRow)
}
images[totalBombs].src = `https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/number_${totalBombs}.png`
}
function draw() {
drawCells()
if (checked) {
drawBomb()
drawNumbers()
// coverCell()
checked = false
}
requestAnimationFrame(draw)
}
function update() {
setup()
numOfBombs()
}
update()
draw()
// bombTest()
<canvas id="myCanvas" width="600" height="600"></canvas>
问题是您正在尝试加载图像并同时绘制它们。因此,当图像仍在加载时,您正在为每个数字替换 onload
函数。这是 Promise
的用武之地:
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
this.bomb = false
this.revealed = false
}
show() {
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width
const h = canvas.height
const ColumnRow = w / 15
const cells = []
const bombs = 5
const bombPosition = []
let checked = true
const arr = [
[-1, 1],
[0, 1],
[1, 1],
[1, 0],
[1, -1],
[0, -1],
[-1, -1],
[-1, 0]
]
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow))
}
}
}
function drawCells() {
for (let c of cells) {
c.show()
}
}
function numOfBombs() {
for (let i = 0; i < bombs; i++) {
if (bombPosition.length < bombs) {
let randomX = Math.floor(Math.random() * w / ColumnRow) * ColumnRow
let randomY = Math.floor(Math.random() * h / ColumnRow) * ColumnRow
for (let j = 0; j < bombPosition.length; j++) {
if (bombPosition[j].x == randomX && bombPosition[j].y == randomY) {
numOfBombs()
}
}
bombPosition.push({ x: randomX, y: randomY });
} else {
break;
}
}
}
function drawBomb() {
let img = new Image();
img.onload = function () {
for (let i = 0; i < bombPosition.length; i++) {
ctx.drawImage(img, bombPosition[i].x, bombPosition[i].y, ColumnRow, ColumnRow)
}
};
img.src = "https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/mine.png";
//set cell bomb to true
for (let i = 0; i < cells.length; i++) {
for (let j = 0; j < bombPosition.length; j++) {
if (cells[i].x == bombPosition[j].x && cells[i].y == bombPosition[j].y)
cells[i].bomb = true
}
}
}
function drawNumbers() {
for (let i = 0; i < cells.length; i++) {
let totalBombs = 0;
if (!cells[i].bomb) {
for (let j = 0; j < arr.length; j++) {
tmpx = cells[i].x + arr[j][0] * ColumnRow // 0 x
tmpy = cells[i].y + arr[j][1] * ColumnRow // 1 y
// console.log(tmpx);
for (let k = 0; k < cells.length; k++) {
if (cells[k].x == tmpx && cells[k].y == tmpy) {
if (cells[k].bomb) {
totalBombs++;
}
break;
}
}
}
}
if (totalBombs > 0) {
test(totalBombs, cells[i].x, cells[i].y)
}
}
}
let images = []
for (let i = 1; i < 9; i++) {
images.push(new Promise((resolve, reject) =>
{
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(img);
img.src = `https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/number_${i}.png`;
}))
}
function test(totalBombs, x, y) {
images[totalBombs-1].then(function (img) {
ctx.drawImage(img, x, y, ColumnRow, ColumnRow)
});
}
function draw() {
drawCells()
if (checked) {
drawBomb()
drawNumbers()
// coverCell()
checked = false
}
requestAnimationFrame(draw)
}
function update() {
setup()
numOfBombs()
}
update()
draw()
// bombTest()
<canvas id="myCanvas" width="600" height="600"></canvas>
我有一个问题,canvas 只画了一张我让他画的图像。我已经看过代码并检查了所有内容,一切都很好,但 drawImage 或 image.onload 函数没有。 idk 为什么它这样做导致它应该在每次调用时绘制图像但它没有。它只是绘制了 1 次然后就完成了。也许我做错了什么,但在我看到它应该工作之后;
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
this.bomb = false
this.revealed = false
}
show() {
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width
const h = canvas.height
const ColumnRow = w / 15
const cells = []
const bombs = 5
const bombPosition = []
let checked = true
const arr = [
[-1, 1],
[0, 1],
[1, 1],
[1, 0],
[1, -1],
[0, -1],
[-1, -1],
[-1, 0]
]
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow))
}
}
}
function drawCells() {
for (let c of cells) {
c.show()
}
}
function numOfBombs() {
for (let i = 0; i < bombs; i++) {
if (bombPosition.length < bombs) {
let randomX = Math.floor(Math.random() * w / ColumnRow) * ColumnRow
let randomY = Math.floor(Math.random() * h / ColumnRow) * ColumnRow
for (let j = 0; j < bombPosition.length; j++) {
if (bombPosition[j].x == randomX && bombPosition[j].y == randomY) {
numOfBombs()
}
}
bombPosition.push({ x: randomX, y: randomY });
} else {
break;
}
}
}
function drawBomb() {
let img = new Image();
img.onload = function () {
for (let i = 0; i < bombPosition.length; i++) {
ctx.drawImage(img, bombPosition[i].x, bombPosition[i].y, ColumnRow, ColumnRow)
}
};
img.src = "https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/mine.png";
//set cell bomb to true
for (let i = 0; i < cells.length; i++) {
for (let j = 0; j < bombPosition.length; j++) {
if (cells[i].x == bombPosition[j].x && cells[i].y == bombPosition[j].y)
cells[i].bomb = true
}
}
}
function drawNumbers() {
for (let i = 0; i < cells.length; i++) {
let totalBombs = 0;
if (!cells[i].bomb) {
for (let j = 0; j < arr.length; j++) {
tmpx = cells[i].x + arr[j][0] * ColumnRow // 0 x
tmpy = cells[i].y + arr[j][1] * ColumnRow // 1 y
// console.log(tmpx);
for (let k = 0; k < cells.length; k++) {
if (cells[k].x == tmpx && cells[k].y == tmpy) {
if (cells[k].bomb) {
totalBombs++;
}
break;
}
}
}
}
if (totalBombs > 0) {
test(totalBombs, cells[i].x, cells[i].y)
}
}
}
let images = []
for (let i = 1; i < 9; i++) {
let img = new Image()
images.push(img)
}
function test(totalBombs, x, y) {
images[totalBombs].onload = function () {
ctx.drawImage(images[totalBombs], x, y, ColumnRow, ColumnRow)
}
images[totalBombs].src = `https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/number_${totalBombs}.png`
}
function draw() {
drawCells()
if (checked) {
drawBomb()
drawNumbers()
// coverCell()
checked = false
}
requestAnimationFrame(draw)
}
function update() {
setup()
numOfBombs()
}
update()
draw()
// bombTest()
<canvas id="myCanvas" width="600" height="600"></canvas>
问题是您正在尝试加载图像并同时绘制它们。因此,当图像仍在加载时,您正在为每个数字替换 onload
函数。这是 Promise
的用武之地:
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
this.bomb = false
this.revealed = false
}
show() {
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width
const h = canvas.height
const ColumnRow = w / 15
const cells = []
const bombs = 5
const bombPosition = []
let checked = true
const arr = [
[-1, 1],
[0, 1],
[1, 1],
[1, 0],
[1, -1],
[0, -1],
[-1, -1],
[-1, 0]
]
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow))
}
}
}
function drawCells() {
for (let c of cells) {
c.show()
}
}
function numOfBombs() {
for (let i = 0; i < bombs; i++) {
if (bombPosition.length < bombs) {
let randomX = Math.floor(Math.random() * w / ColumnRow) * ColumnRow
let randomY = Math.floor(Math.random() * h / ColumnRow) * ColumnRow
for (let j = 0; j < bombPosition.length; j++) {
if (bombPosition[j].x == randomX && bombPosition[j].y == randomY) {
numOfBombs()
}
}
bombPosition.push({ x: randomX, y: randomY });
} else {
break;
}
}
}
function drawBomb() {
let img = new Image();
img.onload = function () {
for (let i = 0; i < bombPosition.length; i++) {
ctx.drawImage(img, bombPosition[i].x, bombPosition[i].y, ColumnRow, ColumnRow)
}
};
img.src = "https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/mine.png";
//set cell bomb to true
for (let i = 0; i < cells.length; i++) {
for (let j = 0; j < bombPosition.length; j++) {
if (cells[i].x == bombPosition[j].x && cells[i].y == bombPosition[j].y)
cells[i].bomb = true
}
}
}
function drawNumbers() {
for (let i = 0; i < cells.length; i++) {
let totalBombs = 0;
if (!cells[i].bomb) {
for (let j = 0; j < arr.length; j++) {
tmpx = cells[i].x + arr[j][0] * ColumnRow // 0 x
tmpy = cells[i].y + arr[j][1] * ColumnRow // 1 y
// console.log(tmpx);
for (let k = 0; k < cells.length; k++) {
if (cells[k].x == tmpx && cells[k].y == tmpy) {
if (cells[k].bomb) {
totalBombs++;
}
break;
}
}
}
}
if (totalBombs > 0) {
test(totalBombs, cells[i].x, cells[i].y)
}
}
}
let images = []
for (let i = 1; i < 9; i++) {
images.push(new Promise((resolve, reject) =>
{
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(img);
img.src = `https://raw.githubusercontent.com/americosp/Minesweeper/master/Minesweeper/images/number_${i}.png`;
}))
}
function test(totalBombs, x, y) {
images[totalBombs-1].then(function (img) {
ctx.drawImage(img, x, y, ColumnRow, ColumnRow)
});
}
function draw() {
drawCells()
if (checked) {
drawBomb()
drawNumbers()
// coverCell()
checked = false
}
requestAnimationFrame(draw)
}
function update() {
setup()
numOfBombs()
}
update()
draw()
// bombTest()
<canvas id="myCanvas" width="600" height="600"></canvas>