LWJGL - 当我的玩家与不止一个墙壁物体碰撞时,他开始来回弹跳
LWJGL - When my player collides with more than one wall object he starts to bounce back and forth
所以我和我的朋友们决定制作游戏,所以我决定为游戏创建一个引擎。一切进展顺利,我实现了一种我称之为 "Push Collision" 的碰撞类型,这基本上意味着:当玩家朝向物体移动时,物体采用它在物体上移动的速度并将其减去位置,所以说我我按下 W 或向上箭头,我正在撞墙,墙将采用我的水平速度或 ysp
(Y 速度)并将其减去我的 y 位置。它开始工作,直到我添加了第二个盒子,知道当我一个接一个地与盒子碰撞时它起作用了,但是当我到达两个墙物体的中间时,我的播放器会开始从墙壁。现在我知道发生了什么事,因为它与一堵墙相撞,它正在减去我的 y 或 x 位置的速度,但是因为我正在与两个相撞,它会减去我移动到我的 x 或 y 的速度的两倍,我是以为我可以只增加 object/player 的 x 或 y 速度,但是当我移动时对象只会减去两次,所以我有点难过。这是我为 "Push Collision type" 和游戏 class 以及玩家 class 和 TestBox class 或 Wall class.[=15= 制作的代码]
碰撞Class:
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;
}
}
}
}
玩家Class:
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);
}
}
测试框Class:
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);
}
}
游戏Class:
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();
}
}
}
解决此问题的一种方法是:
- 当检测到碰撞时,将其添加到 "detected collisions" 的队列中,该队列应包含碰撞框数据。
- 检测到所有碰撞并将其添加到队列后,遍历队列并在每次推送后检查该对象是否仍在与该对象发生碰撞。如果是,计算一个新的推送并应用它。否则,忽略原来的碰撞。
这是我想到的第一个解决方案。如果您对此有任何疑问,请告诉我! :)
所以我和我的朋友们决定制作游戏,所以我决定为游戏创建一个引擎。一切进展顺利,我实现了一种我称之为 "Push Collision" 的碰撞类型,这基本上意味着:当玩家朝向物体移动时,物体采用它在物体上移动的速度并将其减去位置,所以说我我按下 W 或向上箭头,我正在撞墙,墙将采用我的水平速度或 ysp
(Y 速度)并将其减去我的 y 位置。它开始工作,直到我添加了第二个盒子,知道当我一个接一个地与盒子碰撞时它起作用了,但是当我到达两个墙物体的中间时,我的播放器会开始从墙壁。现在我知道发生了什么事,因为它与一堵墙相撞,它正在减去我的 y 或 x 位置的速度,但是因为我正在与两个相撞,它会减去我移动到我的 x 或 y 的速度的两倍,我是以为我可以只增加 object/player 的 x 或 y 速度,但是当我移动时对象只会减去两次,所以我有点难过。这是我为 "Push Collision type" 和游戏 class 以及玩家 class 和 TestBox class 或 Wall class.[=15= 制作的代码]
碰撞Class:
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;
}
}
}
}
玩家Class:
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);
}
}
测试框Class:
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);
}
}
游戏Class:
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();
}
}
}
解决此问题的一种方法是:
- 当检测到碰撞时,将其添加到 "detected collisions" 的队列中,该队列应包含碰撞框数据。
- 检测到所有碰撞并将其添加到队列后,遍历队列并在每次推送后检查该对象是否仍在与该对象发生碰撞。如果是,计算一个新的推送并应用它。否则,忽略原来的碰撞。
这是我想到的第一个解决方案。如果您对此有任何疑问,请告诉我! :)