Detecting collision on canvas border

2019-03-01 16:35发布

I am making a little game with my friends but i am trying to detect the collision when bumping in the the walls of the canvas, and I made it work but when i hit the wall my caracter gets stuck.. and i dont know how to find out a way to make him move again. Do you think any of you guys could help me out with this one. Thanks for all help!

Javascript / jQuery:

function Player() {
    this.w = 50;
    this.h = 60;
    this.x = (cW / 2) - (this.w / 2);
    this.y = (cH / 2) - (this.h / 2);
    this.name = username.value;
    this.nw = ctx.measureText(this.name).width; // username.clientWidth + 1;
    this.src = playerImage;
    this.dx = 0;
    this.dy = 0;
    this.render = function() {
        ctx.drawImage(this.src, this.x, this.y, this.w, this.h);
        ctx.fillStyle = 'orange';
        ctx.font = '15px Arial, sans-serif';
        // fixa x-värdet
        ctx.fillText(this.name, (this.x + this.w / 2) - (this.nw / 2), (this.y - 6));
    }
}

var player = new Player();

function animate() {
    if(player.x > 0 && player.y > 0 && player.x + player.w < cW && player.y + player.h < cH) {
        player.x += spd * player.dx;
        player.y += spd * player.dy;
    } 
    else {
        // Need code here to release player from wall
    }

    ctx.save();
    ctx.clearRect(0, 0, cW, cH);
    ctx.drawImage(bg, 0, 0);
    player.render();
    ctx.rotate(-.4);
    raining();
    ctx.restore();
}
var animateInterval = setInterval(animate, 1000/60);

document.addEventListener('keydown', function(e) {
    var key_press = String.fromCharCode(e.keyCode);

    switch(key_press) {
        case 'W':
            player.dy = -1;
            break;

        case 'A':
            player.dx = -1;
            break;

        case 'S':
            player.dy = 1;
            break;  

        case 'D':
            player.dx = 1;
            break;

        default:
            break;
    }
});

document.addEventListener('keyup', function(e) {
    var key_press = String.fromCharCode(e.keyCode);

    switch(key_press) {
        case 'W':
            player.dy = 0;
            break;

        case 'A':
            player.dx = 0;
            break;

        case 'S':
            player.dy = 0;
            break;

        case 'D':
            player.dx = 0;
            break;

        default:
            break;
    }
});

1条回答
beautiful°
2楼-- · 2019-03-01 17:28

The problem you are having is the following:

Suppose your character is moving at the speed of 10 pixels per frame, the character position is currently 595px (the right side of the character) and the canvas width is 600.

On the current frame you are checking if there is a collision: there's none so you add the speed to the current position and you get 605px. Now on the next frame the character is out the bounds and you cannot move him anymore because the player.x + player.width > canvas.width

What you can do:

1: You check for the collision and move the character back inside the viewport:

if (player.x + player.width > canvas.width) {
    player.x = canvas.width - player.width;
}

Because the collision check fails now, you can move him wherever you want.

You should do this check for all the sides, but the logic is different for each side, this is sample code for collision with the left wall:

if (player.x < 0) {
    player.x = 0;
}

2: In your if statement you should add the speed in your calculations and not move the character if the player.x + player.vx exceeds canvas.width, but I prefer the first method as you can actually be at the side of the viewport

Tip with working with canvas positions: always round off your positions at the render level:

this.render = function() {
    ctx.drawImage(this.src, Math.round(this.x), Math.round(this.y), this.w, this.h);
    ...
}
查看更多
登录 后发表回答