From 0a93fb7da73011b022d3e066693108672d4d1148 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Mon, 6 Jun 2022 22:56:48 +0200 Subject: [PATCH] Allow using a StaticSpriteBatch to draw an IndividualTiledMapRenderer --- .../Tiled/IndividualTiledMapRenderer.cs | 71 +++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs b/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs index b55688e..7ee601a 100644 --- a/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs +++ b/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Cameras; using MLEM.Extensions; +using MLEM.Graphics; using MLEM.Misc; using MonoGame.Extended.Tiled; using RectangleF = MonoGame.Extended.RectangleF; @@ -92,6 +93,20 @@ namespace MLEM.Extended.Tiled { } } + /// + /// Adds this individual tiled map renderer to the given . + /// Optionally, a frustum can be supplied that determines which positions, in pixel space, are visible at this time. provides for this purpose. + /// + /// The static sprite batch to use for drawing. + /// The area that is visible, in pixel space. + /// The add function to use, or null to use . + public void Add(StaticSpriteBatch batch, RectangleF? frustum = null, AddDelegate addFunction = null) { + for (var i = 0; i < this.map.TileLayers.Count; i++) { + if (this.map.TileLayers[i].IsVisible) + this.AddLayer(batch, i, frustum, addFunction); + } + } + /// /// Draws the given layer of this individual tiled map renderer. /// Optionally, a frustum can be supplied that determines which positions, in pixel space, are visible at this time. provides for this purpose. @@ -102,11 +117,7 @@ namespace MLEM.Extended.Tiled { /// The draw function to use, or null to use public void DrawLayer(SpriteBatch batch, int layerIndex, RectangleF? frustum = null, DrawDelegate drawFunction = null) { var draw = drawFunction ?? DefaultDraw; - var frust = frustum ?? new RectangleF(0, 0, float.MaxValue, float.MaxValue); - var minX = Math.Max(0, frust.Left / this.map.TileWidth).Floor(); - var minY = Math.Max(0, frust.Top / this.map.TileHeight).Floor(); - var maxX = Math.Min(this.map.Width, frust.Right / this.map.TileWidth).Ceil(); - var maxY = Math.Min(this.map.Height, frust.Bottom / this.map.TileHeight).Ceil(); + var (minX, minY, maxX, maxY) = this.GetFrustum(frustum); for (var x = minX; x < maxX; x++) { for (var y = minY; y < maxY; y++) { var info = this.drawInfos[layerIndex, x, y]; @@ -116,6 +127,26 @@ namespace MLEM.Extended.Tiled { } } + /// + /// Adds the given layer of this individual tiled map renderer to the given . + /// Optionally, a frustum can be supplied that determines which positions, in pixel space, are visible at this time. provides for this purpose. + /// + /// The static sprite batch to use for drawing. + /// The index of the layer in . + /// The area that is visible, in pixel space. + /// The add function to use, or null to use . + public void AddLayer(StaticSpriteBatch batch, int layerIndex, RectangleF? frustum = null, AddDelegate addFunction = null) { + var add = addFunction ?? DefaultAdd; + var (minX, minY, maxX, maxY) = this.GetFrustum(frustum); + for (var x = minX; x < maxX; x++) { + for (var y = minY; y < maxY; y++) { + var info = this.drawInfos[layerIndex, x, y]; + if (info != null) + add(batch, info); + } + } + } + /// /// Update all of the animated tiles in this individual tiled map renderer /// @@ -125,8 +156,17 @@ namespace MLEM.Extended.Tiled { animation.Update(time); } + private (int MinX, int MinY, int MaxX, int MaxY) GetFrustum(RectangleF? frustum) { + var frust = frustum ?? new RectangleF(0, 0, float.MaxValue, float.MaxValue); + var minX = Math.Max(0, frust.Left / this.map.TileWidth).Floor(); + var minY = Math.Max(0, frust.Top / this.map.TileHeight).Floor(); + var maxX = Math.Min(this.map.Width, frust.Right / this.map.TileWidth).Ceil(); + var maxY = Math.Min(this.map.Height, frust.Bottom / this.map.TileHeight).Ceil(); + return (minX, minY, maxX, maxY); + } + /// - /// The default implementation of that is used by if no custom draw function is passed + /// The default implementation of that is used by if no custom draw function is passed. /// /// The sprite batch to use for drawing /// The to draw @@ -137,6 +177,18 @@ namespace MLEM.Extended.Tiled { batch.Draw(info.Tileset.Texture, drawPos, region, Color.White, 0, Vector2.Zero, 1, effects, info.Depth); } + /// + /// The default implementation of that is used by if no custom add function is passed. + /// + /// The static sprite batch to use for drawing. + /// The to add. + public static void DefaultAdd(StaticSpriteBatch batch, TileDrawInfo info) { + var region = info.Tileset.GetTextureRegion(info.TilesetTile); + var effects = info.Tile.GetSpriteEffects(); + var drawPos = new Vector2(info.Position.X * info.Renderer.map.TileWidth, info.Position.Y * info.Renderer.map.TileHeight); + batch.Add(info.Tileset.Texture, drawPos, region, Color.White, 0, Vector2.Zero, 1, effects, info.Depth); + } + /// /// A delegate method used for . /// The idea is to return a depth (between 0 and 1) for the given tile that determines where in the sprite batch it should be rendererd. @@ -155,6 +207,13 @@ namespace MLEM.Extended.Tiled { /// The to draw public delegate void DrawDelegate(SpriteBatch batch, TileDrawInfo info); + /// + /// A delegate method used for adding an to a . + /// + /// The static sprite batch to use for drawing. + /// The to add. + public delegate void AddDelegate(StaticSpriteBatch batch, TileDrawInfo info); + /// /// A tile draw info contains information about a tile at a given map location. /// It caches a lot of data that is required for drawing a tile efficiently.