I'm trying to understand how HTML canvas works. I know the basics and I'm coding a 2D game, but I have so many questions regarding it and its weird behaviour. I have different versions of code and each gives me different results when moving the character to the right or left on canvas.
The main problem is that when the translate()
for canvas is called on the character move to the right, it starts to leave the trails of sprites. I try to fix this with clearRect()
but if I use clearRect
then it just gives me white empty background on translate()
function when moving to the right. Why there are no trails of the character when moving in the center but once I move outside the center more to the right, it's either the sprite character or sprite tilesets that gets trailed?
I really need help with this, so if the question is too broad or not clear enough, let me know and I fill fix it.
explain me what's happening with the canvas and how to fix it so that when translate()
happens on the character move to the side, there is no white background or sprite trails happening but just a nice render as it is onload.
https://codepen.io/Limpuls/pen/deEGXX leaves trails for tilesets on the character move. You can see that it starts happening when translate() for canvas is happening. If I try to clearRect
inside my render draw loop before drawing, then on the character move then background gets cutted off and there is just a white background. Why and how to fix this? Inside render()
function try to comment and uncomment clearRect()
to see what I'm talking about.
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();