park map and attraction functionality

This commit is contained in:
Ellpeck 2020-05-31 17:24:10 +02:00
parent d612a62306
commit 43a1c3c904
4 changed files with 113 additions and 9 deletions

View file

@ -1,5 +1,7 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Startup;
using MLEM.Textures;
@ -8,10 +10,11 @@ namespace ThemeParkClicker.Attractions {
public static readonly Dictionary<string, Constructor> Attractions = new Dictionary<string, Constructor>();
public static readonly UniformTextureAtlas Texture = new UniformTextureAtlas(MlemGame.LoadContent<Texture2D>("Textures/Attractions"), 16, 16);
public static readonly Vector2 TileSize = new Vector2(Texture.RegionWidth, Texture.RegionHeight);
static Attraction() {
Attractions.Add("Carousel", () => new Attraction(new[,] {{true}}, Texture[0, 0, 1, 1], 0.25F, 50));
Attractions.Add("FoodCourt", () => new Attraction(new[,] {{true, true}}, Texture[1, 0, 2, 1], 0.6F, 300));
Attractions.Add("Carousel", () => new Attraction(new[,] {{true}}, Texture[0, 0, 1, 1], 0.5F, 50));
Attractions.Add("FoodCourt", () => new Attraction(new[,] {{true, true}}, Texture[1, 0, 2, 1], 0.7F, 300));
}
private readonly bool[,] area;
@ -20,6 +23,7 @@ namespace ThemeParkClicker.Attractions {
public readonly TextureRegion TextureRegion;
public readonly float GenerationPerSecond;
public readonly long InitialPrice;
private float ticketPercentage;
public Attraction(bool[,] area, TextureRegion texture, float generationPerSecond, long initialPrice) {
this.area = area;
@ -38,5 +42,14 @@ namespace ThemeParkClicker.Attractions {
return this.InitialPrice;
}
public void GainTickets(GameTime time) {
this.ticketPercentage += this.GenerationPerSecond * (float) time.ElapsedGameTime.TotalSeconds;
var amount = this.ticketPercentage.Floor();
if (amount > 0) {
GameImpl.Instance.Tickets += amount;
this.ticketPercentage -= amount;
}
}
}
}

View file

@ -1,15 +1,19 @@
using System.Numerics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Cameras;
using MLEM.Extensions;
using MLEM.Font;
using MLEM.Startup;
using ThemeParkClicker.Attractions;
namespace ThemeParkClicker {
public class GameImpl : MlemGame {
public static GameImpl Instance { get; private set; }
public BigInteger Tickets = 200;
public ParkMap Map { get; private set; }
public Camera Camera { get; private set; }
public Ui Ui { get; private set; }
public GameImpl() {
@ -19,6 +23,16 @@ namespace ThemeParkClicker {
protected override void LoadContent() {
base.LoadContent();
this.Ui = new Ui(this.UiSystem);
this.Map = new ParkMap(10, 10);
this.Camera = new Camera(this.GraphicsDevice) {
Scale = 4,
AutoScaleWithScreen = true
};
this.Map.Place(Point.Zero, Attraction.Attractions["Carousel"]());
this.Map.Place(new Point(1, 0), Attraction.Attractions["Carousel"]());
this.Map.Place(new Point(3, 0), Attraction.Attractions["Carousel"]());
this.Map.Place(new Point(1,2), Attraction.Attractions["FoodCourt"]());
}
public string DisplayTicketCount() {
@ -27,6 +41,7 @@ namespace ThemeParkClicker {
protected override void DoUpdate(GameTime gameTime) {
base.DoUpdate(gameTime);
this.Map.Update(gameTime);
this.Ui.Update(gameTime);
}

View file

@ -0,0 +1,58 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Extensions;
using MLEM.Misc;
using MLEM.Startup;
using MLEM.Textures;
using ThemeParkClicker.Attractions;
namespace ThemeParkClicker {
public class ParkMap {
public readonly int Width;
public readonly int Height;
private readonly Attraction[,] grid;
private readonly Dictionary<Point, Attraction> attractions = new Dictionary<Point, Attraction>();
public ParkMap(int width, int height) {
this.Width = width;
this.Height = height;
this.grid = new Attraction[width, height];
}
public void Update(GameTime time) {
foreach (var attraction in this.attractions.Values)
attraction.GainTickets(time);
}
public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale) {
var tileSize = Attraction.TileSize * scale;
// draw ground
batch.Draw(batch.GetBlankTexture(), new RectangleF(position, new Vector2(this.Width, this.Height) * tileSize), ColorExtensions.FromHex(0xff53a662));
// draw attractions
foreach (var kv in this.attractions)
batch.Draw(kv.Value.TextureRegion, position + kv.Key.ToVector2() * tileSize, Color.White);
}
public bool CanPlace(Point position, Attraction attraction) {
for (var x = 0; x < attraction.Width; x++) {
for (var y = 0; y < attraction.Height; y++) {
if (this.grid[position.X + x, position.Y + y] != null)
return false;
}
}
return true;
}
public void Place(Point position, Attraction attraction) {
for (var x = 0; x < attraction.Width; x++) {
for (var y = 0; y < attraction.Height; y++)
this.grid[position.X + x, position.Y + y] = attraction;
}
this.attractions[position] = attraction;
}
}
}

View file

@ -9,6 +9,7 @@ using Microsoft.Xna.Framework.Input.Touch;
using MLEM.Extensions;
using MLEM.Font;
using MLEM.Formatting.Codes;
using MLEM.Input;
using MLEM.Misc;
using MLEM.Startup;
using MLEM.Textures;
@ -27,6 +28,7 @@ namespace ThemeParkClicker {
private bool finishingSwipe;
public Ui(UiSystem uiSystem) {
InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.Pinch);
this.uiSystem = uiSystem;
this.uiSystem.GlobalScale = 4;
this.uiSystem.AutoScaleWithScreen = true;
@ -51,19 +53,35 @@ namespace ThemeParkClicker {
ticket.Draw(batch, e.DisplayArea.Size, e.Scale);
}
};
main.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.DisplayTicketCount(), true) {
var ticketGroup = main.AddChild(new Group(Anchor.AutoCenter, new Vector2(1, 0.15F), false));
ticketGroup.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.DisplayTicketCount(), true) {
TextScale = 0.3F
});
var storeGroup = main.AddChild(new CustomDrawGroup(Anchor.AutoLeft, Vector2.One));
BigInteger lastTickets = 0;
var storeGroup = main.AddChild(new CustomDrawGroup(Anchor.AutoCenter, new Vector2(1, 0.5F), null, null, false) {
OnUpdated = (e, time) => {
if (lastTickets != GameImpl.Instance.Tickets) {
lastTickets = GameImpl.Instance.Tickets;
CoroutineHandler.Start(WobbleElement((CustomDrawGroup) e));
}
}
});
storeGroup.AddChild(new Image(Anchor.TopLeft, Vector2.One, Texture[0, 0, 2, 3]) {
OnPressed = e => {
GameImpl.Instance.Tickets++;
CoroutineHandler.Start(WobbleElement(storeGroup));
},
OnPressed = e => GameImpl.Instance.Tickets++,
CanBeSelected = true,
CanBeMoused = true
});
main.OnAreaUpdated += e => storeGroup.Size = new Vector2(e.DisplayArea.Width / e.Scale);
main.AddChild(new Group(Anchor.AutoLeft, new Vector2(1, 0.35F), false) {
Padding = new Padding(4, 4, 12, 4),
OnDrawn = (e, time, batch, alpha) => {
var map = GameImpl.Instance.Map;
var mapSize = new Vector2(map.Width, map.Height) * Attraction.TileSize;
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);
}
});
this.currentUi = main;
this.uiSystem.Add("Main", main);