我使用Libgdx制作了Pacman克隆,我遇到了碰撞问题。
我带来了瓷砖编辑器中制作的方形物体,以确定墙壁的位置。这是我处理它的地图代码。
public void getMapColliders()
{
MapObjects collisionObjects = new MapObjects();
collisionObjects = map.getLayers().get("Level Boundries").getObjects();
int tileWidth = 16; // whatever your tile width is
int tileHeight = 16; // whatever your tile height is
for (int i = 0; i < collisionObjects.getCount(); i++)
{
RectangleMapObject obj = (RectangleMapObject) collisionObjects.get(i);
Rectangle rect = obj.getRectangle();
collisionRects.add(new Rectangle((int)rect.x+2,(int) rect.y+16, rect.width , rect.height));
}
}
然后我在我的Pacman精灵周围有一个矩形作为碰撞盒并使用重叠功能来检测碰撞。最初我把它保存在Pacman的最后位置然后向前移动并且如果它检测到碰撞它重置位置。这没有用,而且我被困在墙上,相反,我最终只是向前移动相同数量的运动,但是因为精灵与地图的完美对齐,它总是把Pacman放在一个他无法下降的位置,因为他略微偏向一侧或另一侧。这是代码:
package Components;
import Math.Point2D;
import com.badlogic.gdx.math.Rectangle;
import java.util.ArrayList;
public class Controller
{
/* Variable to store amount entitie position should increase */
private Input input;
private String keyPressed;
private String lastKeyPressed;
private boolean isMoving;
private double speed;
private ArrayList<Rectangle> mapCollisionBoxes;
private Collider pCol;
private boolean rBlocked;
private boolean lBlocked;
private boolean uBlocked;
private boolean dBlocked;
private Point2D prevPos;
//private Point2D movementP;
public Controller(ArrayList<Rectangle> collisions, Collider pCol)
{
input = new Input();
keyPressed = "N";
lastKeyPressed = "N";
isMoving = false;
speed = 40.0;
mapCollisionBoxes = collisions;
this.pCol = pCol;
prevPos = new Point2D();
}
/**
* Check if a movement input is pressed and move accordingly
*
* @param curPos Player's current position
* @param t Delta time
*/
public void move(Point2D curPos, int t)
{
System.out.println("rBlocked: " + rBlocked);
System.out.println("lBlocked: " + lBlocked);
System.out.println("uBlocked: " + uBlocked);
System.out.println("dBlocked: " + dBlocked);
keyPressed = input.checkKeys();
switch (keyPressed)
{
case "RIGHT":
lastKeyPressed = "R";
break;
case "LEFT":
lastKeyPressed = "L";
break;
case "UP":
lastKeyPressed = "U";
break;
case "DOWN":
lastKeyPressed = "D";
break;
case "NONE":
break;
}
switch (lastKeyPressed)
{
case "R":
if (!rBlocked)
{
if (checkForCollision())
{
curPos.setX(curPos.getX() - speed * t / 1000);
rBlocked = true;
}
else
{
curPos.setX(curPos.getX() + speed * t / 1000);
lBlocked = false;
dBlocked = false;
uBlocked = false;
}
}
break;
case "L":
if (!lBlocked)
{
prevPos = curPos;
if (checkForCollision())
{
curPos.setX(Math.round(curPos.getX() + speed * t / 1000));
lBlocked = true;
}
else
{
curPos.setX(curPos.getX() - speed * t / 1000);
rBlocked = false;
uBlocked = false;
dBlocked = false;
}
}
break;
case "U":
if (!uBlocked)
{
if (checkForCollision())
{
curPos.setY(curPos.getY() - speed * t / 1000);
uBlocked = true;
}
else
{
curPos.setY(curPos.getY() + speed * t / 1000);
dBlocked = false;
lBlocked = false;
rBlocked = false;
}
}
break;
case "D":
if (!dBlocked)
{
if (checkForCollision())
{
curPos.setY(Math.round(curPos.getY() + speed * t / 1000));
dBlocked = true;
}
else
{
curPos.setY(curPos.getY() - speed * t / 1000);
uBlocked = false;
lBlocked = false;
rBlocked = false;
}
}
break;
}
}
public String lastKeyPressed()
{
return lastKeyPressed;
}
private boolean checkForCollision()
{
boolean collided = false;
for (Rectangle rect : mapCollisionBoxes)
{
if (pCol.hBox.overlaps(rect))
{
collided = true;
}
}
return collided;
}
}
这一切都是因为我必须使用布尔来检查他碰撞时的方向,否则他在碰到某些东西后再也不会再移动,因为碰撞并不是方向性的。这造成了我在另一场比赛中出现的旧故障,如果我在左侧停下并向右击然后再快速离开,我将略微穿过墙壁。
对此的任何帮助将不胜感激。