a bunch of stuff! yay!
This commit is contained in:
parent
f485f10c9f
commit
7c51c923b9
8 changed files with 147 additions and 46 deletions
|
@ -14,12 +14,12 @@ namespace ThemeParkClicker.Attractions {
|
|||
|
||||
static Attraction() {
|
||||
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));
|
||||
Attractions.Add("FoodCourt", () => new Attraction(new[,] {{true, true}}, Texture[1, 0, 2, 1], 1.1F, 300));
|
||||
}
|
||||
|
||||
private readonly bool[,] area;
|
||||
public int Width => this.area.GetLength(0);
|
||||
public int Height => this.area.GetLength(1);
|
||||
public int Width => this.area.GetLength(1);
|
||||
public int Height => this.area.GetLength(0);
|
||||
public readonly TextureRegion TextureRegion;
|
||||
public readonly float GenerationPerSecond;
|
||||
public readonly long InitialPrice;
|
||||
|
@ -32,8 +32,13 @@ namespace ThemeParkClicker.Attractions {
|
|||
this.InitialPrice = initialPrice;
|
||||
}
|
||||
|
||||
public bool HasTileAt(int x, int y) {
|
||||
return this.area[y, x];
|
||||
public IEnumerable<Point> GetCoveredTiles() {
|
||||
for (var x = 0; x < this.Width; x++) {
|
||||
for (var y = 0; y < this.Height; y++) {
|
||||
if (this.area[y, x])
|
||||
yield return new Point(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public delegate Attraction Constructor();
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -11,12 +11,25 @@ namespace ThemeParkClicker {
|
|||
public class GameImpl : MlemGame {
|
||||
|
||||
public static GameImpl Instance { get; private set; }
|
||||
public BigInteger Tickets = 200;
|
||||
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 ParkMap Map { get; private set; }
|
||||
public Camera Camera { get; private set; }
|
||||
public Ui Ui { get; private set; }
|
||||
public bool DrawMap;
|
||||
|
||||
public float TicketsPerSecond { get; private set; }
|
||||
private long ticketsPerSecondCounter;
|
||||
private double secondCounter;
|
||||
|
||||
public GameImpl() {
|
||||
Instance = this;
|
||||
}
|
||||
|
@ -26,17 +39,20 @@ namespace ThemeParkClicker {
|
|||
this.Ui = new Ui(this.UiSystem);
|
||||
this.Map = new ParkMap(10, 10);
|
||||
this.Camera = new Camera(this.GraphicsDevice) {
|
||||
Scale = 16,
|
||||
Scale = 5,
|
||||
AutoScaleWithScreen = true,
|
||||
AutoScaleReferenceSize = new Point(720, 1280),
|
||||
MaxScale = 24,
|
||||
MinScale = 4
|
||||
MinScale = 3
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
this.Tickets = 1000;
|
||||
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"]());
|
||||
#endif
|
||||
}
|
||||
|
||||
public string DisplayTicketCount() {
|
||||
|
@ -47,13 +63,21 @@ namespace ThemeParkClicker {
|
|||
base.DoUpdate(gameTime);
|
||||
this.Map.Update(gameTime);
|
||||
this.Ui.Update(gameTime);
|
||||
|
||||
// we average tickets per second over two seconds
|
||||
this.secondCounter += gameTime.ElapsedGameTime.TotalSeconds;
|
||||
if (this.secondCounter >= 2) {
|
||||
this.secondCounter -= 2;
|
||||
this.TicketsPerSecond = this.ticketsPerSecondCounter / 2F;
|
||||
this.ticketsPerSecondCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoDraw(GameTime gameTime) {
|
||||
this.GraphicsDevice.Clear(Color.Black);
|
||||
if (this.DrawMap) {
|
||||
this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: this.Camera.ViewMatrix);
|
||||
this.Map.Draw(gameTime, this.SpriteBatch, Vector2.Zero, 1);
|
||||
this.Map.Draw(gameTime, this.SpriteBatch, Vector2.Zero, 1, 1);
|
||||
this.SpriteBatch.End();
|
||||
}
|
||||
base.DoDraw(gameTime);
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace ThemeParkClicker {
|
|||
private readonly Attraction[,] grid;
|
||||
private readonly Dictionary<Point, Attraction> attractions = new Dictionary<Point, Attraction>();
|
||||
|
||||
public Attraction PlacingAttraction;
|
||||
public Point PlacingPosition;
|
||||
private bool draggingAttraction;
|
||||
|
||||
public ParkMap(int width, int height) {
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
|
@ -43,35 +47,55 @@ namespace ThemeParkClicker {
|
|||
camera.Zoom(-pinch.Delta.Length() / camera.Scale);
|
||||
}
|
||||
} else if (MlemGame.Input.GetGesture(GestureType.FreeDrag, out var drag)) {
|
||||
if (this.draggingAttraction) {
|
||||
// move the current placing position
|
||||
var nextPos = (camera.ToWorldPos(drag.Position + drag.Delta) / Attraction.TileSize).ToPoint();
|
||||
if (nextPos.X >= 0 && nextPos.Y >= 0 && nextPos.X < this.Width && nextPos.Y < this.Height)
|
||||
this.PlacingPosition = nextPos;
|
||||
} else {
|
||||
// move the camera
|
||||
camera.Position -= drag.Delta / camera.Scale;
|
||||
}
|
||||
} else if (this.PlacingAttraction != null) {
|
||||
foreach (var touch in MlemGame.Input.TouchState) {
|
||||
if (touch.State != TouchLocationState.Pressed)
|
||||
continue;
|
||||
// when first pressing down, go into attraction drag mode if we're touching the place location
|
||||
var offset = (camera.ToWorldPos(touch.Position) / Attraction.TileSize).ToPoint();
|
||||
this.draggingAttraction = this.PlacingAttraction.GetCoveredTiles()
|
||||
.Any(p => this.PlacingPosition + p == offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale) {
|
||||
public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale, float alpha) {
|
||||
var tileSize = Attraction.TileSize * scale;
|
||||
// draw ground
|
||||
batch.Draw(batch.GetBlankTexture(), new RectangleF(position, new Vector2(this.Width, this.Height) * tileSize), ColorExtensions.FromHex(0xff53a662));
|
||||
batch.Draw(batch.GetBlankTexture(), new RectangleF(position, new Vector2(this.Width, this.Height) * tileSize), ColorExtensions.FromHex(0xff53a662) * alpha);
|
||||
// draw attractions
|
||||
foreach (var kv in this.attractions)
|
||||
batch.Draw(kv.Value.TextureRegion, position + kv.Key.ToVector2() * tileSize, Color.White);
|
||||
batch.Draw(kv.Value.TextureRegion, position + kv.Key.ToVector2() * tileSize, Color.White * alpha, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
||||
// placing attraction
|
||||
if (this.PlacingAttraction != null) {
|
||||
var placingPos = position + this.PlacingPosition.ToVector2() * tileSize;
|
||||
foreach (var pos in this.PlacingAttraction.GetCoveredTiles())
|
||||
batch.Draw(batch.GetBlankTexture(), new RectangleF(placingPos + pos.ToVector2() * tileSize, tileSize), Color.Black * 0.15F * alpha);
|
||||
batch.Draw(this.PlacingAttraction.TextureRegion, placingPos, Color.White * alpha * 0.5F, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanPlace(Point position, Attraction attraction) {
|
||||
for (var x = 0; x < attraction.Width; x++) {
|
||||
for (var y = 0; y < attraction.Height; y++) {
|
||||
foreach (var (x, y) in attraction.GetCoveredTiles()) {
|
||||
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++)
|
||||
foreach (var (x, y) in attraction.GetCoveredTiles())
|
||||
this.grid[position.X + x, position.Y + y] = attraction;
|
||||
}
|
||||
this.attractions[position] = attraction;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ namespace ThemeParkClicker {
|
|||
return this.position.Y >= 1.15F;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch batch, Vector2 viewport, float scale) {
|
||||
public void Draw(SpriteBatch batch, Vector2 viewport, float scale, Color color) {
|
||||
var tex = Ui.Texture[2, 0];
|
||||
batch.Draw(tex, this.position * viewport, Color.White, this.rotation, tex.Size.ToVector2() / 2, scale, SpriteEffects.None, 0);
|
||||
batch.Draw(tex, this.position * viewport, color, this.rotation, tex.Size.ToVector2() / 2, scale, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Coroutine" Version="1.0.4" />
|
||||
<PackageReference Include="MLEM.Startup" Version="3.3.3-189" />
|
||||
<PackageReference Include="MonoGame.Framework.Portable" Version="3.7.1.189">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace ThemeParkClicker {
|
|||
private bool finishingSwipe;
|
||||
|
||||
public Ui(UiSystem uiSystem) {
|
||||
InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.FreeDrag, GestureType.Pinch);
|
||||
InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.FreeDrag, GestureType.Pinch, GestureType.Tap);
|
||||
this.uiSystem = uiSystem;
|
||||
this.uiSystem.GlobalScale = 4;
|
||||
this.uiSystem.AutoScaleWithScreen = true;
|
||||
|
@ -45,19 +45,22 @@ namespace ThemeParkClicker {
|
|||
if (rainingTickets[i].Update())
|
||||
rainingTickets.RemoveAt(i);
|
||||
}
|
||||
while (rainingTickets.Count < BigInteger.Min(GameImpl.Instance.Tickets / 100, 500))
|
||||
while (rainingTickets.Count < Math.Min(GameImpl.Instance.TicketsPerSecond / 10, 500))
|
||||
rainingTickets.Add(new RainingTicket());
|
||||
},
|
||||
OnDrawn = (e, time, batch, alpha) => {
|
||||
batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorExtensions.FromHex(0xff86cfcb));
|
||||
batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorExtensions.FromHex(0xff86cfcb) * alpha);
|
||||
foreach (var ticket in rainingTickets)
|
||||
ticket.Draw(batch, e.DisplayArea.Size, e.Scale);
|
||||
ticket.Draw(batch, e.DisplayArea.Size, e.Scale, Color.White * alpha);
|
||||
}
|
||||
};
|
||||
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
|
||||
});
|
||||
ticketGroup.AddChild(new Paragraph(Anchor.AutoCenter, 1, p => GameImpl.Instance.TicketsPerSecond.ToString("0.##") + "<i ticket>/s", true) {
|
||||
PositionOffset = new Vector2(0, -8)
|
||||
});
|
||||
BigInteger lastTickets = 0;
|
||||
var storeGroup = main.AddChild(new CustomDrawGroup(Anchor.AutoCenter, new Vector2(1, 0.5F), null, null, false) {
|
||||
OnUpdated = (e, time) => {
|
||||
|
@ -80,9 +83,21 @@ 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);
|
||||
map.Draw(time, batch, pos, scale, alpha);
|
||||
},
|
||||
OnPressed = e => CoroutineHandler.Start(this.SwipeUi(true))
|
||||
OnPressed = e => {
|
||||
var map = GameImpl.Instance.Map;
|
||||
GameImpl.Instance.Camera.LookingPosition = new Vector2(map.Width, map.Height) / 2 * Attraction.TileSize;
|
||||
|
||||
var backUi = new Group(Anchor.BottomLeft, new Vector2(1));
|
||||
backUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(1, 40), "Back") {
|
||||
OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name))
|
||||
});
|
||||
// we want this to render below the main ui while it fades away
|
||||
this.uiSystem.Add("MapViewBack", backUi).Priority = -100;
|
||||
|
||||
this.FadeUi(true);
|
||||
}
|
||||
});
|
||||
this.currentUi = main;
|
||||
this.uiSystem.Add("Main", main);
|
||||
|
@ -96,12 +111,36 @@ namespace ThemeParkClicker {
|
|||
var instance = attraction.Value();
|
||||
var button = buyUi.AddChild(new Button(Anchor.AutoLeft, new Vector2(1, 40)) {
|
||||
ChildPadding = new Vector2(4),
|
||||
Padding = new Padding(0, 0, 0, 4)
|
||||
Padding = new Padding(0, 0, 0, 4),
|
||||
OnPressed = e => {
|
||||
var map = GameImpl.Instance.Map;
|
||||
var pos = new Vector2(map.Width, map.Height) / 2;
|
||||
GameImpl.Instance.Camera.LookingPosition = (pos + new Vector2(0.5F)) * Attraction.TileSize;
|
||||
map.PlacingAttraction = attraction.Value();
|
||||
map.PlacingPosition = pos.ToPoint();
|
||||
|
||||
var yesNoUi = new Group(Anchor.BottomLeft, new Vector2(1));
|
||||
yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), "Back") {
|
||||
OnPressed = e2 => this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name))
|
||||
});
|
||||
yesNoUi.AddChild(new Button(Anchor.AutoInlineIgnoreOverflow, new Vector2(0.5F, 40), "Place") {
|
||||
OnPressed = e2 => {
|
||||
GameImpl.Instance.Tickets -= map.PlacingAttraction.GetPrice();
|
||||
map.Place(map.PlacingPosition, map.PlacingAttraction);
|
||||
this.FadeUi(false, () => this.uiSystem.Remove(e2.Root.Name));
|
||||
},
|
||||
OnUpdated = (e2, time) => ((Button) e2).IsDisabled = !map.CanPlace(map.PlacingPosition, map.PlacingAttraction)
|
||||
});
|
||||
// we want this to render below the main ui while it fades away
|
||||
this.uiSystem.Add("PlacingYesNo", yesNoUi).Priority = -100;
|
||||
|
||||
this.FadeUi(true);
|
||||
}
|
||||
});
|
||||
button.OnUpdated += (e, time) => {
|
||||
button.IsDisabled = GameImpl.Instance.Tickets < instance.GetPrice();
|
||||
};
|
||||
var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false));
|
||||
var center = button.AddChild(new Group(Anchor.Center, new Vector2(0.8F, 1), false) {CanBeMoused = false});
|
||||
center.AddChild(new Paragraph(Anchor.AutoCenter, 1, attraction.Key, true));
|
||||
center.AddChild(new Paragraph(Anchor.AutoCenter, 1, instance.GenerationPerSecond + "<i ticket>/s", true) {TextScale = 0.08F});
|
||||
var image = button.AddChild(new Image(Anchor.CenterLeft, new Vector2(1), instance.TextureRegion) {
|
||||
|
@ -167,21 +206,29 @@ namespace ThemeParkClicker {
|
|||
}
|
||||
}
|
||||
|
||||
private IEnumerator<IWait> SwipeUi(bool swipeOut) {
|
||||
private void FadeUi(bool fadeOut, Action after = null) {
|
||||
IEnumerator<IWait> Impl() {
|
||||
// disable input handling during fade
|
||||
this.uiSystem.Controls.HandleTouch = false;
|
||||
GameImpl.Instance.DrawMap = true;
|
||||
this.currentUi.IsHidden = false;
|
||||
var offset = 0F;
|
||||
while (offset < 1) {
|
||||
offset += 0.025F;
|
||||
var trans = (!swipeOut ? 1 - offset : offset) * this.currentUi.DisplayArea.Height;
|
||||
this.currentUi.Root.Transform = Matrix.CreateTranslation(0, trans, 0);
|
||||
var alpha = 1F;
|
||||
while (alpha > 0) {
|
||||
alpha -= 0.03F;
|
||||
this.currentUi.DrawAlpha = !fadeOut ? 1 - alpha : alpha;
|
||||
yield return new WaitEvent(CoroutineEvents.Update);
|
||||
}
|
||||
this.currentUi.Root.Transform = Matrix.Identity;
|
||||
GameImpl.Instance.DrawMap = swipeOut;
|
||||
this.currentUi.IsHidden = swipeOut;
|
||||
this.uiSystem.Controls.HandleTouch = true;
|
||||
GameImpl.Instance.DrawMap = fadeOut;
|
||||
this.currentUi.IsHidden = fadeOut;
|
||||
// disable horizontal and vertical drag on map view to allow free drag to take priority
|
||||
InputHandler.SetGesturesEnabled(!swipeOut, GestureType.HorizontalDrag, GestureType.VerticalDrag);
|
||||
InputHandler.SetGesturesEnabled(!fadeOut, GestureType.HorizontalDrag, GestureType.VerticalDrag);
|
||||
if (!fadeOut)
|
||||
GameImpl.Instance.Map.PlacingAttraction = null;
|
||||
after?.Invoke();
|
||||
}
|
||||
|
||||
CoroutineHandler.Start(Impl());
|
||||
}
|
||||
|
||||
private static IEnumerator<IWait> WobbleElement(CustomDrawGroup element, float intensity = 0.02F) {
|
||||
|
|
Loading…
Reference in a new issue