159 lines
6.5 KiB
C#
159 lines
6.5 KiB
C#
using System.Collections.Generic;
|
|
using Coroutine;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Content;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using MLEM.Cameras;
|
|
using MLEM.Extended.Extensions;
|
|
using MLEM.Font;
|
|
using MLEM.Startup;
|
|
using MLEM.Ui;
|
|
using MLEM.Ui.Elements;
|
|
using MonoGame.Extended;
|
|
using MonoGame.Extended.Tiled;
|
|
using ColorHelper = MLEM.Extensions.ColorHelper;
|
|
|
|
namespace GreatSpringGameJam {
|
|
public class GameImpl : MlemGame {
|
|
|
|
public static GameImpl Instance { get; private set; }
|
|
public Map Map { get; private set; }
|
|
public Player Player { get; private set; }
|
|
public Camera Camera { get; private set; }
|
|
public bool IsInCutscene { get; private set; }
|
|
private ContentManager mapLoader;
|
|
private int currentLevel;
|
|
|
|
public GameImpl() {
|
|
Instance = this;
|
|
this.IsMouseVisible = true;
|
|
}
|
|
|
|
protected override void LoadContent() {
|
|
this.GraphicsDeviceManager.PreferredBackBufferWidth = 1280;
|
|
this.GraphicsDeviceManager.PreferredBackBufferHeight = 720;
|
|
this.GraphicsDeviceManager.ApplyChanges();
|
|
base.LoadContent();
|
|
|
|
this.UiSystem.Style.Font = new GenericSpriteFont(LoadContent<SpriteFont>("Fonts/Regular"));
|
|
this.UiSystem.Style.TextScale = 0.075F;
|
|
this.UiSystem.Style.TextColor = ColorHelper.FromHexRgb(0xebd5bd);
|
|
this.UiSystem.AutoScaleWithScreen = true;
|
|
this.InputHandler.HandleKeyboardRepeats = false;
|
|
|
|
this.mapLoader = new ContentManager(this.Services, this.Content.RootDirectory);
|
|
this.Camera = new Camera(this.GraphicsDevice) {
|
|
AutoScaleWithScreen = true,
|
|
Scale = 4
|
|
};
|
|
this.StartLevel(1);
|
|
}
|
|
|
|
protected override void DoUpdate(GameTime gameTime) {
|
|
base.DoUpdate(gameTime);
|
|
this.Map.Update(gameTime);
|
|
if (!this.IsInCutscene)
|
|
this.FocusCameraOnPlayer();
|
|
}
|
|
|
|
protected override void DoDraw(GameTime gameTime) {
|
|
this.GraphicsDevice.Clear(ColorHelper.FromHexRgb(0x729cd4));
|
|
base.DoDraw(gameTime);
|
|
this.Map.Draw(gameTime, this.SpriteBatch, this.Camera);
|
|
}
|
|
|
|
public void Finish() {
|
|
IEnumerable<Wait> Impl() {
|
|
// scroll up
|
|
var offset = 0F;
|
|
while (offset < 1) {
|
|
this.Camera.LookingPosition -= new Vector2(0, offset) * this.Map.TileSize;
|
|
offset += 0.01F;
|
|
yield return new Wait(CoroutineEvents.Update);
|
|
}
|
|
|
|
// display end of level info
|
|
var snowRemoved = this.Map.TotalSnow - this.Map.GetTotalTiles("Snow");
|
|
var plantsGrown = this.Map.TotalSeeds - this.Map.GetTotalTiles("Seed");
|
|
// snow removal is less important
|
|
var completion = (snowRemoved / 3F + plantsGrown) / (this.Map.TotalSnow / 3F + this.Map.TotalSeeds);
|
|
|
|
var group = new Group(Anchor.Center, new Vector2(0.5F), false);
|
|
this.UiSystem.Add("EndCard", group);
|
|
group.AddChild(new Paragraph(Anchor.AutoCenter, 1, "Level Completed!", true) {TextScale = 0.125F});
|
|
group.AddChild(new VerticalSpace(15));
|
|
yield return new Wait(1);
|
|
group.AddChild(new Paragraph(Anchor.AutoCenter, 1, $"Snow Removed: {snowRemoved} / {this.Map.TotalSnow}", true));
|
|
yield return new Wait(1);
|
|
group.AddChild(new Paragraph(Anchor.AutoCenter, 1, $"Plants Watered: {plantsGrown} / {this.Map.TotalSeeds}", true));
|
|
yield return new Wait(1);
|
|
|
|
// display score
|
|
var completionCounter = 0;
|
|
group.AddChild(new VerticalSpace(10));
|
|
const string scoreText = "Score: {0}%";
|
|
var score = group.AddChild(new Paragraph(Anchor.AutoCenter, 1, string.Format(scoreText, 0), true) {TextScale = 0.1F});
|
|
while (completionCounter < completion * 100) {
|
|
completionCounter++;
|
|
score.Text = string.Format(scoreText, completionCounter);
|
|
yield return new Wait(0.03F);
|
|
}
|
|
|
|
yield return new Wait(3);
|
|
|
|
// fade out and move to next level
|
|
foreach (var wait in this.FadeAndStartLevel(this.currentLevel + 1, Color.White))
|
|
yield return wait;
|
|
}
|
|
|
|
this.IsInCutscene = true;
|
|
CoroutineHandler.Start(Impl());
|
|
}
|
|
|
|
public void RestartLevel() {
|
|
this.IsInCutscene = true;
|
|
CoroutineHandler.Start(this.FadeAndStartLevel(this.currentLevel, Color.Black));
|
|
}
|
|
|
|
private IEnumerable<Wait> FadeAndStartLevel(int level, Color color) {
|
|
var fadeOverlay = new Group(Anchor.TopLeft, Vector2.One, false) {
|
|
OnDrawn = (e, time, batch, a) => batch.FillRectangle(e.DisplayArea.ToExtended(), color * a),
|
|
DrawAlpha = 0
|
|
};
|
|
this.UiSystem.Add("Fade", fadeOverlay);
|
|
while (fadeOverlay.DrawAlpha < 1) {
|
|
fadeOverlay.DrawAlpha += 0.04F;
|
|
yield return new Wait(CoroutineEvents.Update);
|
|
}
|
|
yield return new Wait(0.25F);
|
|
|
|
this.UiSystem.Remove("EndCard");
|
|
this.StartLevel(level);
|
|
|
|
yield return new Wait(0.25F);
|
|
while (fadeOverlay.DrawAlpha > 0) {
|
|
fadeOverlay.DrawAlpha -= 0.04F;
|
|
yield return new Wait(CoroutineEvents.Update);
|
|
}
|
|
this.UiSystem.Remove(fadeOverlay.Root.Name);
|
|
|
|
this.IsInCutscene = false;
|
|
}
|
|
|
|
private void StartLevel(int level) {
|
|
this.currentLevel = level;
|
|
// dispose loaded maps so that edits don't persist
|
|
this.mapLoader.Unload();
|
|
this.Map = new Map(this.mapLoader.Load<TiledMap>($"Maps/Level{this.currentLevel}"));
|
|
this.Player = new Player(this.Map, this.Map.SpawnPoint.ToVector2());
|
|
this.Map.AddEntity(this.Player);
|
|
this.FocusCameraOnPlayer(1);
|
|
}
|
|
|
|
private void FocusCameraOnPlayer(float speed = 0.25F) {
|
|
this.Camera.LookingPosition = Vector2.Lerp(this.Camera.LookingPosition, (this.Player.Position + Vector2.One / 2) * this.Map.TileSize, speed);
|
|
this.Camera.ConstrainWorldBounds(Vector2.Zero, this.Map.SizeInPixels.ToVector2());
|
|
}
|
|
|
|
}
|
|
} |