示例#1
0
        public override LocationResolvStatus UpdateLocation(double currentTime, double delta)
        {
            this.status = new LocationResolvStatus();

            var xDelta = Velocity.X * (float)delta;
            var yDelta = Velocity.Y * (float)delta;

            var nextTile = CurrentTile.GetNextTileInDirection(Direction);

            var newBounds = new RectangleF(new PointF(Bounds.Left + xDelta, Bounds.Top + yDelta), Bounds.Size);

            Console.WriteLine(newBounds);

            foreach (var item in FloatingObjectRegistry.GetMovingObjects())
            {
                if (item.Tile != CurrentTile && item.Tile.Bounds.IntersectsWith(newBounds))
                {
                    // Not allowed to enter tile, constrain the movement
                    if (xDelta != 0)
                    {
                        // Adjust x movement
                        if (xDelta < 0)
                        {
                            xDelta = Math.Max(CurrentTile.Bounds.Left - Bounds.Left, xDelta);
                        }
                        else
                        {
                            xDelta = Math.Min(CurrentTile.Bounds.Right - Bounds.Right, xDelta);
                        }
                    }
                    if (yDelta != 0)
                    {
                        // Adjust y movement
                        if (yDelta < 0)
                        {
                            yDelta = Math.Max(CurrentTile.Bounds.Top - Bounds.Top, yDelta);
                        }
                        else
                        {
                            yDelta = Math.Min(CurrentTile.Bounds.Bottom - Bounds.Bottom, yDelta);
                        }
                    }
                    Velocity = new PointF(0, 0);
                }
            }

            if (!nextTile.Bounds.IntersectsWith(Bounds) && nextTile.Bounds.IntersectsWith(newBounds))
            {
                // Entering a new tile
                if (!CanEnterTile(nextTile))
                {
                    // Not allowed to enter tile, constrain the movement
                    if (xDelta != 0)
                    {
                        // Adjust x movement
                        if (xDelta < 0)
                        {
                            xDelta = Math.Max(CurrentTile.Bounds.Left - Bounds.Left, xDelta);
                        }
                        else
                        {
                            xDelta = Math.Min(CurrentTile.Bounds.Right - Bounds.Right, xDelta);
                        }
                    }
                    if (yDelta != 0)
                    {
                        // Adjust y movement
                        if (yDelta < 0)
                        {
                            yDelta = Math.Max(CurrentTile.Bounds.Top - Bounds.Top, yDelta);
                        }
                        else
                        {
                            yDelta = Math.Min(CurrentTile.Bounds.Bottom - Bounds.Bottom, yDelta);
                        }
                    }
                    Velocity = new PointF(0, 0);
                }
            }
            else if (nextTile.Bounds.IntersectsWith(newBounds) && CurrentTile != nextTile)
            {
                CanEnterTile(nextTile);
            }

            MoveBy(xDelta, yDelta);

            // Mark tiles around the player as dirty
            CurrentTile.MarkAsDirty();
            CurrentTile.West.MarkAsDirty();
            CurrentTile.North.MarkAsDirty();
            CurrentTile.East.MarkAsDirty();
            CurrentTile.South.MarkAsDirty();

            if (!CurrentTile.Bounds.Contains(this.centerPosition) && nextTile.Bounds.Contains(this.centerPosition))
            {
                // Switched current tile
                status.ChangedTile = true;
                status.PrevTile    = CurrentTile;
                CurrentTile        = nextTile;
            }

            if (!Velocity.IsEmpty)
            {
                AlignWithTileBounds();
            }

            return(status);
        }