我正在尝试理解HTML画布的工作原理。我知道基础知识,我正在编写一个2D游戏,但我有很多关于它及其怪异行为的问题。我有不同版本的代码,每个字符在画布上向右或向左移动时都会给出不同的结果。
主要问题是当角色的translate()
被调用时,角色会向右移动,它会开始留下精灵的踪迹。我尝试使用clearRect()
解决此问题,但如果我使用clearRect
,那么当向右移动时,它只会在translate()
函数上为我提供空白背景。为什么在中心移动时没有角色的痕迹,但是当我向中心移动到右边时,它是精灵角色还是精灵瓷砖集落后了?
我真的需要帮助,所以如果问题太宽泛或不够清楚,请告诉我,我会解决它。
向我解释画布发生了什么以及如何修复它,以便当角色上的translate()
移动到侧面时,没有白色背景或精灵轨迹发生但只是一个很好的渲染,因为它是onload
https://codepen.io/Limpuls/pen/deEGXX在角色移动中留下tilesets的路径。您可以看到,当canvas()的translate()发生时,它开始发生。如果我在绘制之前在渲染绘制循环中尝试clearRect
,那么在角色移动时,背景会被切掉并且只有白色背景。为什么以及如何解决这个问题?在render()
内部功能尝试评论并取消注释clearRect()
以查看我在说什么。
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var view = {x: 0, y: 0};
var questionsArray = [];
var moveCount = 0;
var moveCharacter = false;
var theArray = [];
/*var mapArray = [
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0]
];
*/
var mapArray = [
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
function isPositionWall(ptX, ptY) {
var gridX = Math.floor(ptX / 36);
var gridY = Math.floor(ptY / 36);
/*if(gridX > 0 || gridX >= mapArray[0].length)*/
if(mapArray[gridX][gridY] === 1) {
return true;
/*if(gridY < 0 || gridY >= mapArray.length)
return true;
return mapArray[gridX][gridY];*/
}
}
var Question = function(question, answer1, answer2, correctAnswer) {
this.question = question;
this.answer1 = answer1;
this.answer2 = answer2;
this.correctAnswer = correctAnswer;
this.addToArray = function(){
theArray.push(this);
};
this.addToArray();
}
Question.prototype.checkAnswer = function(answer1, answer2) {
if (answer1.innerHTML == this.correctAnswer) {
console.log("correct");
moveCharacter = true;
} else {
console.log("nope")
}
}
var question1 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question2 = new Question("Jo ar ne?", "Ne", "Jo", "Ne");
var question3 = new Question("Aha ar ne?", "Aha", "Ne", "Aha");
var question4 = new Question("Ja ar ne?", "Taip", "Ne", "Taip");
var question5 = new Question("Jojo ar ne?", "Jojo", "Ne", "Jojo");
var question6 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var question7 = new Question("Taip ar ne?", "Taip", "Ne", "Taip");
var StyleSheet = function(image, width, height, x, y) {
this.image = image;
this.width = width;
this.height = height;
this.x = x;
this.y = y
this.draw = function(image, sx, sy, swidth, sheight, x, y, width, height) {
context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
};
this.drawimage = function(image, x, y, width, height) {
context.drawImage(image, x, y, width, height);
};
};
/* Initial Sprite Position */
var boatPosX = canvas.height/2 - 50;
var boatPosY = canvas.height/2 - 50;
function render(viewport) {
context.save();
context.translate(view.x, view.y);
context.clearRect(0, 0, canvas.width, canvas.height)
requestAnimationFrame(render);
var oldPosX = boatPosX;
var oldPosY = boatPosY;
for (let i = 0; i < mapArray.length; i++) {
for (let j = 0; j < mapArray[i].length; j++) {
if (mapArray[j][i] == 0) {
this.sprite.draw(
background,
190,
230,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);
}
if (mapArray[j][i] == 1) {
this.sprite.draw(
background,
30,
30,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);
}
if (mapArray[j][i] == 2) {
this.sprite.draw(
background,
200,
20,
26,
26,
i * this.sprite.width,
j * this.sprite.height,
this.sprite.width,
this.sprite.height
);
}
}
}
this.ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
/*var lineHeight = 16 * 2.286;
var textWidth = context.measureText(theArray[moveCount].question).width * 3;
context.textAlign = 'left';
context.textBaseline = 'top';
context.font="14px Verdana";
context.fillStyle = 'rgba(0, 0, 0 ,0.9)';
context.fillRect(boatPosX + ship.width / 2, boatPosY - ship.height / 2, textWidth, lineHeight);
context.fillStyle = 'white';
context.fillText(theArray[moveCount].question, boatPosX + ship.width / 2, boatPosY - ship.height / 2);
answerBtn1.innerHTML = theArray[moveCount].answer1;
answerBtn2.innerHTML = theArray[moveCount].answer2;*/
if(isPositionWall(boatPosX + 36, boatPosY)) {
//boatPosX = oldPosY;
//console.log("collision");
}
//console.log(mapArray[Math.floor(boatPosX / 36)]);
//console.log(mapArray[Math.floor(boatPosX / 36)][Math.floor(boatPosX / 36)]);
context.restore();
};
var btn1 = document.getElementsByClassName("button1")[0];
var btn2 = document.getElementsByClassName("button2")[0];
var btn3 = document.getElementsByClassName("button3")[0];
var btn4 = document.getElementsByClassName("button4")[0];
var answerBtn1 = document.getElementsByClassName("answer1")[0];
var answerBtn2 = document.getElementsByClassName("answer2")[0];
console.log(theArray);
answerBtn1.addEventListener("click", function(e) {
theArray[moveCount].checkAnswer(answerBtn1, answerBtn2);
});
answerBtn2.addEventListener("click", function(e) {
question1.checkAnswer(answerBtn2, answerBtn2);
});
btn1.addEventListener("click", function(e) {
if (moveCharacter == true) {
moveCount++;
boatPosX -= 5;
view.x += 5
moveCharacter = false;
}
});
btn2.addEventListener("click", function(e) {
boatPosX += 5;
view.x -= 5
moveCount++;
});
btn3.addEventListener("click", function(e) {
boatPosY += 5;
view.Y += 5
moveCount++;
});
btn4.addEventListener("click", function(e) {
boatPosY -= 5;
view.Y += 5
moveCount++;
});
function move(e) {
if (e.keyCode == 39) {
boatPosX += 5;
//canvas.width += 2;
view.x -= 5
moveCount++;
console.log(moveCount);
console.log("right");
}
if (e.keyCode == 37) {
boatPosX -= 5;
view.x += 5
moveCount++;
console.log(moveCount);
console.log("left");
}
if (e.keyCode == 38) {
boatPosY -= 5;
view.Y += 5
moveCount++;
console.log(moveCount);
console.log("up");
}
if (e.keyCode == 40) {
boatPosY += 5;
view.Y += 5
moveCount++;
console.log(moveCount);
console.log("down");
}
}
document.onkeydown = move;
var background = new Image();
background.src = "ground.png";
var sprite = new StyleSheet(background, 36, 36, 16, 16);
var boat = new Image();
boat.src = "ship.png";
var ship = new StyleSheet(boat, 36, 36, 16, 16);
console.log(mapArray[Math.floor(boatPosX / 36)]);
//console.log(mapArray[Math.floor(boatPosX / 36)][Math.floor(boatPosX / 36)]);
render();