私は何日もこれについて頭を悩ませてきました。エンティティを更新するとき、衝突をチェックし、以下のコードに従って衝突する場合、適切なモーション値が 0 に設定されます。何らかの理由を除いて、このコードは右側の衝突をチェックするために機能しません。エンティティの前に高さ 2 の壁がある場合、エンティティはそれを無視します。ただ、その下を確認するとちゃんと動いているように見えますが、完全に止まってしまいます。
衝突コード:
public static bool CollidesRight(Level level, Vector2 position, Vector2 motion, int width, int height)
{
Vector2 result = position + motion;
int x1 = (int)(result.X / (float)Tile.TILE_WIDTH);
int x2 = (int)((result.X + (float)width) / (float)Tile.TILE_WIDTH) + 1;
int y1 = (int)(result.Y / (float)Tile.TILE_HEIGHT);
int y2 = (int)((result.Y + (float)height) / (float)Tile.TILE_HEIGHT);
AABB resultBB = new AABB(result, width, height);
for (int i = x1; i < x2; i++)
{
for (int j = y1; j < y2; j++)
{
if (level.GetTileAt(i, j) != 0 && (Tile.TileList[level.GetTileAt(i, j)].IsSolid() || Tile.TileList[level.GetTileAt(i, j)].HasSolidTop()))
{
AABB tile = new AABB(new Vector2(i * 64f, j * 64f), 64, 64);
Console.WriteLine(tile);
return resultBB.Intersects(tile);
}
}
}
return false;
}
これが私のエンティティの更新コードです:
public virtual void Tick()
{
lastMotion = motion;
lastPosition = position;
if (Collision.CollidesBottom(level, position, motion, width, height))
{
onGround = true;
}
else if(!Collision.CollidesBottom(level, position, motion, width, height))
{
onGround = false;
}
if (onGround && !isJumping)
{
motion.Y = 0f;
fallDistance = 0;
}
else if(!onGround)
{
fallDistance++;
motion.Y += gravity * (fallDistance * 0.005f);
}
if (isJumping)
{
timeJumping++;
if (timeJumping > 32)
{
timeJumping = 0;
isJumping = false;
}
else
{
motion.Y = -2.25f;
}
}
position.Y += motion.Y;
if (motion.X != 0)
{
if (motion.X < 0)
{
motion.X += friction;
}
if (motion.X > 0)
{
motion.X -= friction;
}
}
if ((motion.X > 0 && Collision.CollidesRight(level, position, motion, width, height)) || (motion.X < 0 && Collision.CollidesLeft(level, position, motion, width, height)))
{
motion.X = 0f;
}
position.X += motion.X;
//MoveEntity(motion);
}