diff --git a/ThemeParkClicker/GameImpl.cs b/ThemeParkClicker/GameImpl.cs index 69b1d34..3e683fe 100644 --- a/ThemeParkClicker/GameImpl.cs +++ b/ThemeParkClicker/GameImpl.cs @@ -15,6 +15,7 @@ namespace ThemeParkClicker { public ParkMap Map { get; private set; } public Camera Camera { get; private set; } public Ui Ui { get; private set; } + public bool DrawMap; public GameImpl() { Instance = this; @@ -25,14 +26,17 @@ namespace ThemeParkClicker { this.Ui = new Ui(this.UiSystem); this.Map = new ParkMap(10, 10); this.Camera = new Camera(this.GraphicsDevice) { - Scale = 4, - AutoScaleWithScreen = true + Scale = 16, + AutoScaleWithScreen = true, + AutoScaleReferenceSize = new Point(720, 1280), + MaxScale = 24, + MinScale = 4 }; 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"]()); + this.Map.Place(new Point(1, 2), Attraction.Attractions["FoodCourt"]()); } public string DisplayTicketCount() { @@ -46,7 +50,12 @@ namespace ThemeParkClicker { } protected override void DoDraw(GameTime gameTime) { - this.GraphicsDevice.Clear(ColorExtensions.FromHex(0x86cfcb)); + 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.SpriteBatch.End(); + } base.DoDraw(gameTime); } diff --git a/ThemeParkClicker/ParkMap.cs b/ThemeParkClicker/ParkMap.cs index a0162b7..d2d618c 100644 --- a/ThemeParkClicker/ParkMap.cs +++ b/ThemeParkClicker/ParkMap.cs @@ -1,6 +1,9 @@ +using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input.Touch; using MLEM.Extensions; using MLEM.Misc; using MLEM.Startup; @@ -25,6 +28,24 @@ namespace ThemeParkClicker { public void Update(GameTime time) { foreach (var attraction in this.attractions.Values) attraction.GainTickets(time); + + // map movement + if (GameImpl.Instance.DrawMap) { + var camera = GameImpl.Instance.Camera; + if (MlemGame.Input.GetGesture(GestureType.Pinch, out var pinch)) { + var startDiff = pinch.Position2 - pinch.Position; + var endDiff = pinch.Position2 + pinch.Delta2 - (pinch.Position + pinch.Delta); + if (startDiff.LengthSquared() < endDiff.LengthSquared()) { + // zooming in + camera.Zoom(pinch.Delta.Length() / camera.Scale); + } else { + // zooming out + camera.Zoom(-pinch.Delta.Length() / camera.Scale); + } + } else if (MlemGame.Input.GetGesture(GestureType.FreeDrag, out var drag)) { + camera.Position -= drag.Delta / camera.Scale; + } + } } public void Draw(GameTime time, SpriteBatch batch, Vector2 position, float scale) { diff --git a/ThemeParkClicker/ThemeParkClicker.csproj b/ThemeParkClicker/ThemeParkClicker.csproj index c026cfb..b11e499 100644 --- a/ThemeParkClicker/ThemeParkClicker.csproj +++ b/ThemeParkClicker/ThemeParkClicker.csproj @@ -5,7 +5,7 @@ - + all diff --git a/ThemeParkClicker/Ui.cs b/ThemeParkClicker/Ui.cs index 6d98d48..8104e1a 100644 --- a/ThemeParkClicker/Ui.cs +++ b/ThemeParkClicker/Ui.cs @@ -28,7 +28,7 @@ namespace ThemeParkClicker { private bool finishingSwipe; public Ui(UiSystem uiSystem) { - InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.Pinch); + InputHandler.EnableGestures(GestureType.HorizontalDrag, GestureType.FreeDrag, GestureType.Pinch); this.uiSystem = uiSystem; this.uiSystem.GlobalScale = 4; this.uiSystem.AutoScaleWithScreen = true; @@ -49,6 +49,7 @@ namespace ThemeParkClicker { rainingTickets.Add(new RainingTicket()); }, OnDrawn = (e, time, batch, alpha) => { + batch.Draw(batch.GetBlankTexture(), e.DisplayArea, ColorExtensions.FromHex(0xff86cfcb)); foreach (var ticket in rainingTickets) ticket.Draw(batch, e.DisplayArea.Size, e.Scale); } @@ -80,7 +81,8 @@ namespace ThemeParkClicker { var scale = Math.Min(scaleX, scaleY); var pos = e.DisplayArea.Location + (e.DisplayArea.Size - mapSize * scale) / 2; map.Draw(time, batch, pos, scale); - } + }, + OnPressed = e => CoroutineHandler.Start(this.SwipeUi(true)) }); this.currentUi = main; this.uiSystem.Add("Main", main); @@ -115,42 +117,44 @@ namespace ThemeParkClicker { public void Update(GameTime time) { // swiping between tabs - if (MlemGame.Input.GetGesture(GestureType.HorizontalDrag, out var gesture)) { - this.swipeProgress -= gesture.Delta.X / this.currentUi.DisplayArea.Width; - } else if (!this.finishingSwipe && this.swipeProgress != 0 && !MlemGame.Input.TouchState.Any()) { - // if we're not dragging or holding, we need to move back to our current ui - this.swipeProgress -= Math.Sign(this.swipeProgress) * 0.03F; - if (this.swipeProgress.Equals(0, 0.03F)) - this.ResetSwipe(); - } - - if (this.swipeProgress != 0) { - // actual swipe reaction logic - var curr = Array.IndexOf(this.swipeRelations, this.currentUi); - var next = curr + Math.Sign(this.swipeProgress); - if (next >= 0 && next < this.swipeRelations.Length) { - this.swipeRelations[next].IsHidden = false; - // if we've swiped a bit, we count this as a success and move to the next ui - this.finishingSwipe = Math.Abs(this.swipeProgress) >= 0.15F; - // if we're in the process of finishing a swipe, move without requiring input - if (this.finishingSwipe) { - if (!MlemGame.Input.TouchState.Any()) - this.swipeProgress += Math.Sign(this.swipeProgress) * 0.05F; - // we're done with the swipe, so switch the active ui - if (this.swipeProgress.Equals(Math.Sign(this.swipeProgress), 0.05F)) { - this.currentUi = this.swipeRelations[next]; - this.ResetSwipe(); - } - } - } else { - // when we're swiping into the void, we want to stop at the max - this.swipeProgress = MathHelper.Clamp(this.swipeProgress, -1, 1); + if (!this.currentUi.IsHidden) { + if (MlemGame.Input.GetGesture(GestureType.HorizontalDrag, out var gesture)) { + this.swipeProgress -= gesture.Delta.X / this.currentUi.DisplayArea.Width; + } else if (!this.finishingSwipe && this.swipeProgress != 0 && !MlemGame.Input.TouchState.Any()) { + // if we're not dragging or holding, we need to move back to our current ui + this.swipeProgress -= Math.Sign(this.swipeProgress) * 0.03F; + if (this.swipeProgress.Equals(0, 0.03F)) + this.ResetSwipe(); } - // update element positions - this.currentUi.Root.Transform = Matrix.CreateTranslation(-this.swipeProgress * this.currentUi.DisplayArea.Width, 0, 0); - if (next >= 0 && next < this.swipeRelations.Length) - this.swipeRelations[next].Root.Transform = Matrix.CreateTranslation((Math.Sign(this.swipeProgress) - this.swipeProgress) * this.swipeRelations[next].DisplayArea.Width, 0, 0); + if (this.swipeProgress != 0) { + // actual swipe reaction logic + var curr = Array.IndexOf(this.swipeRelations, this.currentUi); + var next = curr + Math.Sign(this.swipeProgress); + if (next >= 0 && next < this.swipeRelations.Length) { + this.swipeRelations[next].IsHidden = false; + // if we've swiped a bit, we count this as a success and move to the next ui + this.finishingSwipe = Math.Abs(this.swipeProgress) >= 0.15F; + // if we're in the process of finishing a swipe, move without requiring input + if (this.finishingSwipe) { + if (!MlemGame.Input.TouchState.Any()) + this.swipeProgress += Math.Sign(this.swipeProgress) * 0.05F; + // we're done with the swipe, so switch the active ui + if (this.swipeProgress.Equals(Math.Sign(this.swipeProgress), 0.05F)) { + this.currentUi = this.swipeRelations[next]; + this.ResetSwipe(); + } + } + } else { + // when we're swiping into the void, we want to stop at the max + this.swipeProgress = MathHelper.Clamp(this.swipeProgress, -1, 1); + } + + // update element positions + this.currentUi.Root.Transform = Matrix.CreateTranslation(-this.swipeProgress * this.currentUi.DisplayArea.Width, 0, 0); + if (next >= 0 && next < this.swipeRelations.Length) + this.swipeRelations[next].Root.Transform = Matrix.CreateTranslation((Math.Sign(this.swipeProgress) - this.swipeProgress) * this.swipeRelations[next].DisplayArea.Width, 0, 0); + } } } @@ -163,6 +167,23 @@ namespace ThemeParkClicker { } } + private IEnumerator SwipeUi(bool swipeOut) { + 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); + yield return new WaitEvent(CoroutineEvents.Update); + } + this.currentUi.Root.Transform = Matrix.Identity; + GameImpl.Instance.DrawMap = swipeOut; + this.currentUi.IsHidden = swipeOut; + // disable horizontal and vertical drag on map view to allow free drag to take priority + InputHandler.SetGesturesEnabled(!swipeOut, GestureType.HorizontalDrag, GestureType.VerticalDrag); + } + private static IEnumerator WobbleElement(CustomDrawGroup element, float intensity = 0.02F) { var sin = 0F; while (sin < MathHelper.Pi) {