Skip to content

Commit

Permalink
Added Game options
Browse files Browse the repository at this point in the history
Created toolbar menu
- new game
- pause / resume
- mode change option
- exit

Each game creates coins on random places. Game timer stops after all coins are collected.
  • Loading branch information
fihorvat committed Jan 31, 2021
1 parent 90205d4 commit 617af5f
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 86 deletions.
84 changes: 83 additions & 1 deletion src/Engine/Canvas.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,94 @@
using System.Windows.Forms;
using System;
using System.Linq;
using System.Windows.Forms;

namespace GameEngine
{

public class Canvas : Form
{
public static event EventHandler OnNewGameClick;
public static event EventHandler<bool> OnPauseResumeClick;
public static event EventHandler<bool> OnShowMapClick;
public static event EventHandler OnExitClick;

public Canvas()
{
DoubleBuffered = true;
InitializeComponent();
}

void InitializeComponent()
{
var toolStrip = new ToolStrip();
toolStrip.SuspendLayout();
SuspendLayout();
toolStrip.BackColor = System.Drawing.Color.Transparent;
toolStrip.GripStyle = ToolStripGripStyle.Hidden;
toolStrip.Items.AddRange(new[] { GetToolbar() });

Controls.Add(toolStrip);
toolStrip.ResumeLayout(false);
toolStrip.PerformLayout();
toolStrip.Renderer = new MyToolStripRenderer();
ResumeLayout(false);
PerformLayout();
}

ToolStripItem GetToolbar()
{
var toolbar = new ToolStripDropDownButton
{
BackColor = System.Drawing.Color.White,
DisplayStyle = ToolStripItemDisplayStyle.Text
};
toolbar.DropDownItems.AddRange(_toolstripItemsMap.Select(x => x.MenuItem).ToArray());
toolbar.Text = "File";
return toolbar;
}

readonly IToolstripItem[] _toolstripItemsMap = new IToolstripItem[]{
new ToolstripItem("New Game", ()=> OnNewGameClick?.Invoke(null, null)),
new BooleanToolstripItem("Pause", (ToolStripMenuItem menuItem, bool isChecked) => {
menuItem.Text = isChecked ? "Resume" : "Pause";
OnPauseResumeClick?.Invoke(null, isChecked);
}),
new BooleanToolstripItem("Show map", (ToolStripMenuItem _, bool isChecked) => OnShowMapClick?.Invoke(null, isChecked)),
new ToolstripItem("Exit", ()=>OnExitClick?.Invoke(null, null) ),
};

public interface IToolstripItem
{
ToolStripMenuItem MenuItem { get; set; }
}

public class ToolstripItem : IToolstripItem
{
public ToolstripItem(string text, Action onClick)
{
MenuItem = new ToolStripMenuItem { Text = text };
MenuItem.Click += (object sender, EventArgs e) => onClick();
}
public ToolStripMenuItem MenuItem { get; set; }
}

public class BooleanToolstripItem : IToolstripItem
{
public BooleanToolstripItem(string text, Action<ToolStripMenuItem, bool> onChecked = null)
{
MenuItem = new ToolStripMenuItem { Text = text, CheckOnClick = true, };
MenuItem.CheckedChanged += (object sender, EventArgs e) => onChecked((ToolStripMenuItem)sender, ((ToolStripMenuItem)sender).Checked);
}
public ToolStripMenuItem MenuItem { get; set; }
}

public class MyToolStripRenderer : ToolStripSystemRenderer
{
//This fixes the system bug for white underline https://stackoverflow.com/questions/1918247/how-to-disable-the-line-under-tool-strip-in-winform-c
protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
{
//base.OnRenderToolStripBorder(e);
}
}
}
}
80 changes: 48 additions & 32 deletions src/Engine/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ public abstract class Engine
public Canvas Window;
public Color BackgroundColor = Color.Black;
public Vector2 CameraPosition = Vector2.Zero();
public float CameraAngle = 0f;
public Stopwatch GameTime = new Stopwatch();
public float CameraAngle;
public bool IsPause;
public bool IsMapVisible;
public bool IsEnd;

