我正在使用XNA制作一个简单的基于2d tile的RPG游戏 . 我已经制作了一个简单的瓷砖 Map ,其中包含每个瓷砖包含矩形的瓷砖对象列表 . 我对玩家的移动更新首先创建一个矩形,表示下一帧中的玩家 . 然后它运行一个foreach循环来检查tile列表中的每个tile是否与播放器矩形相交 . 如果是这样,它会将碰撞的布尔值设置为true,并且还会记住玩家将与之碰撞的图块 .
如果玩家将发生碰撞,它会设置玩家位置,以便玩家触摸进入玩家的区块 . 我遇到的问题是,不可能“滑动”在瓷砖墙上 . 例如,如果我向下移动并同时向左移动,一旦我击中了一块牌,如果继续向左移动,则该牌手会被卡住 . 你有什么想法我怎么能改进这个方法所以无论我如何移动它都会正确行事?
public void MovementUpdate(KeyboardState ks, GameTime time, List<Tile> tlist)
{
Direction = Vector2.Zero;
Rectangle nextPosRec;
if (ks.IsKeyDown(Keys.Right)){
Direction.X = MOVE_RIGHT;
}
if (ks.IsKeyDown(Keys.Down))
{
Direction.Y = MOVE_DOWN;
}
if (ks.IsKeyDown(Keys.Up))
{
Direction.Y = MOVE_UP;
}
if (ks.IsKeyDown(Keys.Left)){
Direction.X = MOVE_LEFT;
}
Vector2 nextPos = Position ;
nextPos += Direction * Speed * (float)time.ElapsedGameTime.TotalSeconds;
nextPosRec = new Rectangle((int)nextPos.X, (int)nextPos.Y, 32, 32);
bool colide = false;
Tile ctile = new Tile(playerTexture, Position, 0);
foreach (Tile t in tlist)
{
if (t.tileRectangle.Intersects(nextPosRec))
{
colide = true;
ctile = t;
}
}
if (colide == false)
{
Position = nextPos;
}
else
{
if (Position.Y < ctile.tileRectangle.Top - 32)
{
//COLLIDE TOP
Position.Y = ctile.tileRectangle.Top - 32;
}
if(Position.Y > ctile.tileRectangle.Bottom)
{
//COLLIDE BOTTOM
Position.Y = ctile.tileRectangle.Bottom;
}
if (Position.X < ctile.tileRectangle.Left - 32)
{
//COLLIDE LEFT
Position.X = ctile.tileRectangle.Left - 32;
}
if (Position.X > ctile.tileRectangle.Right)
{
//COLLIDE RIGHT
Position.X = ctile.tileRectangle.Right;
}
}
}
感谢帮助!
1 回答
碰撞逻辑中存在一些缺陷:
您忽略多个碰撞并仅处理一个碰撞(与
ctile
碰撞)你的碰撞方向逻辑是不正确的,它会检查是否有一个交叉点,但是没有检查是否有哪个边框交叉,这就是粘贴行为来自的地方
应该为每个相交的图块执行碰撞处理,而不仅仅是您正在进行的最后一个图块 . 在碰撞处理中,您可以将对象移回到它在x和y轴上碰撞的瓷砖中的数量 .
如果你真的使用了瓷砖 Map (瓷砖网格),那么迭代所有瓷砖的效率非常低 . 您可以只计算哪些图块与正在移动的对象相交 .