【发布时间】:2016-12-29 18:56:25
【问题描述】:
这可能真的很简单,但它让我很伤心,我想知道你们是否能够对此有所了解。基本上我有一个瓷砖贴图,它以 64 * 64 的尺寸绘制瓷砖,效果很好,它们在 game1 类中绘制在一个像这样的二维数组中。
TileMap tileMap = new TileMap(new int[,]
{
{ 2,2,2,2,2,2,2,2,2,2 },
{ 2,2,2,2,2,2,2,2,2,2 },
{ 0,0,0,0,0,0,4,4,4,4 },
{ 0,0,0,0,0,0,1,1,4,4 },
{ 1,1,1,1,1,1,1,1,1,1,},
{ 1,1,1,1,1,1,1,1,1,1,}
});
现在问题来了。基本上我想确定玩家从哪一侧击中瓷砖。但是,使用下面的算法,碰撞仅适用于底部和左侧。如果玩家从顶部击中瓷砖,它将声明它是从底部击中的。如果玩家从右侧击中,它将指定左侧被击中。如果玩家从顶部或右侧击中,它将显示碰撞已经发生,但说明它发生在底部或左侧。 它会输出图块的顶部已经被击中,但只有当玩家完全在图块中时才会这样。
当它显示右侧被击中时会发生几乎相同的事情(玩家比上图稍微向左移动)
平铺地图
int left = (int)Math.Floor((float)player.playerBounds.Left / TILE_WIDTH);
int top = (int)Math.Floor((float)player.playerBounds.Top / TILE_HEIGHT);
int right = (int)Math.Ceiling((float)player.playerBounds.Right / TILE_WIDTH) - 1;
int bottom = (int)Math.Ceiling((float)player.playerBounds.Bottom / TILE_HEIGHT) - 1;
Rectangle tileBounds = new Rectangle((int)tilePosX, (int)tilePosY, TILE_WIDTH, TILE_HEIGHT);
Rectangle playerBounds = player.playerBounds;
float WidthOfRects = 0.5f * (playerBounds.Width + tileBounds.Width);
float heightOfRects = 0.5f * (playerBounds.Height + tileBounds.Height);
int centerX = (playerBounds.Left + playerBounds.Width / 2) - (tileBounds.Left + tileBounds.Width / 2);
int centerY = (playerBounds.Top + playerBounds.Height / 2) - (tileBounds.Top + tileBounds.Height / 2);
for (int y = top; y <= bottom; ++y)
{
for (int x = left; x <= right; ++x)
{
if (mapCell[y, x].TileID == 1)
{
//minkowski sum
if (Math.Abs(centerX) <= WidthOfRects && Math.Abs(centerY) <= heightOfRects)
{
double wy = WidthOfRects * centerY;
double hx = heightOfRects * centerX;
if (wy > hx)
{
if (wy > -hx)
{
Console.WriteLine("bottom");
//newPos.Y = tileCollision.Bottom;
}
else
{
Console.WriteLine("right");
//newPos.X = tileCollision.Right;
}
}
if (wy > -hx)
{
Console.WriteLine("left ");
//newPos.X = tileCollision.Left - playerBounds.Width;
}
else
{
Console.WriteLine("top");
//newPos.Y = tileCollision.Top - playerBounds.Height;
}
}
// player.Position = newPos;
}
}
}
地图单元
public class MapCell
{
public int TileID { get; set; }
public MapCell(int tileID)
{
TileID = tileID;
}
播放器边界在继承自 sprite 类的 播放器类更新方法中。
public override void Update(GameTime gameTime)
{
playerBounds = new Rectangle((int)Position.X, (int)Position.Y, 50, 50);
}
位置继承自sprite类
protected Vector2 position;
public Vector2 Position
{
get { return position; }
set { position = value; }
}
任何帮助将不胜感激。
谢谢。
【问题讨论】:
标签: c# xna geometry collision-detection