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(); }