Example #1
0
        protected void ApplyGravity()
        {
            Rectangle futurePosition = new Rectangle(CollisionBox.X, CollisionBox.Y - VelocityY, CollisionBox.Width, CollisionBox.Height);

            Collision.LineSegment intersectedPlatform = CollisionUtils.IntersectsWithSlopedPlatforms(futurePosition) ?? CollisionUtils.IntersectsWithAxisAlignedPlatforms(futurePosition);

            if (intersectedPlatform == null)
            {
                SetCollisionBoxY(CollisionBox.Y - VelocityY);
                IsGrounded = false;
                IsFalling  = true;
            }
            else
            {
                if (intersectedPlatform.IsSloped)
                {
                    do
                    {
                        // Set the incline angle
                        if ((intersectedPlatform.IsAscending && CollisionBox.Y + CollisionBox.Height < intersectedPlatform.PointB.Y) ||
                            (!intersectedPlatform.IsAscending && CollisionBox.Y + CollisionBox.Height < intersectedPlatform.PointA.Y))
                        {
                            // Don't apply incline angle if we are completely above the platform
                            InclineAngle = 0;
                        }
                        else
                        {
                            InclineAngle = intersectedPlatform.IsAscending
                                ? Maths.DegreesToRadians(360) - intersectedPlatform.InclineAngleWithX
                                : intersectedPlatform.InclineAngleWithX;
                        }
                        // Check for collision a little higher
                        futurePosition.Y   -= Math.Abs(StartingVelocityY * 0.1f);
                        intersectedPlatform = CollisionUtils.IntersectsWithSlopedPlatforms(futurePosition);
                    }while (intersectedPlatform != null);

                    SetCollisionBoxY(futurePosition.Y);
                }
                else
                {
                    InclineAngle = 0;
                    float distanceToPlatform = intersectedPlatform.PointA.Y - (CollisionBox.Y + CollisionBox.Height) - 1;
                    SetCollisionBoxY(CollisionBox.Y + distanceToPlatform);
                }
                IsGrounded = true;
                IsFalling  = false;
            }
        }
Example #2
0
        protected void ManageHorizontalMovement(Rectangle futurePosition)
        {
            Collision.LineSegment intersectedPlatform = CollisionUtils.IntersectsWithPlatforms(futurePosition);

            if (intersectedPlatform == null)
            {
                SetCollisionBoxX(futurePosition.X);
                InclineAngle = 0;
            }
            else
            {
                if (intersectedPlatform.IsSloped)
                {
                    do
                    {
                        // Set the incline angle
                        InclineAngle = intersectedPlatform.InclineAngleWithX;
                        // Check for collision a little higher
                        futurePosition.Y   -= 3;
                        intersectedPlatform = CollisionUtils.IntersectsWithSlopedPlatforms(futurePosition);
                    }while (intersectedPlatform != null);

                    // Proceed forward and climb the slope
                    SetCollisionBoxX(futurePosition.X);
                    SetCollisionBoxY(futurePosition.Y);
                }
                else
                {
                    // If there is a step smaller than your horizontal velocity, climb it
                    if ((CollisionBox.Y + CollisionBox.Height) - intersectedPlatform.PointA.Y - 1 <= Math.Abs(VelocityX))
                    {
                        SetCollisionBoxX(futurePosition.X);
                        SetCollisionBoxY(intersectedPlatform.PointA.Y - CollisionBox.Height - 1);
                    }
                    // Else don't move, because the movement is invalid
                }
            }
        }
