I've created a little bouncing boxes demo in javascript using the canvas. Each box (for want of a better word) class handles it's own updates and rendering. However, my problem lies in clearing the canvas before drawing the next frame. It clears fine when the boxes are moving but leaves artifacts behind after it hits a wall. Here's a fiddle - https://jsfiddle.net/dzuvL7ph/1/
Here's my code;
function init(){
window.box1 = new Box(50, 'red', 0, 0);
window.box2 = new Box(50, 'blue', 400, 20);
requestAnimationFrame(update);
}
function update() {
window.box1.update();
window.box2.update();
requestAnimationFrame(update);
requestAnimationFrame(render);
}
function render() {
window.box1.render();
window.box2.render();
}
// -------------------------------------------------------------------------------------------------------
// --
// -------------------------------------------------------------------------------------------------------
var Box = function(dimensions, color, x, y){
this.width = dimensions;
this.height = dimensions;
this.x = x;
this.y = y;
this.velocityX = 10;
this.velocityY = 10;
this.color = color;
this.context = document.getElementById('canvas').getContext('2d');
this.update = function(){
this.x += this.velocityX;
this.y += this.velocityY;
this.collisionCheck();
};
this.render = function(){
this.context.fillStyle = this.color;
this.context.clearRect(this.x - this.velocityX, this.y - this.velocityY, this.width, this.height);
this.context.fillRect(this.x, this.y, this.width, this.height);
};
this.collisionCheck = function(){
if(this.y > 600 - this.height || this.y < 0)
this.velocityY *= -1;
if(this.x > 800 - this.width || this.x < 0)
this.velocityX *= -1;
};
};
I assume it's to do with this.context.clearRect(this.x - this.velocityX, this.y - this.velocityY, this.width, this.height); but I can't figure out what I'm doing wrong.
It's a little weird you're doing a cleanup for each box. Normally, you'd wipe the whole canvas on each frame: https://jsfiddle.net/yb58fd47/
Your update function checks for collisions, which can in turn reverse the speed component(s). But, your render function relies on that speed component to accurately represent the last speed. If you don't want to clear the whole canvas, you can keep track of the previous actual speed the box had (I added velocityXLast and velocityYLast):
function init(){
window.box1 = new Box(50, 'red', 0, 0);
window.box2 = new Box(50, 'blue', 120, 20);
requestAnimationFrame(update);
}
function update() {
window.box1.update();
window.box2.update();
requestAnimationFrame(update);
requestAnimationFrame(render);
}
function render() {
window.box1.render();
window.box2.render();
}
// -------------------------------------------------------------------------------------------------------
// --
// -------------------------------------------------------------------------------------------------------
var Box = function(dimensions, color, x, y){
this.width = dimensions;
this.height = dimensions;
this.x = x;
this.y = y;
this.velocityX = 10;
this.velocityY = 10;
this.color = color;
this.context = document.getElementById('canvas').getContext('2d');
this.update = function(){
this.x += this.velocityX;
this.y += this.velocityY;
this.velocityXLast = this.velocityX;
this.velocityYLast = this.velocityY;
this.collisionCheck();
};
this.render = function(){
this.context.fillStyle = this.color;
this.context.clearRect(this.x - this.velocityXLast, this.y - this.velocityYLast, this.width, this.height);
this.context.fillRect(this.x, this.y, this.width, this.height);
};
this.collisionCheck = function(){
if(this.y > 150 - this.height || this.y < 0)
this.velocityY *= -1;
if(this.x > 400 - this.width || this.x < 0)
this.velocityX *= -1;
};
};
init();
canvas {border: 1px solid black}
<canvas id="canvas" width="400" height="150"></canvas>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With