这可能很简单,但它给了我很多的悲伤,我想知道你们是否能够对它有所了解。基本上我有一个瓦片地图,它以64 * 64绘制瓦片并且效果非常好,它们在game1类中以2D数组绘制。
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,}
});
现在出现了问题。基本上我想确定玩家从哪个方面击中了牌。但是,使用下面的算法,碰撞仅适用于底部和左侧。如果玩家从顶部击中了瓷砖,它将说明它是从底部击中的。如果玩家从右侧击中它将指定左侧被击中。如果玩家从顶部或右侧击中,它将显示碰撞已经发生,但是说它发生在它的底部或左侧。 它将输出图块的顶部已被命中,但仅当玩家完全位于图块时。
当它显示右侧被击中时(玩家向上移动的位置比上图略高),发生了同样的事情。
tilemap的
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;
}
玩家界限位于玩家类更新方法中,该方法继承自精灵类。
public override void Update(GameTime gameTime)
{
playerBounds = new Rectangle((int)Position.X, (int)Position.Y, 50, 50);
}
该职位继承自精灵课程
protected Vector2 position;
public Vector2 Position
{
get { return position; }
set { position = value; }
}
非常感谢任何帮助。
谢谢。
答案 0 :(得分:0)
我们的坐标系是OY轴从上到下,玩家的中心位置为PX,PY,半宽PW,半高PH,方向矢量DX,DY。
以TX,TY,半宽TW,半高TH为中心的平铺矩形。
当玩家的中心点在第一次遇到Minkowski的总和矩形时(t是时间参数),玩家会触摸平铺
CX = PX + DX * t
CY = PX + DY * t
if DY >= 0 then //moving down
t1 = (TY - TH - PH - PY) / DY //time to meet horizontal edge
else //moving up
t1 = (TY + TH + PH - PY) / DY
if DX >= 0 then //moving right
t2 = (TX - TW - PW - PX) / DX //time to meet vertical edge
else //moving left
t2 = (TX + TW + PW - PX) / DX
if t1 <= t2 then
if DY >= 0 then
touches top edge first
else
touches bottom edge first
else
if DX >= 0 then
touches left edge first
else
touches right edge first
//you can consider corner touches (t1=t2) separately