TouchyTickets/ThemeParkClicker/ParkMap.cs
2020-06-01 01:21:54 +02:00

103 lines
4.8 KiB
C#

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;
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 Attraction PlacingAttraction;
public Point PlacingPosition;
private bool draggingAttraction;
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);
// 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)) {
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, 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) * alpha);
// draw attractions
foreach (var kv in this.attractions)
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) {
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) {
foreach (var (x, y) in attraction.GetCoveredTiles())
this.grid[position.X + x, position.Y + y] = attraction;
this.attractions[position] = attraction;
}
}
}