protected Engine(string title, Vector2 screenSize)
{
Expand All @@ -31,6 +34,11 @@ protected Engine(string title, Vector2 screenSize)
Window.KeyUp += Window_KeyUp;
Window.Resize += Window_Resize;

Canvas.OnNewGameClick += (object sender, EventArgs e) => OnLoad();
Canvas.OnPauseResumeClick += (object _, bool isChecked) => { IsPause = isChecked; if (isChecked) GameTime.Stop(); else GameTime.Start(); };
Canvas.OnShowMapClick += (object _, bool isChecked) => IsMapVisible = isChecked;
Canvas.OnExitClick += (object sender, EventArgs e) => Window.Close();

GameLoopThread = new Thread(GameLoop);
GameLoopThread.Start();
GameTime.Start();
Expand All @@ -55,7 +63,7 @@ protected void AdjustCamera()

void Window_Resize(object sender, EventArgs e) => AdjustCamera();
void Window_KeyUp(object sender, KeyEventArgs e) => OnKeyUp(e);
void Window_KeyDown(object sender, KeyEventArgs e) => OnKeyDown(e);
void Window_KeyDown(object sender, KeyEventArgs e) { if (!IsPause) OnKeyDown(e); }
void Window_Closing(object sender, FormClosingEventArgs e) => GameLoopThread.Abort();

void GameLoop()
Expand All @@ -78,45 +86,53 @@ void Window_Renderer(object sender, PaintEventArgs e)
graphics.TranslateTransform(CameraPosition.X, CameraPosition.Y);

//border
var borderWidth = 3;
graphics.DrawRectangle(new Pen(Color.DarkRed, borderWidth), -borderWidth, -borderWidth, MapProvider.MapWidth + borderWidth, MapProvider.MapHeight + borderWidth);
const int borderWidth = 1;
graphics.DrawRectangle(new Pen(Color.DarkGray, borderWidth), -borderWidth, -borderWidth, MapProvider.MapWidth + borderWidth, MapProvider.MapHeight + borderWidth);

//score
var score = ScoreService.Get(GameObjects);
var score = ScoreService.Get();
var timeText = $"Time: {(GameTime.Elapsed.Minutes < 10 ? "0" : "")}{GameTime.Elapsed.Minutes}:{(GameTime.Elapsed.Seconds < 10 ? "0" : "")}{GameTime.Elapsed.Seconds}";
var scoreText = $"Score: {score.Current} / {score.Total}";
var text = $"{scoreText} | {timeText}";
var drawFormat = new StringFormat { Alignment = StringAlignment.Center };
graphics.DrawString(text, new Font("Arial", 20, FontStyle.Bold), new SolidBrush(Color.White), MapProvider.MapWidth / 2, -40, drawFormat);
var drawFormat = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Far };
graphics.DrawString(text, new Font("Arial", 20, FontStyle.Bold), new SolidBrush(Color.White), MapProvider.MapWidth / 2, 0, drawFormat);

if (IsMapVisible)
DrawMap(graphics);
else
DrawFlashliteMode(graphics);

//----------------
//If we want to show everything uncomment
foreach (var gameObject in GameObjects.ToArray())
graphics.DrawImage(gameObject.Sprite, gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
//----------------
if (score.IsEnd)
GameTime.Stop();
}

//----------------
void DrawFlashliteMode(Graphics graphics)
{
//This will show only whats is in reach
//var player = GameObjects.Find(x => x.Type == GameObjectType.Player);
//if (player != null)
//{
// var radius = 70;
// var x = (player.Position.X + (player.Scale.X / 2)) - radius / 2;
// var y = (player.Position.Y + (player.Scale.Y / 2)) - radius / 2;


// graphics.DrawEllipse(new Pen(Brushes.Yellow, radius), x, y, radius, radius);
// graphics.DrawImage(player.Sprite, player.Position.X, player.Position.Y, player.Scale.X, player.Scale.Y);
//}

//foreach (var gameObject in GameObjectsInReach.ToArray())
//{
// graphics.DrawImage(gameObject.Sprite, gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
// //Uncomment for displaying borders around elements in reach
// //graphics.DrawRectangle(new Pen(Brushes.DarkRed), gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
//}
//----------------
var player = GameObjects.Find(x => x.Type == GameObjectType.Player);
if (player != null)
{
const int radius = 70;
var x = (player.Position.X + (player.Scale.X / 2)) - (radius / 2);
var y = (player.Position.Y + (player.Scale.Y / 2)) - (radius / 2);

graphics.DrawEllipse(new Pen(Brushes.Yellow, radius), x, y, radius, radius);
graphics.DrawImage(player.Sprite, player.Position.X, player.Position.Y, player.Scale.X, player.Scale.Y);
}

foreach (var gameObject in GameObjectsInReach.ToArray())
{
graphics.DrawImage(gameObject.Sprite, gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
//Uncomment for displaying borders around elements in reach
//graphics.DrawRectangle(new Pen(Brushes.DarkRed), gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
}
}

void DrawMap(Graphics graphics)
{
//If we want to show everything
foreach (var gameObject in GameObjects.ToArray())
graphics.DrawImage(gameObject.Sprite, gameObject.Position.X, gameObject.Position.Y, gameObject.Scale.X, gameObject.Scale.Y);
}
}
}
58 changes: 33 additions & 25 deletions src/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ public class Game : Engine

BitmapProvider BitmapProvider { get; } = new BitmapProvider();
GameObject _player;
const int _coinsCount = 20;

public override void OnLoad()
{
var map = MapProvider.Get;
GameObjects.Clear();
GameTime.Restart();
MapProvider.InitializeMap(_coinsCount);

var map = MapProvider.Map;
var objects = new List<GameObject>();
for (int i = 0; i < map.GetLength(1); i++)
{
Expand Down Expand Up @@ -45,6 +50,7 @@ public override void OnLoad()
}

GameObjects.AddRange(objects);
ScoreService.CalculateScore(GameObjects);
AdjustCamera();
}

Expand All @@ -54,12 +60,6 @@ public override void OnDraw()
{
}

bool _up;
bool _down;
bool _left;
bool _right;
bool _shift;

public override void OnUpdate()
{
const double threshold = 50;
Expand All @@ -69,6 +69,32 @@ public override void OnUpdate()
var colideElement = GameObjectsInReach.FirstOrDefault(tile => _player.IsColliding(tile));
if (colideElement?.Type == GameObjectType.Coin)
GameObjects.Remove(colideElement);

ScoreService.CalculateScore(GameObjects);
}

bool _up;
bool _down;
bool _left;
bool _right;
bool _shift;

public override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up) { _up = true; }
if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left) { _left = true; }
if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down) { _down = true; }
if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right) { _right = true; }
if (e.KeyCode == Keys.ShiftKey) { _shift = true; }
}

public override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up) { _up = false; }
if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left) { _left = false; }
if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down) { _down = false; }
if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right) { _right = false; }
if (e.KeyCode == Keys.ShiftKey) { _shift = false; }
}

void UpdatePosition()
Expand All @@ -91,23 +117,5 @@ void TryUpdatePosition(Action<Vector2> updateAction)
_player.Position.Y = lastPosition.Y;
}
}

public override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up) { _up = true; }
if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left) { _left = true; }
if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down) { _down = true; }
if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right) { _right = true; }
if (e.KeyCode == Keys.ShiftKey) { _shift = true; }
}

public override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up) { _up = false; }
if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left) { _left = false; }
if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down) { _down = false; }
if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right) { _right = false; }
if (e.KeyCode == Keys.ShiftKey) { _shift = false; }
}
}
}
Loading

0 comments on commit 617af5f

Please sign in to comment.