1

このコードが衝突検出のためにどのように機能するかを理解しようとしています。目標はバウンディング ボックスであり、エンティティの各可能なポイントをテストしていることはわかりますが、この場合の符号付きシフト演算子の目的はわかりません。実際、なぜそれが役立つのか、それが何をするのかさえ理解できません。誰でも詳しく説明できますか?

protected boolean move2(int xa, int ya) {
    if (xa != 0 && ya != 0) throw new IllegalArgumentException("Move2 can only move along one axis at a time!");

    int xto0 = ((x) - xr) >> 4;
    int yto0 = ((y) - yr) >> 4;
    int xto1 = ((x) + xr) >> 4;
    int yto1 = ((y) + yr) >> 4;

    int xt0 = ((x + xa) - xr) >> 4;
    int yt0 = ((y + ya) - yr) >> 4;
    int xt1 = ((x + xa) + xr) >> 4;
    int yt1 = ((y + ya) + yr) >> 4;
    boolean blocked = false;
    for (int yt = yt0; yt <= yt1; yt++)
        for (int xt = xt0; xt <= xt1; xt++) {
            if (xt >= xto0 && xt <= xto1 && yt >= yto0 && yt <= yto1) continue;
            level.getTile(xt, yt).bumpedInto(level, xt, yt, this);
            if (!level.getTile(xt, yt).mayPass(level, xt, yt, this)) {
                blocked = true;
                return false;
            }
        }
    if (blocked) return false;

    List<Entity> wasInside = level.getEntities(x - xr, y - yr, x + xr, y + yr);
    List<Entity> isInside = level.getEntities(x + xa - xr, y + ya - yr, x + xa + xr, y + ya + yr);
    for (int i = 0; i < isInside.size(); i++) {
        Entity e = isInside.get(i);
        if (e == this) continue;

        e.touchedBy(this);
    }
    isInside.removeAll(wasInside);
    for (int i = 0; i < isInside.size(); i++) {
        Entity e = isInside.get(i);
        if (e == this) continue;

        if (e.blocks(this)) {
            return false;
        }
    }

    x += xa;
    y += ya;
    return true;
}

エンティティは正確な x と y の位置をピクセルごとに認識していますが、タイルはその位置をまったく認識していないことに注意してください。世界にはタイルの配列がありますが、そのタイルの位置しか知りません...そのため、衝突検出を行うときは、プレイヤーの位置からどのタイルの位置を取得するかを関数で決定する必要があります。

完全なソースはこちらから入手できます: http://www.ludumdare.com/compo/ludum-dare-22/?action=preview&uid=398

タイルは 16x16 であることに注意してください

4

1 に答える 1

2

2 のべき乗で割ることは、多くの場合、右シフトnビット ( nはべき乗) として表現されます。

実際の除算を行うよりもはるかに高速だったので、以前は C やアセンブリを書くときにそうしていました。左シフトは、等価の 2 の累乗を乗算することと同じであり、ハードウェア乗算よりもはるかに高速です。現在、ほとんどのコンパイラはこれを特殊なケースとして、2 の累乗の乗算/除算の代わりにシフトを出力します。

もちろん、タイル サイズが 2 の累乗でない場合は、代わりに除算する必要があります。

于 2012-10-25T06:42:32.827 に答える