Exemplo n.º 1
0
        // Attempt to dodge a collision.
        private bool PerformCollisionDodge(Entity entity, int direction, object solidObject, Rectangle2F solidBox)
        {
            // Only dodge if moving perpendicular to the edge.
            int axis = Directions.ToAxis(direction);
            if (Math.Abs(entity.Physics.Velocity[1 - axis]) > 0.001f)
                return false;

            // Can't dodge moving tiles.
            if ((solidObject is Tile) && ((Tile) solidObject).IsMoving)
                return false;

            Rectangle2F entityBox = entity.Physics.PositionedCollisionBox;
            float penetrationDistance = GetClipPenetration(
                entity.Physics.PositionedCollisionBox, solidBox, direction);

            // Check dodging for both edges of the solid object.
            for (int side = 0; side < 2; side++) {
                int moveDirection = (direction + (side == 0 ? 1 : 3)) % 4;
                float distanceToEdge = Math.Abs(entityBox.GetEdge(
                    Directions.Reverse(moveDirection)) - solidBox.GetEdge(moveDirection));

                // Check if the distance to the edge is within dodge range.
                if (distanceToEdge <= entity.Physics.AutoDodgeDistance) {
                    float moveAmount = Math.Min(entity.Physics.AutoDodgeSpeed, distanceToEdge);

                    Vector2F nextPosition = GMath.Round(entity.Position) +
                        (Directions.ToVector(moveDirection) * moveAmount);
                    Vector2F goalPosition = entity.Position + Directions.ToVector(direction) +
                        (Directions.ToVector(moveDirection) * distanceToEdge);

                    // Make sure the entity is not colliding when placed at the solid object's edge.
                    if (!IsCollidingAt(entity, nextPosition, false, direction, penetrationDistance) &&
                        !IsCollidingAt(entity, goalPosition, false, direction, penetrationDistance))
                    {
                        entity.Position += Directions.ToVector(moveDirection) * moveAmount;
                        entity.Physics.CollisionInfo[direction].IsAutoDodged = true;
                        //entity.Physics.MovementCollisions[direction] = false; // TODO: Figure out complications for removing this.
                        return true;
                    }
                }
            }

            return false;
        }
Exemplo n.º 2
0
 // Returns true if two rectangles share an edge in the given direction.
 public static bool AreEdgesAligned(Rectangle2F box1, Rectangle2F box2, int edgeDirection)
 {
     return Math.Abs(box1.GetEdge(edgeDirection) - box2.GetEdge(edgeDirection)) < 0.1f;
 }
Exemplo n.º 3
0
        private bool PerformCollisionDodge(Rectangle2F block, int direction)
        {
            float		dodgeDist	= autoDodgeDistance;
            Rectangle2F	objBox		= Rectangle2F.Translate(collisionBox, entity.Position);
            Vector2F	pos			= entity.Position;
            Vector2F	dirVect		= Directions.ToVector(direction);

            for (int side = 0; side < 2; side++) {
                int moveDir		= (direction + (side == 0 ? 1 : 3)) % 4;
                float distance	= Math.Abs(objBox.GetEdge((moveDir + 2) % 4) - block.GetEdge(moveDir));

                if (distance <= dodgeDist) {
                    Vector2F checkPos	= pos + dirVect + (Directions.ToVector(moveDir) * distance);
                    Vector2F gotoPos	= GMath.Round(pos) + Directions.ToVector(moveDir);

                    if (!IsPlaceMeetingSolid(checkPos, collisionBox) &&
                        !IsPlaceMeetingSolid(gotoPos, collisionBox))
                    {
                        entity.Position = gotoPos;
                        return true;
                    }
                }
            }
            return false;
        }