diff --git a/ThemeParkClicker/Content/Content.mgcb b/ThemeParkClicker/Content/Content.mgcb index d6d7b88..774eb6a 100644 --- a/ThemeParkClicker/Content/Content.mgcb +++ b/ThemeParkClicker/Content/Content.mgcb @@ -35,3 +35,8 @@ /processor:TextureProcessor /build:Textures/Attractions.png +#begin Textures/Tiles.png +/importer:TextureImporter +/processor:TextureProcessor +/build:Textures/Tiles.png + diff --git a/ThemeParkClicker/Content/Textures/Tiles.aseprite b/ThemeParkClicker/Content/Textures/Tiles.aseprite new file mode 100644 index 0000000..d998752 Binary files /dev/null and b/ThemeParkClicker/Content/Textures/Tiles.aseprite differ diff --git a/ThemeParkClicker/Content/Textures/Tiles.png b/ThemeParkClicker/Content/Textures/Tiles.png new file mode 100644 index 0000000..1878967 Binary files /dev/null and b/ThemeParkClicker/Content/Textures/Tiles.png differ diff --git a/ThemeParkClicker/GameImpl.cs b/ThemeParkClicker/GameImpl.cs index 80da2e9..a13f2d0 100644 --- a/ThemeParkClicker/GameImpl.cs +++ b/ThemeParkClicker/GameImpl.cs @@ -12,24 +12,12 @@ namespace ThemeParkClicker { public class GameImpl : MlemGame { public static GameImpl Instance { get; private set; } - private BigInteger tickets; - public BigInteger Tickets { - get => this.tickets; - set { - var diff = value - this.tickets; - if (diff > 0) - this.ticketsPerSecondCounter += (long) diff; - this.tickets = value; - } - } + public BigInteger Tickets; public ParkMap Map; public Camera Camera { get; private set; } public Ui Ui { get; private set; } public bool DrawMap; public DateTime LastUpdate; - public float TicketsPerSecond { get; private set; } - private long ticketsPerSecondCounter; - private double secondCounter; private double saveCounter; public GameImpl() { @@ -38,6 +26,10 @@ namespace ThemeParkClicker { protected override void LoadContent() { base.LoadContent(); + + if (!SaveHandler.Load(this)) + this.Map = new ParkMap(10, 10); + this.Ui = new Ui(this.UiSystem); this.Camera = new Camera(this.GraphicsDevice) { Scale = 5, @@ -46,9 +38,6 @@ namespace ThemeParkClicker { MaxScale = 24, MinScale = 3 }; - - if (!SaveHandler.Load(this)) - this.Map = new ParkMap(10, 10); } protected override void DoUpdate(GameTime gameTime) { @@ -66,15 +55,6 @@ namespace ThemeParkClicker { this.Ui.Update(gameTime); - // we average tickets per second over 4 seconds - const float avgTime = 4; - this.secondCounter += gameTime.ElapsedGameTime.TotalSeconds; - if (this.secondCounter >= avgTime) { - this.secondCounter -= avgTime; - this.TicketsPerSecond = this.ticketsPerSecondCounter / avgTime; - this.ticketsPerSecondCounter = 0; - } - // save every 3 seconds this.saveCounter += gameTime.ElapsedGameTime.TotalSeconds; if (this.saveCounter >= 3) { diff --git a/ThemeParkClicker/ParkMap.cs b/ThemeParkClicker/ParkMap.cs index 1649417..4d34bf1 100644 --- a/ThemeParkClicker/ParkMap.cs +++ b/ThemeParkClicker/ParkMap.cs @@ -15,13 +15,18 @@ namespace ThemeParkClicker { [DataContract] public class ParkMap { + private static readonly UniformTextureAtlas TilesTexture = new UniformTextureAtlas(MlemGame.LoadContent("Textures/Tiles"), 16, 16); + private const int AdditionalRadius = 10; [DataMember] public readonly int Width; [DataMember] public readonly int Height; [DataMember] private readonly List<(Point, Attraction)> attractions = new List<(Point, Attraction)>(); + private readonly Dictionary treePositions = new Dictionary(); + private readonly Dictionary fencePositions = new Dictionary(); + public float TicketsPerSecond { get; private set; } public Attraction PlacingAttraction; public Point PlacingPosition; private bool draggingAttraction; @@ -29,11 +34,39 @@ namespace ThemeParkClicker { public ParkMap(int width, int height) { this.Width = width; this.Height = height; + + // set up trees + var random = new Random(); + for (var i = 0; i < 100; i++) { + var type = random.Next(3); + var x = random.Next(-AdditionalRadius, this.Width + AdditionalRadius); + var y = random.Next(-AdditionalRadius, this.Height + AdditionalRadius); + if (x < 0 || y < 0 || x >= this.Width || y >= this.Width) + this.treePositions[new Point(x, y)] = type; + } + + // set up fences + this.fencePositions[new Point(-1, -1)] = 2; + this.fencePositions[new Point(this.Width, -1)] = 3; + this.fencePositions[new Point(-1, this.Height)] = 4; + this.fencePositions[new Point(this.Width, this.Height)] = 5; + for (var x = 0; x < this.Width; x++) { + this.fencePositions[new Point(x, -1)] = 0; + this.fencePositions[new Point(x, this.Height)] = 0; + } + for (var y = 0; y < this.Height; y++) { + this.fencePositions[new Point(-1, y)] = 1; + this.fencePositions[new Point(this.Width, y)] = 1; + } } public void Update(GameTime time, TimeSpan passed) { - foreach (var (_, attraction) in this.attractions) + var tickets = 0F; + foreach (var (_, attraction) in this.attractions) { attraction.Update(time, passed); + tickets += attraction.Type.GenerationPerSecond; + } + this.TicketsPerSecond = tickets; // map movement if (GameImpl.Instance.DrawMap) { @@ -68,13 +101,26 @@ namespace ThemeParkClicker { .Any(p => this.PlacingPosition + p == offset); } } + camera.ConstrainWorldBounds(new Vector2(-AdditionalRadius) * Attraction.TileSize, new Vector2(this.Width + AdditionalRadius, this.Height + AdditionalRadius) * Attraction.TileSize); } } - public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale, float alpha) { + public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale, float alpha, int additionalRadius = AdditionalRadius) { var tileSize = Attraction.TileSize * scale; // draw ground - batch.Draw(batch.GetBlankTexture(), new RectangleF(position, new Vector2(this.Width, this.Height) * tileSize), ColorExtensions.FromHex(0xff53a662) * alpha); + for (var x = -additionalRadius; x < this.Width + additionalRadius; x++) { + for (var y = -additionalRadius; y < this.Height + additionalRadius; y++) { + var pos = new Vector2(x, y); + var drawPos = position + pos * tileSize; + batch.Draw(TilesTexture[0, 0], drawPos, Color.White * alpha, 0, Vector2.Zero, scale, SpriteEffects.None, 0); + + if (this.fencePositions.TryGetValue(pos.ToPoint(), out var fenceType)) { + batch.Draw(TilesTexture[fenceType, 1], drawPos, Color.White * alpha, 0, Vector2.Zero, scale, SpriteEffects.None, 0); + } else if (this.treePositions.TryGetValue(pos.ToPoint(), out var treeType)) { + batch.Draw(TilesTexture[1 + treeType, 0], drawPos, Color.White * alpha, 0, Vector2.Zero, scale, SpriteEffects.None, 0); + } + } + } // draw attractions foreach (var (pos, attraction) in this.attractions) batch.Draw(attraction.Type.TextureRegion, position + pos.ToVector2() * tileSize, Color.White * alpha, 0, Vector2.Zero, scale, SpriteEffects.None, 0); diff --git a/ThemeParkClicker/Ui.cs b/ThemeParkClicker/Ui.cs index c11313d..7afb5a6 100644 --- a/ThemeParkClicker/Ui.cs +++ b/ThemeParkClicker/Ui.cs @@ -45,7 +45,7 @@ namespace ThemeParkClicker { if (rainingTickets[i].Update()) rainingTickets.RemoveAt(i); } - while (rainingTickets.Count < Math.Min(GameImpl.Instance.TicketsPerSecond / 10, 500)) + while (rainingTickets.Count < Math.Min(GameImpl.Instance.Map.TicketsPerSecond / 10, 500)) rainingTickets.Add(new RainingTicket()); }, OnDrawn = (e, time, batch, alpha) => { @@ -58,7 +58,7 @@ namespace ThemeParkClicker { ticketGroup.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.DisplayTicketCount(), true) { TextScale = 0.3F }); - ticketGroup.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.TicketsPerSecond.ToString("0.##") + "/s", true) { + ticketGroup.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.Map.TicketsPerSecond.ToString("0.##") + "/s", true) { PositionOffset = new Vector2(0, -8) }); BigInteger lastTickets = 0; @@ -83,7 +83,7 @@ namespace ThemeParkClicker { var (scaleX, scaleY) = e.DisplayArea.Size / mapSize; var scale = Math.Min(scaleX, scaleY); var pos = e.DisplayArea.Location + (e.DisplayArea.Size - mapSize * scale) / 2; - map.Draw(time, batch, pos, scale, alpha); + map.Draw(time, batch, pos, scale, alpha, 0); }, OnPressed = e => { var map = GameImpl.Instance.Map;