Пример #1
0
 public static Vector2 MovePos(Vector2 position, float width, float height, Vector2 velocity, Room room, out bool collided)
 {
     collided = false;
     if (velocity == Vector2.Zero)
     {
         return position;
     }
     while (velocity != Vector2.Zero)
     {
         Hitbox box = new Hitbox(position, width, height);
         CollideLine? collision = GetNextCollision(box, velocity, room);
         float distance = collision.HasValue ? collision.Value.distance : velocity.Length();
         Vector2 move = velocity;
         move.Normalize();
         move *= distance;
         position += move;
         velocity -= move;
         if (collision.HasValue)
         {
             switch (collision.Value.type)
             {
                 case CollideType.X:
                     velocity.X = 0f;
                     break;
                 case CollideType.Y:
                     velocity.Y = 0f;
                     break;
             }
             collided = true;
         }
     }
     return position;
 }
Пример #2
0
 private static CollideLine? GetNextCollision(Hitbox box, Vector2 velocity, Room room)
 {
     CollideLine? xLine = NextXCollision(box, velocity, room);
     CollideLine? yLine = NextYCollision(box, velocity, room);
     if (!xLine.HasValue)
     {
         return yLine;
     }
     if (!yLine.HasValue)
     {
         return xLine;
     }
     return xLine.Value.distance < yLine.Value.distance ? xLine : yLine;
 }
Пример #3
0
 public bool BoxOnScreen(Hitbox box)
 {
     if (box.topLeft.X > size.X / 2f + camera.X)
     {
         return false;
     }
     if (box.topRight.X < -size.X / 2f + camera.X)
     {
         return false;
     }
     if (box.topLeft.Y > size.Y / 2f + camera.Y)
     {
         return false;
     }
     if (box.bottomLeft.Y * tileSize < -size.Y / 2f + camera.Y)
     {
         return false;
     }
     return true;
 }
Пример #4
0
 private static CollideLine? NextXCollision(Hitbox box, Vector2 velocity, Room room)
 {
     if (velocity.X > 0f)
     {
         int x = (int)Math.Ceiling(box.topRight.X / tileSize);
         x = Math.Max(x, 0);
         int end = (int)Math.Floor((box.topRight.X + velocity.X) / tileSize);
         while (x <= end && x < room.width)
         {
             float xDistance = tileSize * x - box.topRight.X;
             float yDistance = xDistance / velocity.X * velocity.Y;
             int y = (int)Math.Floor((box.topRight.Y + yDistance) / tileSize);
             y = Math.Max(y, 0);
             int yEnd = (int)Math.Ceiling((box.bottomRight.Y + yDistance) / tileSize) - 1;
             while (y <= yEnd && y < room.height)
             {
                 if (SolidTile(room.tiles[x, y]))
                 {
                     return new CollideLine
                     {
                         type = CollideType.X,
                         position = x * tileSize,
                         start = y * tileSize,
                         end = (y + 1) * tileSize,
                         distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance)
                     };
                 }
                 y++;
             }
             x++;
         }
     }
     else if (velocity.X < 0f)
     {
         int x = (int)Math.Floor(box.topLeft.X / tileSize);
         x = Math.Min(x, room.width);
         int end = (int)Math.Ceiling((box.topLeft.X + velocity.X) / tileSize);
         while (x >= end && x > 0)
         {
             float xDistance = tileSize * x - box.topLeft.X;
             float yDistance = xDistance / velocity.X * velocity.Y;
             int y = (int)Math.Floor((box.topLeft.Y + yDistance) / tileSize);
             y = Math.Max(y, 0);
             int yEnd = (int)Math.Ceiling((box.bottomLeft.Y + yDistance) / tileSize) - 1;
             while (y <= yEnd && y < room.height)
             {
                 if (SolidTile(room.tiles[x - 1, y]))
                 {
                     return new CollideLine
                     {
                         type = CollideType.X,
                         position = x * tileSize,
                         start = y * tileSize,
                         end = (y + 1) * tileSize,
                         distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance)
                     };
                 }
                 y++;
             }
             x--;
         }
     }
     return null;
 }
Пример #5
0
 private static CollideLine? NextYCollision(Hitbox box, Vector2 velocity, Room room)
 {
     if (velocity.Y > 0f)
     {
         int y = (int)Math.Ceiling(box.bottomLeft.Y / tileSize);
         y = Math.Max(y, 0);
         int end = (int)Math.Floor((box.bottomLeft.Y + velocity.Y) / tileSize);
         while (y <= end && y < room.height)
         {
             float yDistance = tileSize * y - box.bottomLeft.Y;
             float xDistance = yDistance / velocity.Y * velocity.X;
             int x = (int)Math.Floor((box.bottomLeft.X + xDistance) / tileSize);
             x = Math.Max(x, 0);
             int xEnd = (int)Math.Ceiling((box.bottomRight.X + xDistance) / tileSize) - 1;
             while (x <= xEnd && x < room.width)
             {
                 if (SolidTile(room.tiles[x, y]))
                 {
                     return new CollideLine
                     {
                         type = CollideType.Y,
                         position = y * tileSize,
                         start = x * tileSize,
                         end = (x + 1) * tileSize,
                         distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance)
                     };
                 }
                 x++;
             }
             y++;
         }
     }
     else if (velocity.Y < 0f)
     {
         int y = (int)Math.Floor(box.topLeft.Y / tileSize);
         y = Math.Min(y, room.height);
         int end = (int)Math.Ceiling((box.topLeft.Y + velocity.Y) / tileSize);
         while (y >= end && y > 0)
         {
             float yDistance = tileSize * y - box.topLeft.Y;
             float xDistance = yDistance / velocity.Y * velocity.X;
             int x = (int)Math.Floor((box.bottomLeft.X + xDistance) / tileSize);
             x = Math.Max(x, 0);
             int xEnd = (int)Math.Ceiling((box.bottomRight.X + xDistance) / tileSize) - 1;
             while (x <= xEnd && x < room.width)
             {
                 if (SolidTile(room.tiles[x, y - 1]))
                 {
                     return new CollideLine
                     {
                         type = CollideType.Y,
                         position = y * tileSize,
                         start = x * tileSize,
                         end = (x + 1) * tileSize,
                         distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance)
                     };
                 }
                 x++;
             }
             y--;
         }
     }
     return null;
 }