예제 #1
0
        private void InternalDrawEntities(Map map, Position3D center, MousePicking mousePick, out Vector2 renderOffset)
        {
            if (center == null)
            {
                renderOffset = new Vector2();
                return;
            }

            const int renderDimensionY          = 16; // the number of tiles that are drawn for half the screen (doubled to fill the entire screen).
            const int renderDimensionX          = 18; // the number of tiles that are drawn in the x-direction ( + renderExtraColumnsAtSides * 2 ).
            const int renderExtraColumnsAtSides = 2;  // the client draws additional tiles at the edge to make wide objects that are mostly offscreen visible.


            // when the player entity is higher (z) in the world, we must offset the first row drawn. This variable MUST be a multiple of 2.
            int renderZOffset = (center.Z / 14) * 2 + 4;
            // this is used to draw tall objects that would otherwise not be visible until their ground tile was on screen. This may still skip VERY tall objects (those weird jungle trees?)
            int renderExtraRowsAtBottom = renderZOffset + 10;

            Point firstTile = new Point(
                center.X + renderExtraColumnsAtSides - ((renderZOffset + 1) / 2),
                center.Y - renderDimensionY - renderExtraColumnsAtSides - (renderZOffset / 2));

            renderOffset.X  = ((Settings.Game.Resolution.Width + ((renderDimensionY) * 44)) / 2) - 22 + renderExtraColumnsAtSides * 44;
            renderOffset.X -= (int)((center.X_offset - center.Y_offset) * 22);
            renderOffset.X -= (firstTile.X - firstTile.Y) * 22;

            renderOffset.Y  = ((Settings.Game.Resolution.Height - (renderDimensionY * 44)) / 2);
            renderOffset.Y += (center.Z * 4) + (int)(center.Z_offset * 4);
            renderOffset.Y -= (int)((center.X_offset + center.Y_offset) * 22);
            renderOffset.Y -= (firstTile.X + firstTile.Y) * 22;
            renderOffset.Y -= (renderZOffset) * 22;

            ObjectsRendered = 0;                                                                           // Count of objects rendered for statistics and debug

            MouseOverList  overList         = new MouseOverList(_input.MousePosition, mousePick.PickOnly); // List of entities mouse is over.
            List <AEntity> deferredToRemove = new List <AEntity>();

            for (int col = 0; col < renderDimensionY * 2 + renderExtraRowsAtBottom; col++)
            {
                Vector3 drawPosition = new Vector3();
                drawPosition.X = (firstTile.X - firstTile.Y + (col % 2)) * 22 + renderOffset.X;
                drawPosition.Y = (firstTile.X + firstTile.Y + col) * 22 + renderOffset.Y;

                Point index = new Point(firstTile.X + ((col + 1) / 2), firstTile.Y + (col / 2));

                for (int row = 0; row < renderDimensionX + renderExtraColumnsAtSides * 2; row++)
                {
                    var maptile = map.GetMapTile(index.X - row, index.Y + row);
                    if (maptile == null)
                    {
                        continue;
                    }

                    foreach (var entity in maptile.Entities)
                    {
                        if (!DrawTerrain)
                        {
                            if (entity is Ground)
                            {
                                break;
                            }
                            if (entity.Z > maptile.Ground.Z)
                            {
                                break;
                            }
                        }

                        if (entity.Z >= _maxItemAltitude)
                        {
                            continue;
                        }

                        var view = entity.GetView();

                        if (view != null)
                        {
                            if (view.Draw(_spriteBatch, drawPosition, overList, map))
                            {
                                ObjectsRendered++;
                            }
                        }

                        if (entity is DeferredEntity)
                        {
                            deferredToRemove.Add(entity);
                        }
                    }

                    foreach (var deferred in deferredToRemove)
                    {
                        maptile.OnExit(deferred);
                    }
                    deferredToRemove.Clear();

                    drawPosition.X -= 44f;
                }
            }

            OverheadRenderer.Render(_spriteBatch, overList, map);

            // Update the MouseOver objects
            mousePick.UpdateOverEntities(overList, _input.MousePosition);

            // Draw the objects we just send to the spritebatch.
            _spriteBatch.Prepare(true, true);
            _spriteBatch.Flush();
        }