基于XNA平铺的边界框碰撞-靠墙滑动
我正在使用XNA制作一个简单的基于2d瓷砖的RPG游戏。我制作了一个简单的平铺贴图,其中有一个平铺对象列表,每个平铺对象包含一个矩形。玩家的“我的移动更新”首先创建一个矩形,表示下一帧中的玩家。然后它运行一个foreach循环来检查tile列表中的每个tile是否与播放器矩形相交。如果是,它会将“碰撞布尔”设置为true,并记住玩家将与之碰撞的平铺 如果玩家将发生碰撞,它会设置玩家的位置,以便玩家在进入时触摸瓷砖。我的问题是不可能靠着瓷砖墙“滑动”。例如,如果我同时向下和向左移动,只要我击中一块瓷砖,如果继续向左移动,玩家就会被卡住。你有什么想法可以让我改进这个方法,无论我怎么做,它都能正确运作吗基于XNA平铺的边界框碰撞-靠墙滑动,xna,2d,collision-detection,bounding-box,Xna,2d,Collision Detection,Bounding Box,我正在使用XNA制作一个简单的基于2d瓷砖的RPG游戏。我制作了一个简单的平铺贴图,其中有一个平铺对象列表,每个平铺对象包含一个矩形。玩家的“我的移动更新”首先创建一个矩形,表示下一帧中的玩家。然后它运行一个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;
}
}
}
public void MovementUpdate(键盘状态ks、游戏时间、列表列表)
{
方向=矢量2.0;
矩形nextPosRec;
if(ks.IsKeyDown(key.Right)){
方向X=向右移动;
}
if(ks.IsKeyDown(Keys.Down))
{
方向Y=向下移动_;
}
if(ks.IsKeyDown(Keys.Up))
{
方向Y=向上移动;
}
if(ks.IsKeyDown(Keys.Left)){
方向X=向左移动;
}
Vector2 nextPos=位置;
nextPos+=方向*速度*(浮动)时间.ElapsedGameTime.TotalSeconds;
nextPosRec=新矩形((int)nextPos.X,(int)nextPos.Y,32,32);
bool-colide=false;
Tile ctile=新的Tile(playerTexture,位置,0);
foreach(t列表中的t块)
{
如果(t.tileRectangle.相交(nextPosRec))
{
colide=真;
ctile=t;
}
}
if(colide==false)
{
位置=nextPos;
}
其他的
{
if(位置Yctile.tileRectangle.Bottom)
{
//碰撞底部
位置Y=ctile.tileRectangle.Bottom;
}
if(位置Xctile.tileRectangle.Right)
{
//对撞
位置.X=ctile.tileRectangle.Right;
}
}
}
谢谢你的帮助 您的冲突逻辑中有一些缺陷:
- 您正在忽略多个碰撞,而只处理一个碰撞(与ctile的碰撞)
- 您的碰撞方向逻辑不正确,它会检查是否存在交叉点,但不会检查平铺的哪些边界交叉,这就是粘滞行为的来源
如果你真的在使用一个平铺贴图(一个平铺网格),迭代所有的平铺是非常低效的。您可以只计算哪些磁贴与正在移动的对象相交。这个问题属于gamedev堆栈交换。也许让碰撞成为矢量2?并进行水平和垂直碰撞。