【问题标题】:Why canvas image is drawn improperly when specific coordinates given为什么给定特定坐标时画布图像绘制不正确
【发布时间】:2018-10-09 05:09:05
【问题描述】:

我正在尝试用原版 javascript 构建 Snake 游戏。到目前为止,我已经生成了墙边界并定义了玩家初始头部开始的坐标。但是当我在浏览器中尝试时,发生了一个奇怪的错误,我不知道为什么。这是一个例子:

1.发生错误。球员头是场上的那个单点。然而由于某种原因,墙壁也被涂成红色(玩家初始头部颜色)。

这是我的 javascript 代码:

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

var xAxis = 600, yAxis = 600, wallImage, playerHeadImage;  // we defined that canvas is 600 x 600 big
var playerHeadInitialXpos = Math.floor(Math.random() * 28) + 1;  // We use 28 and 1, because 29 and 0 are occupied by walls in the worldTileSet
var playerHeadInitialYpos = Math.floor(Math.random() * 28) + 1;
console.log(playerHeadInitialXpos);
console.log(playerHeadInitialYpos);
var isGameOver = false;
var arrayLength = 30;
var worldTileSet = new Array(arrayLength);
var documentBody = document.body;


function wall(xPosition, yPosition) {
  this.name = 'Wall';
  this.xPosition = xPosition;
  this.yPosition = yPosition;
  isWall : true;
  ctx.save();
  ctx.rect(this.xPosition, this.yPosition, 20, 20);  // since our keyboard is 30 * 30 squares (two dimensional array), then 600 / 30 = 20
  ctx.clip();
  ctx.drawImage(wallImage, this.xPosition, this.yPosition);
  ctx.restore();
}

function playerHead(xPosition, yPosition) {
  console.log("X body coordinate:" + xPosition + ", Y body coordinate: " + yPosition);
  this.name = 'Body';
  this.xPosition = xPosition;
  this.yPosition = yPosition;
  isPlayerBody : true;
  ctx.save();
  ctx.rect(this.xPosition, this.yPosition, 20, 20);
  ctx.clip();
  ctx.drawImage(playerHeadImage, this.xPosition, this.yPosition);
  ctx.restore();
}

function processImages() {
  wallImage = new Image();
  playerHeadImage = new Image();
  wallImage.src = 'img/wall1.jpeg';
  playerHeadImage.src = 'img/red.jpg';
}

function setUpEnvironment() {

  if (wallImage.complete) {
    setUpNorthernGameBorder();
    setUpSouthernGameBorder();
    setUpEasternGameBorder();
    setUpWesternGameBorder();
    return;
  }

  setTimeout(function () {
    setUpEnvironment()
  }, 1000);
}

function setUpPlayer() {
  if (playerHeadImage.complete) {
    alert(1);
    setPlayerHeadInitialPosition();
    return;
  }
  setTimeout(function () {
    setUpPlayer()
  }, 1000);
}

window.onload = function () {  // <-- Here code begins
  processImages();
  initializeWorldTileSet();
  setUpEnvironment();
  setUpPlayer();
};

function setUpNorthernGameBorder() {
  var xPos = 0;
  for (var tile = 0; tile < arrayLength; tile++) {
    worldTileSet[tile][0] = new wall(xPos, yAxis - 600);
    xPos += 20;
  }
}

function setUpSouthernGameBorder() {
  var xPos = 0;
  for (var tile = 0; tile < arrayLength; tile++) {
    worldTileSet[tile][29] = new wall(xPos, yAxis - 20);
    xPos += 20;
  }
}

function setUpEasternGameBorder() {
  var yPos = 0;
  for (var tile = 0; tile < arrayLength; tile++) {
    worldTileSet[29][tile] = new wall(xAxis - 20, yPos);
    yPos += 20;
  }
}

function setUpWesternGameBorder() {
  var yPos = 0;
  for (var tile = 0; tile < arrayLength; tile++) {
    worldTileSet[0][tile] = new wall(xAxis - 600, yPos);
    yPos += 20;
  }
}

function initializeWorldTileSet() {  // Here we build two dimensional array which represents our game board
  for (var i = 0; i < worldTileSet.length; i++) {
    worldTileSet[i] = new Array(arrayLength);
  }
}

function setPlayerHeadInitialPosition() {  // <-- I suspect a bug happens here, but i dont know why
  var yPos = 0;
  console.log("playerHeadInitialXpos: " + playerHeadInitialXpos + ", playerHeadInitialYpos: " + playerHeadInitialYpos);
  worldTileSet[playerHeadInitialXpos][playerHeadInitialYpos] = new playerHead(playerHeadInitialXpos * 20, playerHeadInitialYpos * 20);

  worldTileSet[29][29] = new playerHead(580, 580);
  for (var tile = 0; tile < arrayLength; tile++) {
    yPos += 20;
    console.log("Eastern wall. Coordinates: X: " + 29 + ", Y: " + tile + ". Object: " + worldTileSet[29][tile] + ". Name: " + worldTileSet[29][tile].name);
  }
}

如您所见,我已经定义了两个对象,并且所有内容(除了草)都是一个 javascript 对象(墙壁、头部)。所以我调试了一下,看看墙上的那些红色是不是玩家头部对象,我得到了以下结果:

Eastern wall. Coordinates: X: 29, Y: 0. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 1. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 2. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 3. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 4. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 5. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 6. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 7. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 8. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 9. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 10. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 11. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 12. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 13. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 14. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 15. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 16. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 17. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 18. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 19. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 20. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 21. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 22. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 23. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 24. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 25. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 26. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 27. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 28. Object: [object Object]. Name: Wall
game.js:167 Eastern wall. Coordinates: X: 29, Y: 29. Object: [object Object]. Name: Body

2.我的调试表明,即使有些墙壁是红色的,它们仍然是墙壁对象。注意:出于调试目的,我特意将最后一个红点(头部对象)放在了东部边界上。

在这里,我不知道为什么会这样。我注意到当最初的玩家头部更偏西时,这不会发生。只有当玩家头部足够靠近东墙时才会发生这种情况。这种行为的原因可能是什么?

附件(图片资源):

【问题讨论】:

  • “setPlayerHeadInitialPosition”函数是否只被调用一次?
  • @Stakvino 是的
  • 您能否提供您的程序中使用的 3 张图像(红色、墙壁和草)我试图在浏览器上执行它。或者你的程序有一个 jsfiddle/codepen 链接?
  • 起初我认为删除这一行:worldTileSet[29][29] = new playerHead(580, 580);在“setPlayerHeadInitialPosition”函数中将删除右下角的红色方块(它为我做了)。
  • 是的。但这只是为了调试目的。主要问题是其他点

标签: javascript html5-canvas


【解决方案1】:

问题是你画的是整个红色方块,而不是只取它的 20x20 部分,所以你必须替换:

ctx.drawImage(playerHeadImage, this.xPosition, this.yPosition);

与:

ctx.drawImage(playerHeadImage, this.xPosition, this.yPosition, 20, 20);

从红色方形图像中仅取 20x20。我个人建议,因为您只想绘制一个红色方块来使用 fillrect 而不是像这样绘制图像:

ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(this.xPosition, this.yPosition, 20, 20);
ctx.clip();
ctx.restore();

而不是:

ctx.save();
ctx.clip();
ctx.drawImage(playerHeadImage, this.xPosition, this.yPosition, 20, 20);
ctx.restore();

【讨论】:

  • 非常感谢 :) 你拯救了这一天!
猜你喜欢
  • 2017-05-20
  • 1970-01-01
  • 2018-06-07
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 2014-04-23
  • 1970-01-01
相关资源
最近更新 更多