Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public void Update()
- {
- bool crushedLeft = false, crushedRight = false, crushedTop = false, crushedBottom = false; // Boolean values to check if the body is "crushed"
- IsCollidingOnBottom = false; // Boolean value to check if the body is on the ground
- List<object[]> invokations = new List<object[]>(); // List of "detection events" invokations
- PositionPrevious = Position; // Sets the previous position to the current position
- if (IsAffectedByGravity) Velocity += World.Gravity; // Adds gravity to velocity
- Position += Velocity; // Adds velocity to position
- List<SSSPBody> bodiesToCheck = World.Grid.GetBodiesIn(new Rectangle(Left, Top, Width, Height)); // Gets nearby bodies from spatial hash
- if (Velocity.Y < 0) bodiesToCheck.Sort((b, a) => a.Position.Y.CompareTo(b.Position.Y)); // Sorts bodies by Y axis to avoid wall-jumping bugs
- else bodiesToCheck.Sort((a, b) => a.Position.Y.CompareTo(b.Position.Y));
- for (int i = 0; i < bodiesToCheck.Count; i++) // Detection loop
- {
- SSSPBody body = bodiesToCheck[i];
- if (IgnoresDetectionWith(body)) continue; // If the body has to be ignored, continue
- if (!SSSPUtils.IsOverlapping(this, body, new SSSPVector2(0, 0))) continue; // If there isn't any overlap, continue
- int encrX = 0, encrY = 0; // Penetration values (X and Y)
- if (Bottom < body.Bottom && Bottom >= body.Top) encrY = body.Top - Bottom; // Calculates Y penetration
- else if (Top > body.Top && Top <= body.Bottom) encrY = body.Bottom - Top;
- if (Left < body.Left && Right >= body.Left) encrX = body.Left - Right; // Calculates X penetration
- else if (Right > body.Right && Left <= body.Right) encrX = body.Right - Left;
- invokations.Add(new object[] { body, encrX, encrY }); // Adds "detection event" invokation
- }
- for (int i = 0; i < bodiesToCheck.Count; i++) // Resolution loop
- {
- SSSPBody body = bodiesToCheck[i];
- if (IgnoresDetectionWith(body)) continue; // If the body has to be ignored, continue
- if (!SSSPUtils.IsOverlapping(this, body, new SSSPVector2(0, 0))) continue; // If there isn't any overlap, continue
- int encrX = 0, encrY = 0, numPxOverlapX, numPxOverlapY; // Penetration values and overlap values
- if (Bottom < body.Bottom && Bottom >= body.Top) encrY = body.Top - Bottom; // Calculates Y penetration
- else if (Top > body.Top && Top <= body.Bottom) encrY = body.Bottom - Top;
- if (Left < body.Left && Right >= body.Left) encrX = body.Left - Right; // Calculates X penetration
- else if (Right > body.Right && Left <= body.Right) encrX = body.Right - Left;
- if (Left < body.Left) numPxOverlapX = Right - body.Left; // Calculates X overlap
- else numPxOverlapX = body.Right - Left;
- if (Top < body.Top) numPxOverlapY = Bottom - body.Top; // Calculates Y overlap
- else numPxOverlapY = body.Bottom - Top;
- if (IgnoresResolutionWith(body, new SSSPVector2(encrX, encrY))) continue; // If resolution has to be ignored, continue
- if (Left >= body.Left && Top >= body.Top) crushedLeft = true; // Checks for crushing
- if (Right <= body.Right && Top >= body.Top) crushedRight = true;
- if (Left >= body.Left && Bottom <= body.Bottom) crushedTop = true;
- if (Right <= body.Right && Bottom <= body.Bottom) crushedBottom = true;
- if (numPxOverlapX > numPxOverlapY)
- {
- Position += new SSSPVector2(0, encrY); // Resolves penetration
- body.Velocity = new SSSPVector2(body.Velocity.X, Velocity.Y); // Transfers velocity
- }
- else
- {
- Position += new SSSPVector2(encrX, 0);
- body.Velocity = new SSSPVector2(Velocity.X, body.Velocity.Y);
- }
- if (SSSPUtils.IsOverlapping(this, body, new SSSPVector2(PositionPrevious.X - Position.X, Math.Abs(Velocity.Y) * Math.Sign(World.Gravity.Y))))
- IsCollidingOnBottom = true; // Checks if the body is on the ground
- SSSPVector2 checkPosition = PositionPrevious - (body.PositionPrevious - body.Position); // Calculates difference vector for moving platforms
- if (encrX > 0 && Velocity.X < 0 && Position.X == checkPosition.X) Velocity = new SSSPVector2(0, Velocity.Y); // Sets velocity to 0 if the body is on a moving platform
- if (encrX < 0 && Velocity.X > 0 && Position.X == checkPosition.X) Velocity = new SSSPVector2(0, Velocity.Y);
- if (encrY < 0 && Velocity.Y > 0 && Position.Y == checkPosition.Y) Velocity = new SSSPVector2(Velocity.X, 0);
- if (encrY > 0 && Velocity.Y < 0 && Position.Y == checkPosition.Y) Velocity = new SSSPVector2(Velocity.X, 0);
- }
- if (Position.X == PositionPrevious.X) Velocity = new SSSPVector2(0, Velocity.Y); // If the body hasn't moved, set velocity to 0
- if (Position.Y == PositionPrevious.Y) Velocity = new SSSPVector2(Velocity.X, 0);
- foreach (object[] objects in invokations)
- {
- InvokeOnOverlap((SSSPBody)objects[0], new SSSPVector2((int)objects[1], (int)objects[2])); // Calls overlap events in the bodies
- SSSPBody b = (SSSPBody)objects[0];
- b.InvokeOnOverlap(this, new SSSPVector2((int)objects[1] * -1, (int)objects[2] * -1));
- }
- if (crushedLeft && crushedRight && crushedTop && crushedBottom)
- InvokeOnCrush(this, new SSSPVector2(0, 0)); // Calls crush event in the body
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement