Can't the graphics on the canvas clean properly?

I try to squeeze every last bit of performance out of my game on canvas; I recently found out that cleaning the canvas is very difficult, so I'm trying to find a way to replace cleaning the entire canvas in each frame. However, I find a few problems with the new method that I am trying to do to clear each bounding object object separately and then update them.

The problem is that the elements remain โ€œleftโ€ when they leave the canvas, and part of the image remains. I tried to simplify the code to make sure that the problem is not with the rest of the code, and there is no joy.

Returning to wiping the entire canvas, each frame is also undesirable, especially since this new method is much faster. Here's the code (for some reason, it doesn't work like a fiddle ).

var enemyCtx = document.getElementById('enemy').getContext('2d'); var game = { w: 800, h: 500 }; var enemies = []; window.addEventListener('load', function() { for (var i = 0; i < 200; i++) { enemies[enemies.length] = new Enemy(); } update(); }, false); var buffer = document.createElement('canvas'); buffer.width = 42; buffer.height = 42; var bufferCtx = buffer.getContext('2d'); drawEnemy(bufferCtx, 5, 5, 32, 32, 'red'); function update() { for (var i = 0; i < enemies.length; i++) { enemyCtx.clearRect( enemies[i].x, enemies[i].y, enemies[i].x + enemies[i].width, enemies[i].y + enemies[i].height); } for (var i = 0; i < enemies.length; i++) { enemies[i].x-=5; enemyCtx.drawImage(buffer, enemies[i].x-5, enemies[i].y-5); } requestAnimationFrame(update); } function drawEnemy(ctx, x, y, width, height, colour) { ctx.lineWidth = 1; ctx.strokeStyle = colour; ctx.strokeRect(x + 0.5, y + 0.5, width, height); } function Enemy() { this.x = Math.random()*game.w; this.y = Math.random()*game.h; this.width = 32; this.height = 32; } (function() { // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); 

& HTML:

 <canvas id="enemy" width="800" height="500"></canvas>โ€‹ 

Any insights you guys could give me would be very helpful; thanks!

+4
source share
1 answer

If I thought about this a bit, I came up with a solution; perhaps it can benefit you.

Basically, the image is โ€œleft behindโ€ on the canvas, because the clearRect () method should work with the actual coordinates of the canvas. As the image leaves the canvas, its coordinates will be negative.

 function update() { for (var i = 0; i < enemies.length; i++) { lx = (enemies[i].x > 0) ? enemies[i].x : 0; ly = (enemies[i].y > 0) ? enemies[i].y : 0; enemyCtx.clearRect( lx, ly, lx + enemies[i].width + 1, ly + enemies[i].height + 1); } // ... } 

An additional 1 to the width is to stop the canvas by drawing the last column of the image pixel when it is erased. Hope this helps.

+1
source

All Articles