public Vector2 GetIntersectionDepth(MainGuiObject obj) { Vector4 thisBounds = this.Bounds; Vector4 thatBounds = obj.Bounds; return(GetIntersectionDepth(thisBounds, thatBounds)); }
public void AddGuiObject(MainGuiObject guiObject) { if (_guiObjects.ContainsKey(guiObject.Group)) { _guiObjects[guiObject.Group].Add(guiObject); } else { _guiObjects.Add(guiObject.Group, new List <MainGuiObject>() { guiObject }); } }
// This is where all the physics logic gets set. public override void PreUpdate(GameTime gameTime) { // projectedVerticalSpeed is assumed to be gravity unless otherwise determined. float projectedVerticalSpeed = AverageSpeed.Y; // Assume not moving in a direction horizontally. float projectedHorizontalSpeed = 0; Vector4 nextBounds = this.Bounds; nextBounds.Y += AverageSpeed.Y; Dictionary <Group, List <MainGuiObject> > guiObjects = Level.GetAllGuiObjects(); // WARNING DUPLICATE CODE COMING UP, WILL FIX IN NEXT SPRINT. // Vertical. IEnumerable <Tuple <Vector2, MainGuiObject> > verticallyHitPlatforms = guiObjects.SelectMany(kv => kv.Value).Select(p => { if (VerticalPass && p.Group == Group.VerticalPassable) { return new { bounds = Vector2.Zero, select = false, obj = MainGuiObject.EmptyVessel } } ; var bounds = MainGuiObject.GetIntersectionDepth(nextBounds, p.Bounds); float platHeight = p.Size.Y; //return bounds != Vector2.Zero && bounds.Y <= 0 && bounds.Y >= -platHeight; return(new { bounds = bounds, select = bounds != Vector2.Zero && bounds.Y <= 0 && bounds.Y >= -platHeight, obj = p }); }).Where(o => o.select).Select(o => new Tuple <Vector2, MainGuiObject>(o.bounds, o.obj));; //Pick shortest depth as that's the one we care about presumably. Tuple <Vector2, MainGuiObject> verticallyHitPlatformTuple = verticallyHitPlatforms.OrderBy(p => Math.Abs(p.Item1.Y)).FirstOrDefault(); // Will unfortunately have to do some better logic later. if (verticallyHitPlatformTuple != null) { MainGuiObject verticallyHitPlatform = verticallyHitPlatformTuple.Item2; float platHeight = verticallyHitPlatform.Size.Y; float bumpLeeway = Position.Y + Size.Y - platHeight; Vector2 bounds = GetIntersectionDepth(verticallyHitPlatform); // If the object is moving downwards, and is below the top of the platform, push it back up. if (!StopGravity && bounds.Y <= 0 && bounds.Y >= -AverageSpeed.Y * 2) { // fix offset Position = new Vector2(Position.X, Position.Y + bounds.Y + 1); projectedVerticalSpeed = 0; IsLanded = true; } } // Horizontal // Make this check more groups... in an elegant way. IEnumerable <Tuple <Vector2, MainGuiObject> > horizontallyHitPlatforms = guiObjects.Where(g => g.Key == Group.ImpassableIncludingMagic).SelectMany(kv => kv.Value).Select(p => { var bounds = MainGuiObject.GetIntersectionDepth(nextBounds, p.Bounds); float platWidth = p.Size.X; return(new { bounds = bounds, select = bounds != Vector2.Zero && Math.Abs(bounds.X) > 0 && Math.Abs(bounds.X) <= platWidth, obj = p }); }).Where(o => o.select).Select(o => new Tuple <Vector2, MainGuiObject>(o.bounds, o.obj)); //Pick shortest depth as that's the one we care about presumably. Tuple <Vector2, MainGuiObject> horizontallyHitPlatformTuple = horizontallyHitPlatforms.OrderBy(p => Math.Abs(p.Item1.X)).FirstOrDefault(); // Will unfortunately have to do some better logic later. if (horizontallyHitPlatformTuple != null) { MainGuiObject horizontallyHitPlatform = horizontallyHitPlatformTuple.Item2; float platWidth = horizontallyHitPlatform.Size.X; float bumpLeeway = Position.X + Size.X - platWidth; Vector2 bounds = GetIntersectionDepth(horizontallyHitPlatform); // If the object is moving downwards, and is below the top of the platform, push it back up. if (Math.Abs(bounds.X) > 0 && Math.Abs(bounds.X) <= AverageSpeed.X) { // fix offset Position = new Vector2(Position.X + bounds.X, Position.Y); projectedHorizontalSpeed = 0; } } // Move object if needed. CurrentMovement = new Vector2(projectedHorizontalSpeed, projectedVerticalSpeed); PostPhysicsPreUpdate(gameTime); }