Reputation: 13
I'm trying to use Javascript to create a Canvas Game which is similar to Bug Smasher or Ant Smasher game. It means the obj will move randomly, and when u click on it, the score will increase. ( I'm not allowed to use JQuery )
I almost finished all the work. But there's an error I cannot figure out: Everytime I click on the object, the score increases but it overwrites the number "0" like this:
And this is my code:
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
<html lang="en">
<head>
<meta charset="utf-8">
<title>Assignment 5</title>
</head>
<body>
<script src="game.js"></script>
</body>
</html>
Please help ! :(
Upvotes: 1
Views: 1883
Reputation: 54089
The problem is simple to solve. You just need to clear all the previous frame's rendering before you render the new frame.
Just add the following line to the render
function
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
You will notice that the quality of the text also improves. This is because you are no long drawing over the top of the old text,
I dont know what the background image is so I clear the whole canvas. But if the background image is not transparent you only need to clear what it does not cover.
See change below
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var timer = 0;
var caught = false;
var fps = 10;
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 544;
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = "images/background.png";
// nar image
var narReady = false;
var narImage = new Image();
narImage.onload = function () {
narReady = true;
};
narImage.src = "images/nar.png";
var nar = {};
var narCaught = 0;
// When nar is caught, reset
var reset = function () {
nar.x = 40 + (Math.random() * (canvas.width - 70));
do {
nar.y = 40 + (Math.random() * (canvas.height - 70));
}
while (nar.y < 100)
};
//mousedown event
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(e) {
if (e.button != 0) return;
mouseXinCanvas = e.clientX;
mouseYinCanvas = e.clientY;
if (narBody(nar, mouseXinCanvas, mouseYinCanvas)) {
caught = true;
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
}
if (ResetScore(mouseXinCanvas, mouseYinCanvas)) {
location.reload();
}
if (ResetSpeed(mouseXinCanvas, mouseYinCanvas)) {
clearInterval(timer);
timer = setInterval(reset, 20000 / fps);
reset();
render();
}
};
//nar's body define
function narBody(nar, x, y) {
if (x <= (nar.x + 80)
&& nar.x <= (x + 80)
&& y <= (nar.y + 80)
&& nar.y <= (y + 80)
) {
fps = fps + 5;
narCaught++;
return true;
}
return false;
};
//Reset Score box
function ResetScore(x, y) {
if (x > (305)
&& x < (545)
&& y > (15)
&& y < (85)
) {
return true;
}
return false;
};
//Reset speed box
function ResetSpeed(x, y) {
if (x > (605)
&& x < (845)
&& y > (15)
&& y < (85)
) {
fps = 10;
return true;
}
return false;
};
// Draw everything
var render = function () {
//===========================================================
// add the following line to clear the display.
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
if (narReady) {
ctx.drawImage(narImage, nar.x, nar.y);
}
if (caught == true) {
if (bgReady) {
ctx.drawImage(bgImage, 0, 100);
}
caught = false;
}
// Score, Title
ctx.fillStyle = "rgb(65, 226, 24)";
ctx.font = "34px Helvetica";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Catch Naruto!!!", 5, 40);
ctx.font = "20px Helvetica";
ctx.fillText("Score: " + narCaught, 10, 10);
// Reset Score, Speed button
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(250, 10, 250, 80);
ctx.fillRect(520, 10, 250, 80);
ctx.fillStyle = "rgb(30, 168, 99)";
ctx.fillRect(255, 15, 240, 70);
ctx.fillRect(525, 15, 240, 70);
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.font = "34px Arial";
ctx.fillText("Reset Score", 275, 30);
ctx.fillText("Reset Speed", 545, 30);
};
// The main game loop
var main = function () {
render();
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
//var then = Date.now();
reset();
main();
Upvotes: 3