Esempio n. 1
0
        private void RenderIsoFrontObjects(Layer layer, IList <RenderTextureRegion> r)
        {
            batch.Begin();
            int     w              = layer.Width;
            int     h              = layer.Height;
            TileSet tset           = layer.TileSet;
            Point   upperLeft      = engine.Camera.GetUpperLeft();
            int     maxTilesWidth  = (viewWidth / tileWidth) + 2 * tset.OversizeX;
            int     maxTilesHeight = ((viewHeight / tileHeight) + 2 * (tset.OversizeY)) * 2;
            int     j              = upperLeft.Y - tset.OversizeY / 2 + tset.OversizeX;
            int     i              = upperLeft.X - tset.OversizeY / 2 - tset.OversizeX;
            int     rCursor        = 0;
            int     rEnd           = r.Count;

            while (rCursor != rEnd && ((int)r[rCursor].MapX + (int)r[rCursor].MapY < i + j || (int)r[rCursor].MapX < i))
            {
                ++rCursor;
            }
            List <int> renderBehindSW   = new List <int>();
            List <int> renderBehindNE   = new List <int>();
            List <int> renderBehindNone = new List <int>();

            int[,] drawnTiles = new int[w, h];
            for (uint y = (uint)maxTilesHeight; y != 0; --y)
            {
                int tilesWidth = 0;
                if (i < -1)
                {
                    j          = j + i + 1;
                    tilesWidth = tilesWidth - (i + 1);
                    i          = -1;
                }

                int d = j - h;
                if (d >= 0)
                {
                    j          = j - d;
                    tilesWidth = tilesWidth + d;
                    i          = i + d;
                }

                int jEnd = Math.Max(j + i - w + 1, Math.Max(j - maxTilesWidth, 0));
                engine.Camera.MapToScreen(i, j, out int pX, out int pY);
                Point p            = engine.Camera.CenterTile(pX, pY);
                bool  isLastNeTile = false;
                while (j > jEnd)
                {
                    --j;
                    ++i;
                    ++tilesWidth;
                    p.X += tileWidth;
                    bool drawTile   = true;
                    int  rPreCursor = rCursor;
                    while (rPreCursor != rEnd)
                    {
                        int rCursorX = (int)r[rPreCursor].MapX;
                        int rCursorY = (int)r[rPreCursor].MapY;
                        if ((rCursorX - 1 == i && rCursorY + 1 == j) || (rCursorX + 1 == i && rCursorY - 1 == j))
                        {
                            drawTile = false;
                            break;
                        }
                        else if ((rCursorX + 1 > i) || (rCursorY + 1 > j))
                        {
                            break;
                        }
                        ++rPreCursor;
                    }
                    if (drawTile && drawnTiles[i, j] == 0)
                    {
                        RenderTile(layer, layer[i, j], p.X, p.Y);
                        drawnTiles[i, j] = 1;
                    }
                    if (rCursor == rEnd)
                    {
                        continue;
                    }
doLastNETile:
                    GetTileBounds(i - 2, j + 2, layer, out Rect tileSWBounds, out Point tileSWCenter);
                    GetTileBounds(i - 1, j + 2, layer, out Rect tileSBounds, out Point tileSCenter);
                    GetTileBounds(i, j, layer, out Rect tileNEBounds, out Point tileNECenter);
                    GetTileBounds(i, j + 1, layer, out Rect tileEBounds, out Point tileECenter);
                    bool drawSWTile = false;
                    bool drawNETile = false;
                    while (rCursor != rEnd)
                    {
                        int rCursorX = (int)r[rCursor].MapX;
                        int rCursorY = (int)r[rCursor].MapY;
                        if ((rCursorX + 1 == i) && (rCursorY - 1 == j))
                        {
                            drawSWTile = true;
                            drawNETile = !isLastNeTile;
                            engine.Camera.MapToScreen(r[rCursor].MapX, r[rCursor].MapY, out pX, out pY);
                            Point rCursorLeft = new Point(pX, pY);
                            rCursorLeft.Y -= r[rCursor].TextureRegion.OffsetY;
                            Point rCursorRight = new Point(rCursorLeft.X, rCursorLeft.Y);
                            rCursorLeft.X  -= r[rCursor].TextureRegion.OffsetX;
                            rCursorRight.X += r[rCursor].TextureRegion.Width - r[rCursor].TextureRegion.OffsetX;
                            bool isBehindSW = false;
                            bool isBehindNE = false;
                            if (IsWithinRect(tileSBounds, rCursorRight) && IsWithinRect(tileSWBounds, rCursorLeft))
                            {
                                isBehindSW = true;
                            }
                            if (drawNETile && IsWithinRect(tileEBounds, rCursorLeft) && IsWithinRect(tileNEBounds, rCursorRight))
                            {
                                isBehindNE = true;
                            }
                            if (isBehindSW)
                            {
                                renderBehindSW.Add(rCursor);
                            }
                            else if (!isBehindSW && isBehindNE)
                            {
                                renderBehindNE.Add(rCursor);
                            }
                            else
                            {
                                renderBehindNone.Add(rCursor);
                            }
                            ++rCursor;
                        }
                        else
                        {
                            break;
                        }
                    }

                    while (renderBehindSW.Count > 0)
                    {
                        RenderRenderable(r[renderBehindSW[0]]);
                        renderBehindSW.RemoveAt(0);
                    }

                    if (drawSWTile && i - 2 >= 0 && j + 2 < h && drawnTiles[i - 2, j + 2] == 0)
                    {
                        RenderTile(layer, layer[i - 2, j + 2], tileSWCenter.X, tileSWCenter.Y);
                        drawnTiles[i - 2, j + 2] = 1;
                    }

                    while (renderBehindNE.Count > 0)
                    {
                        RenderRenderable(r[renderBehindNE[0]]);
                        renderBehindNE.RemoveAt(0);
                    }

                    if (drawNETile && !drawTile && drawnTiles[i, j] == 0)
                    {
                        RenderTile(layer, layer[i, j], tileNECenter.X, tileNECenter.Y);
                        drawnTiles[i, j] = 1;
                    }

                    while (renderBehindNone.Count > 0)
                    {
                        RenderRenderable(r[renderBehindNone[0]]);
                        renderBehindNone.RemoveAt(0);
                    }

                    if (isLastNeTile)
                    {
                        ++j;
                        --i;
                        isLastNeTile = false;
                    }
                    else if (i == w - 1 || j == 0)
                    {
                        --j;
                        ++i;
                        isLastNeTile = true;
                        goto doLastNETile;
                    }
                }
                j = j + tilesWidth;
                i = i - tilesWidth;
                if ((y % 2) != 0)
                {
                    i++;
                }
                else
                {
                    j++;
                }
                while (rCursor != rEnd && ((int)r[rCursor].MapX + (int)r[rCursor].MapY < i + j || (int)r[rCursor].MapX <= i))
                {
                    ++rCursor;
                }
            }
            batch.End();
        }