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 (オーバーラップ) のようなもの -> 1 ピクセル後ろに移動

于 2013-10-26T03:22:47.840 に答える