为什么我的碰撞实现会导致我的玩家在发生碰撞时“反弹”?

我有一个玩家多边形,我用这个方法检查它是否与我的平铺地图相碰撞:

public static boolean playerCollisionWith() { for(int i = 0; i < Blockmap.entities.size(); i++) { Block entity1 = (Block) Blockmap.entities.get(i); if(playerPoly.intersects(entity1.poly)) { return true; } } return false; } 

这将正常工作,但我正在使用不同的方法进行移动。 而不是只为玩家的X轴添加速度variables。 我像这样移动:

 if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { speedX = Math.min(5, speedX + 1); moving = true; playerPoly.setX(x); if(playerCollisionWith()) { speedX = -5; playerPoly.setX(x); } } 

Math.min电话是什么搞砸了我。 我不能直接调用speedX = -5 ,因为当我点击鼠标右键并碰撞时,播放器会“弹跳”。 如同闪烁来来回回, 真的很快。 但是我真的不知道该怎么做才能让Y轴上的碰撞也能起作用,无论玩家是否跳跃。 所以,如果我可以得到一些帮助,如何解决这个问题,这将是伟大的。

编辑:我刚刚意识到的东西,我有这些代码行我敢肯定对我的碰撞问题有很大的影响。

 if(!Keyboard.isKeyDown(Keyboard.KEY_LEFT) && speedX < 0 && !playerCollisionWith()) { speedX = 0f; playerPoly.setX(x); } if(!Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && speedX > 0 && !playerCollisionWith()) { speedX = 0f; playerPoly.setX(x); } 

所以当我撞到墙上,我不再按箭头键的时候,玩家就会漂进墙里,而且都是毛毛病。 对不起,我之前没有说过,我只是做了一些更多的testing。 再次感谢!

Solutions Collecting From Web of "为什么我的碰撞实现会导致我的玩家在发生碰撞时“反弹”?"

问题是speedX = -5; 在这个代码中的赋值:

 if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { speedX = Math.min(5, speedX + 1); moving = true; playerPoly.setX(x); if(playerCollisionWith()) { speedX = -5; // <---- PROBLEM! playerPoly.setX(x); } } 

换句话说,当发生碰撞时,无论角色走向哪个方向或速度如何,都将速度设置为-5。 如果角色向前移动(正向速度为X),它会突然向后跳。 如果以-4至-1的速度向后移动,则突然加速。

弹跳的发生是因为你移动了角色,尽管移动不是有效的。 为了防止这种情况的发生,只有在确认动作是否正常后才能移动角色。

 if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { if(!playerCollisionWith()) { moving = true; speedX = 5; playerPoly.setX(x); } } 

你的角色在帧间的+5和-5之间移动,导致闪烁。 我不确定你正在寻找什么样的效果,所以解决scheme可能会有所不同。

首先,为了input,保持简单。 修改速度,让其他functionrest:

 if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) { speedX = Math.min(5, speedX + 1); } 

(注意:因为你加1来加速每一帧,字符加速的速率将取决于帧速率,这意味着它只能在预定的固定帧速率下工作。修复这个问题已经超出了这个问题的范围,但基本上你会想让加速/加速成为时间的函数,让你的游戏工作在更慢或更快的帧速率上)

现在你已经有了你的inputfunction。 接下来是更新function。 这里是你实际移动球员的地方,并检查碰撞。 我没有在Java中编程一段时间,所以我对任何语法错误表示歉意:

 public void update() { if (speedX > 0.0f) { // Check if moving right positionX += speedX; // positionX += speedX * delta; // would produce a better result (where // delta is the change in time from the // last frame to this frame) float collisionRight = checkCollisionRight(); // This function checks // collisions to the right, and returns a value for how much the // player is intersection. 0 if not intersecting. if (collisionRight > 0.0f) { // Check if collision, if so, resolve collision positionX -= collisionRight; // Just shift the player back by // the amount intersected speedX = 0.0f; // This stops the player if colliding. If you // want a bounce, the process is more complicated } } } 

明白了吗? 使冲突检测和解决独立于input,以最小化奇怪的行为。 上述情况还不完美(如果玩家如此快速移动,他们最终会穿过墙壁),但这只是一个开始。 如果您想对碰撞检测进行一些阅读,请查找AABB碰撞 ,这是简单碰撞检测最基本和最有效的方法之一。