Search code examples
javascriptcanvas

Javascript canvas not refreshing with clearRect() nor redrawing


I feel like I'm missing something obvious here, but I can't find what it is:

I have 2 draw functions : The first one draw_canvas() draws the background, 2 rectangles on mostly all the canvas size. The second one draw_player() draws a triangle with some context.stroke()

Both of them are being called in an update function called with setInterval(update,10), a context.clearRect is also there.

The orientation of the triangle is also updated via document.onkeydown and onkeyup.

On my understanding, clearRect() should refresh the canvas and erase everything, draw_canvas should redraw the background, both of those should erase my triangle.

however when changing the orientation, every iteration of the triangle can be seen, and I cannot understand why it doesn't get erased.

Does anyone can explain to me what is happening please ?

My code below (104 lines)

var canvas;
var ctx;
var lx;
var ly;
right = false;
left = false;

var player = {
    x: 0,
    y: 0,
    size: 32,
    angle: 90
}

window.addEventListener("load", function(event) {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    player.x = canvas.width/2;
    player.y = canvas.height/2;
});

document.onkeydown = function (e) {
    /*
    left = 37
    up = 38
    right = 39
    down = 40
    space = 32
    */
    if(e.keyCode == 37){
        left = true;
        right = false;
    }
    
    if(e.keyCode == 39){
        left = false;
        right = true;
    }

}

document.onkeyup = function (e) {
    if(e.keyCode == 37 || e.keyCode == 39){
        left = false;
        right = false;
    }
}

function draw_canvas(){
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'white';
    ctx.fillRect(1, 1, canvas.width-2, canvas.height-2);
}

function draw_player(){
    
    // draw du player, triangle équilatéral avec angle
    ctx.strokeStyle = 'black';
    ctx.linewidth = 2;
    
    lx = player.x + (player.size/2)*Math.cos(Math.PI*player.angle/180);
    ly = player.y + (player.size/2)*Math.sin(-Math.PI*player.angle/180);
    
    ctx.moveTo(lx,ly);
    ctx.lineTo( lx + player.size*Math.cos(Math.PI*(player.angle-150)/180), 
                ly + player.size*Math.sin(-Math.PI*(player.angle-150)/180));
    ctx.stroke();
    
    lx = lx + player.size*Math.cos(Math.PI*(player.angle-150)/180), 
    ly = ly + player.size*Math.sin(-Math.PI*(player.angle-150)/180);
    
    ctx.moveTo(lx,ly);
    ctx.lineTo( lx + player.size*Math.cos(Math.PI*(90 + player.angle)/180), 
                ly + player.size*Math.sin(-Math.PI*(90 + player.angle)/180));                
    ctx.stroke();

    lx = lx + player.size*Math.cos(Math.PI*(90 + player.angle)/180);
    ly = ly + player.size*Math.sin(-Math.PI*(90 + player.angle)/180);
    
    ctx.moveTo(lx,ly);
    ctx.lineTo( lx + player.size*Math.cos(Math.PI*(player.angle-30)/180), 
                ly + player.size*Math.sin(-Math.PI*(player.angle-30)/180));                
    ctx.stroke();

}

function update_player(){
    if (right){
        player.angle -= 2;
    }
    else if (left){
        player.angle += 2;
    }
}


setInterval(update,10);
function update(){
    ctx.clearRect(0,0,canvas.width,canvas.height);
      draw_canvas();
    draw_player();
    update_player();

}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Asteroids</title>
    <script type="text/javascript" src="asteroids.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="512" height="512"></canvas>
  </body>
</html>


Solution

  • Just add ctx.beginPath() as the first thing in draw_player().

    btw. try using requestAnimationFrame(update); instead of interval of 10ms.