以下代码是我试图阻止PC(玩家角色)走过NPC。
代码:
if (PC.charSprite.BoundingBox.Intersects(npc.charSprite.BoundingBox))
{
Rectangle collisionBox = Rectangle.Intersect(PC.charSprite.BoundingBox, npc.charSprite.BoundingBox);
if (PC.moveDir.X > 0) //Moving Right
{
//Unknown Code Goes Here
}
else if (PC.moveDir.X < 0) //Moving Left
{
}
else if (PC.moveDir.Y > 0) //Moving Down
{
}
else if (PC.moveDir.Y < 0) //Moving Up
{
}
}
如何使PC在触摸NPC时,PC停止向该方向移动,但可以自由移动其他三个方向?
我尝试过的代码:
if (PC.moveDir.X > 0) //Moving Right
{
PC.moveDir = Vector2.Zero;
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.moveDir = Vector2.Zero;
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.moveDir = Vector2.Zero;
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.moveDir = Vector2.Zero;
}
^这会将PC锁定到位,防止任何和所有移动。
if (PC.moveDir.X > 0) //Moving Right
{
PC.moveDir.X = 0;
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.moveDir.X = 0;
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.moveDir.Y = 0;
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.moveDir.Y = 0;
}
^这也将PC锁定到位。
if (PC.moveDir.X > 0) //Moving Right
{
PC.moveDir.X = -currentspeed;
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.moveDir.X = currentspeed;
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.moveDir.Y = -currentspeed;
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.moveDir.Y = currentspeed;
}
^这是非常间歇性的。我曾希望通过将moveDir更改为与其重叠(或更大)的相反方向将PC保持在NPC的边缘但防止重叠。不幸的是,有一半时间电脑卡到位。
结合两个
if (PC.moveDir.X > 0) //Moving Right
{
PC.moveDir.X = -currentspeed;
PC.moveDir.X = 0;
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.moveDir.X = currentspeed;
PC.moveDir.X = 0;
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.moveDir.Y = -currentspeed;
PC.moveDir.Y = 0;
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.moveDir.Y = currentspeed;
PC.moveDir.Y = 0;
}
只是导致整体锁定。
if (PC.moveDir.X > 0) //Moving Right
{
PC.moveDir.X = -collisionBox.Width;
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.moveDir.X = collisionBox.Width;
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.moveDir.Y = -collisionBox.Height;
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.moveDir.Y = collisionBox.Height;
}
^这个几乎完美地工作,但是当PC对抗NPC并且垂直于它接触的NPC时,PC会跳到一边。再次,大约一半的时间。
受到CSJ评论的启发:
if (PC.charSprite.BoundingBox.Intersects(npc.charSprite.BoundingBox))
{
Rectangle collisionBox = Rectangle.Intersect(PC.charSprite.BoundingBox, npc.charSprite.BoundingBox);
if (PC.moveDir.X > 0) //Moving Right
{
PC.charSprite.Position = new Vector2(npc.charSprite.BoundingBox.Left - 34, PC.charSprite.Position.Y);
}
else if (PC.moveDir.X < 0) //Moving Left
{
PC.charSprite.Position = new Vector2(npc.charSprite.BoundingBox.Right + 2, PC.charSprite.Position.Y);
}
else if (PC.moveDir.Y > 0) //Moving Down
{
PC.charSprite.Position = new Vector2(PC.charSprite.Position.X, npc.charSprite.BoundingBox.Top - 34);
}
else if (PC.moveDir.Y < 0) //Moving Up
{
PC.charSprite.Position = new Vector2(PC.charSprite.Position.X, npc.charSprite.BoundingBox.Bottom + 2)
}
}
我再问一遍:我怎么做到这样当PC接触NPC时,PC停止向那个方向移动但是可以自由移动其他三个方向?
或者,在更通用的术语中,如何使一个与另一个Rectangle相交的Rectangle失去其向相交的矩形移动的能力,而不会妨碍它在任何其他方向上的移动?
答案 0 :(得分:1)
我在这种情况下所做的是:
它可能不是运行速度最快的解决方案,但它可以完成工作。当有许多可能发生碰撞的动态事物时,效果很好。
答案 1 :(得分:0)
在[i]多次[/ i]头部撞击和喝酒后,我终于想出了一个解决方案。我甚至将它放入一个班级,以便其他人可以用它来帮助他们解决类似的问题。
class Collision
{
#region Declarations
private Rectangle rectangle1;
private Rectangle rectangle2;
private Rectangle collisionZone;
#endregion
#region Constructors
public Collision(Rectangle R1, Rectangle R2)
{
rectangle1 = R1;
rectangle2 = R2;
if(AreColliding())
{
collisionZone = Rectangle.Intersect(rectangle1, rectangle2);
}
else
{
collisionZone = Rectangle.Empty;
}
}
#endregion
#region Properties
/// <summary>
/// Returns the x-axis value of the top-left corner of R1
/// </summary>
public int TopLeftR1X
{
get { return rectangle1.X; }
}
/// <summary>
/// Returns the y-axis value of the top-left corner of R1
/// </summary>
public int TopLeftR1Y
{
get { return rectangle1.Y; }
}
/// <summary>
/// Returns the x-axis value of the top-right corner of R1
/// </summary>
public int TopRightR1X
{
get { return rectangle1.X + rectangle1.Width; }
}
/// <summary>
/// Returns the y-axis value of the top-right corner of R1
/// </summary>
public int TopRightR1Y
{
get { return rectangle1.Y; }
}
/// <summary>
/// Returns the x-axis value of the bottom-left corner of R1
/// </summary>
public int BottomLeftR1X
{
get { return rectangle1.X; }
}
/// <summary>
/// Returns the y-axis value of the bottom-left corner of R1
/// </summary>
public int BottomLeftR1Y
{
get { return rectangle1.Y + rectangle1.Height; }
}
/// <summary>
/// Returns the x-axis value of the bottom-right corner of R1
/// </summary>
public int BottomRightR1X
{
get { return rectangle1.X + rectangle1.Width; }
}
/// <summary>
/// Returns the y-axis value of the bottom-right corner of R1
/// </summary>
public int BottomRightR1Y
{
get { return rectangle1.Y + rectangle1.Height; }
}
/// <summary>
/// Returns the x-axis value of the top-left corner of R2
/// </summary>
public int TopLeftR2X
{
get { return rectangle2.X; }
}
/// <summary>
/// Returns the y-axis value of the top-left corner of R2
/// </summary>
public int TopLeftR2Y
{
get { return rectangle2.Y; }
}
/// <summary>
/// Returns the x-axis value of the top-right corner of R2
/// </summary>
public int TopRightR2X
{
get { return rectangle2.X + rectangle2.Width; }
}
/// <summary>
/// Returns the y-axis value of the top-right corner of R2
/// </summary>
public int TopRightR2Y
{
get { return rectangle2.Y; }
}
/// <summary>
/// Returns the x-axis value of the bottom-left corner of R2
/// </summary>
public int BottomLeftR2X
{
get { return rectangle2.X; }
}
/// <summary>
/// Returns the y-axis value of the bottom-left corner of R2
/// </summary>
public int BottomLeftR2Y
{
get { return rectangle2.Y + rectangle2.Height; }
}
/// <summary>
/// Returns the x-axis value of the bottom-right corner of R2
/// </summary>
public int BottomRightR2X
{
get { return rectangle2.X + rectangle2.Width; }
}
/// <summary>
/// Returns the y-axis value of the bottom-right corner of R2
/// </summary>
public int BottomRightR2Y
{
get { return rectangle2.Y + rectangle2.Height; }
}
/// <summary>
/// Returns the rectangle formed by how much the rectangles overlap.
/// </summary>
public Rectangle Overlap
{
get { return collisionZone; }
}
#endregion
#region Methods
public bool AreColliding()
{
if (rectangle1.Intersects(rectangle2))
{
return true;
}
else
{
return false;
}
}
public Vector2 StopOnCollision(Vector2 position, Vector2 moveDir, int currentspeed)
{
if (Overlap.Width < Overlap.Height)
{
if (position.X < rectangle2.Left)
{
if (moveDir.X > 0) //Moving Right
{
moveDir = Vector2.Zero;
}
else
{
moveDir.X = -currentspeed;
moveDir.Y = 0;
}
}
//else if ((position.X + 33) > rectangle2.Right)
else if (position.X < rectangle2.Right)
{
if (moveDir.X < 0) //Moving Left
{
moveDir = Vector2.Zero;
}
else
{
moveDir.X = currentspeed;
moveDir.Y = 0;
}
}
}
else
{
if (Overlap.Y == rectangle2.Top)
{
if (moveDir.Y > 0) //Moving Down
{
moveDir = Vector2.Zero;
}
else
{
moveDir.Y = -currentspeed;
moveDir.X = 0;
}
}
else
{
if (moveDir.Y < 0) //Moving Up
{
moveDir = Vector2.Zero;
}
else
{
moveDir.Y = currentspeed;
moveDir.X = 0;
}
}
}
return moveDir;
}
#endregion
}
这有点简单: - 使用要检查的两个碰撞框(矩形)实例化类。 - 您可以检查以确保它们实际上是碰撞的。 - 要使用StopOnCollision,您可以输入任何移动的位置(参考的x,y坐标),您希望用来改变或阻止其移动的矢量,以及物体移动的速度(每帧的像素数) )
我希望这能帮助其他所有人,就像它帮助我一样