LWJGL - 当我的玩家与多个墙对象发生碰撞时,他开始来回弹跳

时间:2017-06-15 08:22:39

标签: java lwjgl game-engine

所以我和我的朋友决定制作游戏,所以我决定为游戏创建一个引擎。一切进展顺利,我实施了一种碰撞类型,我打电话给#34; Push Collision"这基本上意味着:当玩家移动并且物体以速度移动时它会移动到物体并将其减去位置,所以说我按下W或向上箭头我正在移动到墙上,墙将会取我的水平速度或ysp(Y速度)并将其减去我的y位置。它开始工作,直到我添加了第二个盒子,当我一个接一个地与盒子碰撞时知道它有效,但当我进入两个墙壁物体的中间时,我的播放器将开始来回弹跳墙壁。现在我知道发生了什么,因为它与一面墙碰撞,它将我的速度减去我的y或x位置,但是因为我与两个碰撞它会减去我移动到我的x的速度的两倍或者y,我以为我可以增加物体/玩家的x或y速度但是然后物体将减去两次,我正在移动,所以我有点腌菜。这是我为" Push Collision类型"制作的代码。和Game类以及P​​layer类和TestBox类或Wall类。

碰撞类:

package engine.test.core;

public class Collision {
    public static void PushCollision(BaseObject obj1, BaseObject obj2) {
        if (obj1.box.CollideWOB(obj2.box)) {

            if (obj1.MoveDir == 2) {
                obj1.Position.x -= obj1.xsp;
            } else if (obj1.MoveDir == 1) {
                obj1.Position.x += obj1.xsp;
            } else if (obj1.MoveDir == 3) {
                obj1.Position.y += obj1.ysp;
            } else if (obj1.MoveDir == 4) {
                obj1.Position.y -= obj1.ysp;
            }
        }
    }
}

玩家等级:

package engine.test.game;

import org.lwjgl.input.Keyboard;

import engine.test.core.BaseObject;
import engine.test.core.Renderer;

public class Player extends BaseObject {

    public Player(int x, int y, int w, int h) {
        super(x, y, w, h);
    }

    @Override
    public void Init() {
        xsp = 5;
        ysp = 5;
    }

    @Override
    public void Update() {
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
            MoveDir = 2;
        } else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
            MoveDir = 1;
        } else if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
            MoveDir = 4;
        } else if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
            MoveDir = 3;
        } else {
            MoveDir = 0;
        }

        if (MoveDir == 1) {
            Position.x -= xsp;
        } else if (MoveDir == 2) {
            Position.x += xsp;
        } else if (MoveDir == 3) {
            Position.y -= ysp;
        } else if (MoveDir == 4) {
            Position.y += ysp;
        }

        box.UpdateBox(Position, Size);
    }

    @Override
    public void Draw() {
        Renderer.Quad(Position, Size);
    }
}

TestBox类:

package engine.test.game;

import engine.test.core.BaseObject;
import engine.test.core.Renderer;

public class TestBox extends BaseObject {

    public TestBox(int x, int y, int w, int h) {
        super(x, y, w, h);
    }

    @Override
    public void Init() {

    }

    @Override
    public void Update() {
        box.UpdateBox(Position, Size);
    }

    @Override
    public void Draw() {
        Renderer.Quad(Position, Size);
    }
}

游戏类:

package engine.test.game;

import java.util.ArrayList;
import java.util.List;

import engine.test.core.BaseGame;
import engine.test.core.Collision;

public class Game extends BaseGame {

    Player p;
    TestBox tb;
    TestBox tb2;

    List<TestBox> TestBoxes = new ArrayList<TestBox>();


    boolean Debug = false;

    @Override
    public void Init() {
        p = new Player(0, 0, 32, 32);

        p.Init();

        tb = new TestBox(100, 100, 32, 32);
        tb2 = new TestBox(132, 100, 32, 32);

        tb.Init();
        tb2.Init();

        TestBoxes.add(tb);
        TestBoxes.add(tb2);
    }

    @Override
    public void Update() {

        p.Update();

        for (TestBox box : TestBoxes) {
            Collision.PushCollision(p, box);
        }
    }

    @Override
    public void Draw() {
        p.Draw();

        for (TestBox box : TestBoxes) {
            box.Draw();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您可以采取的一种解决方法是:

  • 检测到碰撞时,将其添加到“检测到的碰撞”队列中,该队列应保存碰撞盒数据。
  • 在检测到所有冲突并将其添加到队列后,遍历队列并在每次推送后检查对象是否仍然与该对象发生冲突。如果是,请计算新推,并应用它。否则,请忽略原始碰撞。

这是我想到的第一个解决方案。如果您对此有任何疑问,请与我们联系! :)