0

http://jsfiddle.net/xknbn/ http://jsfiddle.net/xknbn/embedded/result/

大家好。我在让我的碰撞系统正常运行时遇到问题。目前,如果我走得太快,我会嵌入到对象中,并且我的碰撞解决方案会失败。我相当确定问题的发生是因为我设置了速度,但我不知道如何解决这个问题。任何帮助将不胜感激。

friction = 0.9,
gravity = 0.3;

function keycheck() {

if (keys[32]) {
    if (!player.jumping) {
        player.jumping = true;
        player.vely = -player.speed;
    }
}

if (keys[68]) {
    if (player.velx < player.speed) {
        player.velx++;
    }
}
if (keys[65]) {
    if (player.velx > -player.speed) {
        player.velx--;
    }
}
}

ctx.startx = player.x;
ctx.starty = player.y;
function playerupdate() {

player.Intersects = function(object) {                                      
    return player.x < object.x + object.width + 1  &&
    player.x + player.width + 1 > object.x &&
    player.y < object.y + object.height + 1 &&
    player.y + player.height + 1 > object.y;
}

solidcount = 0;
for (i = 0; i < tgen.length; i++) {

    for (ii = 0; ii < tgen[i].length; ii++) {

        if ( player.Intersects(tgen[i][ii]) && tgen[i][ii].solid ) {
            var pright = player.x + player.width,
                pleft = player.x,
                ptop = player.y,
                pbottom = player.y + player.height,
                oright = tgen[i][ii].x + tgen[i][ii].width,
                oleft = tgen[i][ii].x,
                otop = tgen[i][ii].y,
                obottom = tgen[i][ii].y + tgen[i][ii].height;

            //if player is to the right of his previous position, and his right side has collided with objects left
            if (player.x >= ctx.startx && pright > oleft - 1) {
                player.x--;
            }
            //if player is to the left of his previous position, and his left side has collided with objects right
            if (player.x <= ctx.startx && pleft < oright + 1) {
                player.x++;
            }
            //if player is above his previous position, and his top side has collided with objects bottom
            if (player.y <= ctx.starty && ptop < obottom + 1) {
                player.y++;
            }
            //if player is below his previous position, and his bottom side has collided with objects top
            if (player.y >= ctx.starty && pbottom > otop - 1) {
                player.y--;
                player.vely = 0;
                player.jumping = false;
            }
            solidcount++;
        }
    }

    if ( i == tgen.length - 1 && solidcount == 0 ) {
        player.jumping = true;
    }
}

ctx.diffx = player.x - ctx.startx;
ctx.diffy = player.y - ctx.starty;

if (player.x <= bgimg.width - width/2 && player.x >= width/2) {
    ctx.translate(-ctx.diffx,0);
}

if (player.y <= bgimg.height - 360 - player.height) {
    ctx.translate(0,-ctx.diffy);
}

ctx.startx = player.x;
ctx.starty = player.y;

ctx.clearRect(player.x-width/2,player.y-height/2,width,height);

ctx.fillStyle = 'red';
ctx.fillRect(player.x,player.y,player.width,player.height);

keycheck();

player.velx *= friction;
if (player.jumping) {player.vely += gravity;}

player.x += player.velx;
player.x = Math.round(player.x);   

player.y += player.vely;
player.y = Math.round(player.y);

if (player.y >= bgimg.height - player.height - 1) {
    player.y = bgimg.height - player.height - 1;
    player.vely = 0;
    player.jumping = false;
}

if (player.x > bgimg.width - player.width) {
    player.x = bgimg.width - player.width;
    player.velx = 0;
};

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

if (!keys[65] && !keys[68] && (player.velx < 0.2 && player.velx > -0.2)) {player.velx = 0};

console.log(player.x,player.y)
requestAnimationFrame(playerupdate);
}
4

1 回答 1

0

所以这是一个常见的平台引擎问题。如果你的玩家移动得太快,它会直接穿过障碍物,因为在当前位置和下一个位置之间不会发生碰撞测试。您的目标是尽可能少地测试碰撞,但要测试起始位置和目标之间所有可能的碰撞。此外,当您检测到路径中的碰撞时,您必须正确处理它。

安全移动物体

要安全地移动任何物体,您需要逐步移动它们,并在每一步测试碰撞。最简单的选择是一次将玩家移动 1 个像素,然后测试是否发生碰撞。这确实意味着要进行大量的碰撞测试。

为了改善这一点,如果你只做盒子碰撞测试,你可以每次移动播放器的最大宽度。

处理碰撞

因此,在您的示例中,您根据玩家的方向将玩家向后移动 1 个像素。如果玩家要下沉 5 像素进入障碍物,那么您的碰撞处理机制只会将玩家移回障碍物 4 像素。看起来好像玩家慢慢地穿过障碍物。

如果您一次将播放器移动 1 个像素,则您采用的方法有效。如果一次移动玩家超过 1 个像素,则必须将玩家向后移动,直到它不再与障碍物重叠。像while(重叠)->向后移动一个像素

于 2013-10-26T03:22:47.840 回答