112 lines
No EOL
5 KiB
C#
112 lines
No EOL
5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.Serialization;
|
|
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 {
|
|
[DataContract]
|
|
public class ParkMap {
|
|
|
|
[DataMember]
|
|
public readonly int Width;
|
|
[DataMember]
|
|
public readonly int Height;
|
|
[DataMember]
|
|
private readonly List<(Point, Attraction)> attractions = new List<(Point, Attraction)>();
|
|
|
|
public Attraction PlacingAttraction;
|
|
public Point PlacingPosition;
|
|
private bool draggingAttraction;
|
|
|
|
public ParkMap(int width, int height) {
|
|
this.Width = width;
|
|
this.Height = height;
|
|
}
|
|
|
|
public void Update(GameTime time, TimeSpan passed) {
|
|
foreach (var (_, attraction) in this.attractions)
|
|
attraction.Update(time, passed);
|
|
|
|
// 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 (pos, attraction) in this.attractions)
|
|
batch.Draw(attraction.Type.TextureRegion, position + pos.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.Type.TextureRegion, placingPos, Color.White * alpha * 0.5F, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
|
}
|
|
}
|
|
|
|
public bool CanPlace(Point position, Attraction attraction) {
|
|
foreach (var offset in attraction.GetCoveredTiles()) {
|
|
if (this.GetAttractionAt(position + offset) != null)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void Place(Point position, Attraction attraction) {
|
|
this.attractions.RemoveAll(pa => pa.Item1 == position);
|
|
this.attractions.Add((position, attraction));
|
|
}
|
|
|
|
public Attraction GetAttractionAt(Point position) {
|
|
foreach (var (pos, attraction) in this.attractions) {
|
|
if (attraction.GetCoveredTiles().Any(p => pos + p == position))
|
|
return attraction;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}
|
|
} |