Example #3
0
        /// <summary>
        /// The main logic for the Traverse Magic Flow action.
        /// When triggered, if Midori is colliding with the first or last segment of a Magic Flow, she will start traversing it.
        /// While traversing, Midori becomes a small pink sphere and is uncontrollable.
        /// The pink sphere is in the center of Midori's CollisionBox.
        /// When she reaches the end of the flow she turns back to normal and the player regains control.
        /// </summary>
        public void Action_TraverseMagicFlow()
        {
            Collision.LineSegment currentSegment = CurrentMagicFlow.Segments[CurrentMagicFlowSegmentIndex];

            Vector2 sourcePoint;
            Vector2 destinationPoint;

            if (CurrentMagicFlow.TraverseFirstToLast)
            {
                sourcePoint      = currentSegment.PointA;
                destinationPoint = currentSegment.PointB;
            }
            else
            {
                sourcePoint      = currentSegment.PointB;
                destinationPoint = currentSegment.PointA;
            }

            // Solution with vectors
            //Vector2 v = destinationPoint - CollisionBox.Center;
            //float vLength = (float) Math.Sqrt(Math.Pow(v.X, 2) + Math.Pow(v.Y, 2));

            //Vector2 u = v / vLength;
            //Vector2 newCenterPosition = CollisionBox.Center + (_magicFlowVelocity * u);

            // Solution with distance percentage
            // t = distanceWeWantToTraverseOnTheSegment / totalDistanceOfThatSegment
            float t = _magicFlowVelocity / currentSegment.Length;

            // Add up the t values for the current segment
            MagicFlowCurrentSegmentProgress += t;

            // A value of 1 means 100% of the line will be traversed so we make sure it's not more
            if (MagicFlowCurrentSegmentProgress > 1)
            {
                MagicFlowCurrentSegmentProgress = 1;
            }

            // The new position for the center of the CollisionBox
            Vector2 newCenterPosition = new Vector2(
                ((1 - MagicFlowCurrentSegmentProgress) * sourcePoint.X) + (MagicFlowCurrentSegmentProgress * destinationPoint.X),
                ((1 - MagicFlowCurrentSegmentProgress) * sourcePoint.Y) + (MagicFlowCurrentSegmentProgress * destinationPoint.Y)
                );

            // Debug print
            //Collision.LineSegment debugSegment = new Collision.LineSegment(
            //    CurrentMagicFlow.TraverseFirstToLast ? currentSegment.PointA : currentSegment.PointB,
            //    newCenterPosition
            //);
            //Console.WriteLine($"Delta from source point {debugSegment.Length}; t = {MagicFlowCurrentSegmentProgress}; Distance = {currentSegment.Length}");

            // If the destination is reached
            if (newCenterPosition.X == destinationPoint.X && newCenterPosition.Y == destinationPoint.Y)
            {
                // If there are more lines, go to the next one
                if (CurrentMagicFlow.TraverseFirstToLast && CurrentMagicFlowSegmentIndex + 1 < CurrentMagicFlow.Segments.Count)
                {
                    CurrentMagicFlowSegmentIndex += 1;
                }
                else if (!CurrentMagicFlow.TraverseFirstToLast && CurrentMagicFlowSegmentIndex > 0)
                {
                    CurrentMagicFlowSegmentIndex -= 1;
                }
                // If not, end the Magic Flow sequence
                else
                {
                    CurrentMagicFlow  = null;
                    IsMagicFlowActive = false;
                    IsUnableToMove    = false;
                }

                MagicFlowCurrentSegmentProgress = 0;
            }

            SetCollisionBoxX(newCenterPosition.X - (CollisionBox.Width / 2));
            SetCollisionBoxY(newCenterPosition.Y - (CollisionBox.Height / 2));
        }
Example #4
0
        protected void ManageMovement()
        {
            if (IsUnableToMove)
            {
                return;
            }

            Room  currentRoom = GameContext.Scene.LoadedRoom;
            float newVelocity = VelocityX * RunTimer.Progress;

            if (IsMovingLeft)
            {
                // Make sure movement is within the room borders
                if (CollisionBox.X > 0 + newVelocity)
                {
                    Rectangle futurePosition = new Rectangle(CollisionBox.X - newVelocity, CollisionBox.Y, CollisionBox.Width, CollisionBox.Height);
                    ManageHorizontalMovement(futurePosition);
                }
                else
                {
                    SetCollisionBoxX(0);
                    IsMovingLeft = false;
                    IsIdle       = true;
                }
            }

            if (IsMovingRight)
            {
                // Make sure movement is within the room borders
                if (CollisionBox.X + CollisionBox.Width < currentRoom.Size.X - newVelocity)
                {
                    Rectangle futurePosition = new Rectangle(CollisionBox.X + newVelocity, CollisionBox.Y, CollisionBox.Width, CollisionBox.Height);
                    ManageHorizontalMovement(futurePosition);
                }
                else
                {
                    SetCollisionBoxX(currentRoom.Size.X - CollisionBox.Width);
                    IsMovingRight = false;
                    IsIdle        = true;
                }
            }

            if (IsJumping)
            {
                if (JumpTimer.Finished && !IsFalling)
                {
                    IsFalling = true;
                    JumpTimer.GoNormal();
                }

                if (IsFalling)
                {
                    VelocityY = StartingVelocityY;
                }

                Rectangle             futurePosition      = new Rectangle(CollisionBox.X, CollisionBox.Y - (JumpTimer.Progress * VelocityY), CollisionBox.Width, CollisionBox.Height);
                Collision.LineSegment intersectedPlatform = CollisionUtils.IntersectsWithPlatforms(futurePosition);
                if (intersectedPlatform == null)
                {
                    SetCollisionBoxY(CollisionBox.Y - JumpTimer.Progress * VelocityY);
                }
                else
                {
                    IsJumping  = false;
                    IsFalling  = false;
                    IsGrounded = true;
                    JumpTimer.End();
                    //Y = 580;
                }
            }
            else
            {
                VelocityY = StartingVelocityY;
                ApplyGravity();
            }
        }
Example #5
0
 /// <summary>
 /// Adds the given segment to the list of segments and updates the total length.
 /// </summary>
 /// <param name="segment"></param>
 public void AddSegment(Collision.LineSegment segment)
 {
     Segments.Add(segment);
     Length += segment.Length;
 }