using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Cameras; using MLEM.Extended.Extensions; using MLEM.Extended.Tiled; using MLEM.Extensions; using MLEM.Misc; using MLEM.Startup; using MLEM.Textures; using MonoGame.Extended; using MonoGame.Extended.Tiled; namespace GreatSpringGameJam { public class Map { private static readonly UniformTextureAtlas BackgroundTexture = new(MlemGame.LoadContent("Textures/Backgrounds"), 8, 8); public Point SizeInPixels => new(this.map.WidthInPixels, this.map.HeightInPixels); public Point SpawnPoint => new(this.map.Properties.GetInt("StartX"), this.map.Properties.GetInt("StartY")); public Vector2 TileSize => this.map.GetTileSize(); public readonly TiledMapCollisions Collisions; public readonly int TotalSnow; public readonly int TotalSeeds; private readonly TiledMap map; private readonly IndividualTiledMapRenderer renderer; private readonly List entities = new(); public Map(string name) { this.map = MlemGame.LoadContent($"Maps/{name}"); this.renderer = new IndividualTiledMapRenderer(this.map); this.Collisions = new TiledMapCollisions(this.map); this.TotalSnow = this.GetTotalTiles("Snow"); this.TotalSeeds = this.GetTotalTiles("Seed"); } public void AddEntity(Entity entity) { this.entities.Add(entity); } public void RemoveEntity(Entity entity) { this.entities.Remove(entity); } public void Update(GameTime time) { this.renderer.UpdateAnimations(time); for (var i = this.entities.Count - 1; i >= 0; i--) this.entities[i].Update(time); } public TiledMapTile GetTile(string layer, int x, int y) { return this.map.GetTile(layer, x, y); } public void SetTile(string layer, int x, int y, int globalTile) { var index = this.map.GetTileLayerIndex(layer); this.map.SetTile(layer, x, y, globalTile); this.renderer.UpdateDrawInfo(index, x, y); this.Collisions.UpdateCollisionInfo(index, x, y); } public TiledMapTilesetTile GetTilesetTile(TiledMapTile tile) { return tile.GetTilesetTile(this.map); } public void Draw(GameTime time, SpriteBatch batch, Camera camera) { batch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: camera.ViewMatrix); // render background const float parallaxFactor = 0.5F; var parallax = camera.Position * parallaxFactor; var (parW, parH) = this.SizeInPixels.ToVector2() * (1 - parallaxFactor) + camera.ScaledViewport * parallaxFactor; var mountains = BackgroundTexture[0, 0, 8, 4]; for (var x = 0; x < parW; x += mountains.Width * 2) { batch.Draw(mountains, parallax + new Vector2(x, parH - mountains.Height * 2), Color.White * 0.5F, 0, Vector2.Zero, 2, SpriteEffects.None, 0); } // render map etc. this.DrawLayer(batch, "Ground", camera); foreach (var entity in this.entities) entity.Draw(time, batch); this.DrawLayer(batch, "Foreground", camera); this.DrawLayer(batch, "Snow", camera); batch.End(); } public int GetTotalTiles(string type) { var total = 0; for (var x = 0; x < this.map.Width; x++) { for (var y = 0; y < this.map.Height; y++) { foreach (var tile in this.map.GetTiles(x, y)) { if (tile.IsBlank) continue; var tilesetTile = this.GetTilesetTile(tile); if (tilesetTile.Properties.GetBool(type)) total++; } } } return total; } private void DrawLayer(SpriteBatch batch, string layer, Camera camera) { this.renderer.DrawLayer(batch, this.map.GetTileLayerIndex(layer), camera.GetVisibleRectangle().ToExtended()); } } }