AsciiArt fancyfication deluxe

Rough draft for Menu class
This commit is contained in:
Constantin Köpplinger 2023-03-30 23:41:58 +02:00
parent f5f846d995
commit b69776dfc3
3 changed files with 320 additions and 16 deletions

199
ConsoleSnake/AsciiArt.cs Normal file
View File

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleSnake
{
internal static class AsciiArt
{
public enum TextAlignment
{
Left,
Centered,
Right,
Top,
Bottom
}
private static (Int32 left, Int32 top) FindStartingPosition(Int32 numLines, Int32 numColumns, TextAlignment horizontalAlignment, TextAlignment verticalAlignment, int offsetLeft = 0, int offsetTop = 0)
{
Int32 left;
Int32 top;
switch(horizontalAlignment)
{
default:
case TextAlignment.Left:
left = 0;
break;
case TextAlignment.Centered:
left = Console.WindowWidth / 2 - numColumns / 2;
break;
case TextAlignment.Right:
left = Console.WindowWidth - numColumns;
break;
}
switch(verticalAlignment)
{
default:
case TextAlignment.Top:
top = 0;
break;
case TextAlignment.Centered:
top = Console.WindowHeight / 2 - numLines / 2;
break;
case TextAlignment.Bottom:
top = Console.WindowHeight - numLines;
break;
}
return (left + offsetLeft, top + offsetTop);
}
private static void DrawAt(ref string[] str, TextAlignment horizontalAlignment, TextAlignment verticalAlignment, ConsoleColor col = ConsoleColor.White, int offsetLeft = 0, int offsetTop = 0)
{
(Int32 left, Int32 top) startingPos = FindStartingPosition(str.Count(), str[0].Length, horizontalAlignment, verticalAlignment, offsetLeft, offsetTop);
Console.SetCursorPosition(startingPos.left, startingPos.top);
Console.ForegroundColor = col;
foreach(var item in str)
{
Console.WriteLine(item);
Console.CursorLeft = startingPos.left;
}
}
public static void IntroAnimation()
{
bool loopRunning = true;
(ConsoleColor col, Int32 sleepFor)[] animFrames =
{
(ConsoleColor.DarkGray, 150),
(ConsoleColor.Gray, 100),
(ConsoleColor.White, 170),
(ConsoleColor.Gray, 90),
(ConsoleColor.DarkGray, 190),
(ConsoleColor.White, 40),
(ConsoleColor.DarkGray, 100),
(ConsoleColor.Gray, 160),
(ConsoleColor.DarkGray, 100),
(ConsoleColor.DarkGray, 60),
(ConsoleColor.Gray, 100),
(ConsoleColor.DarkGray, 40),
};
while (loopRunning)
{
foreach ((ConsoleColor col, Int32 sleepFor) frame in animFrames)
{
CNake(TextAlignment.Centered, TextAlignment.Top, frame.col, offsetTop: 4);
Thread.Sleep(frame.sleepFor);
if (Console.KeyAvailable)
{
Console.ReadKey();
loopRunning = false;
}
}
}
Console.Clear();
}
public static void CNake(TextAlignment horizontalAlignment = TextAlignment.Centered, TextAlignment verticalAlignment = TextAlignment.Centered, ConsoleColor col = ConsoleColor.White, Int32 offsetLeft = 0, Int32 offsetTop = 0)
{
string[] lines =
{
@" _____ _____ ______ ____ ____ ____ ______ ",
@" ___|\ \|\ \ |\ \ ____|\ \ | | | | ___|\ \ ",
@" / /\ \ \ \| \ \ / /\ \ | | | | | \ \ ",
@"| | | |\| \ \ || | | || | / // | ,_____/|",
@"| | |____| | \ | || |__| || |/ _ _// | \--'\_|/",
@"| | ____ | \ | || .--. || |\ \' | /___/| ",
@"| | | | | |\ \| || | | || | \ \ | \____|\ ",
@"|\ ___\/ /| |____||\_____/||____| |____||____| \____\ |____ ' /|",
@"| | /____/ | | |/ \| ||| | | || | | || /_____/ |",
@" \|___| | / |____| |___|/|____| |____||____| |____||____| | /",
@" \( |____|/ \( )/ \( )/ \( )/ \( |_____|/ ",
@" ' )/ ' ' ' ' ' ' ' )/ ",
@" ' ' ",
@" ",
@" PRESS ANY KEY "
};
DrawAt(ref lines, horizontalAlignment, verticalAlignment, col, offsetLeft, offsetTop);
}
public static void GameOver(TextAlignment horizontalAlignment = TextAlignment.Centered, TextAlignment verticalAlignment = TextAlignment.Centered, ConsoleColor col = ConsoleColor.White, Int32 offsetLeft = 0, Int32 offsetTop = 0)
{
string[] lines =
{
@" ___ ___ ",
@" / __|__ _ _ __ ___ / _ \__ _____ _ _ ",
@" | (_ / _` | ' \/ -_) | (_) \ V / -_) '_|",
@" \___\__,_|_|_|_\___| \___/ \_/\___|_| ",
@" ",
@" ",
@" PRESS ANY KEY "
};
DrawAt(ref lines, horizontalAlignment, verticalAlignment, col, offsetLeft, offsetTop);
}
public static void Countdown(TextAlignment horizontalAlignment = TextAlignment.Centered, TextAlignment verticalAlignment = TextAlignment.Centered, ConsoleColor col = ConsoleColor.White, Int32 offsetLeft = 0, Int32 offsetTop = 0)
{
string[][] numbers =
{
new string[] {
@" ____",
@" |__ /",
@" |_ \",
@" |___/",
@" "
},
new string[]
{
@" ___ ",
@" |_ )",
@" / / ",
@" /___|",
@" "
},
new string[]
{
@" _ ",
@" / | ",
@" | | ",
@" |_| ",
@" "
}
};
foreach(string[] lines in numbers)
{
string[] curLines = lines;
DrawAt(ref curLines, horizontalAlignment, verticalAlignment, col, offsetLeft, offsetTop);
Thread.Sleep(1000);
}
string[] clearArea = new string[]
{
@" ",
@" ",
@" ",
@" ",
@" "
};
DrawAt(ref clearArea, horizontalAlignment, verticalAlignment, col, offsetLeft, offsetTop);
}
}
}

65
ConsoleSnake/Menu.cs Normal file
View File

@ -0,0 +1,65 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleSnake
{
internal class Menu
{
internal class MenuItem
{
//public delegate bool MenuAction(object? customData = null);
public delegate bool MenuAction();
public string Label { get; set; }
public string Description { get; set; }
public MenuAction Action { get; set; }
}
private Dictionary<string, MenuItem> _menuItems = new Dictionary<string, MenuItem>();
private string _selectedEntry = "";
public Menu() { }
public void Show()
{
Console.CursorTop = 10;
foreach (var item in _menuItems)
{
Console.CursorLeft = 30;
if (_selectedEntry == item.Key)
{
Console.BackgroundColor = ConsoleColor.Green;
}
else
{
Console.BackgroundColor = ConsoleColor.Black;
}
Console.WriteLine(item.Key);
}
while (true)
{
Thread.Sleep(1000);
break;
}
}
public void AddItem(string label, string description, MenuItem.MenuAction action, bool selected = false)
{
MenuItem menuItem = new MenuItem();
menuItem.Label = label;
menuItem.Description = description;
menuItem.Action = action;
if (_selectedEntry == null || selected)
_selectedEntry = label;
_menuItems.Add(label, menuItem);
}
public bool RemoveItem(string label) => _menuItems.Remove(label);
public void Clear() => _menuItems.Clear();
}
}

View File

@ -1,6 +1,4 @@
using System.ComponentModel.Design; namespace ConsoleSnake
namespace ConsoleSnake
{ {
internal class Program internal class Program
{ {
@ -48,8 +46,14 @@ namespace ConsoleSnake
} }
} }
const Int32 MINWIDTH = 82;
const Int32 MINHEIGHT = 35;
private static PlayArea _playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2); private static PlayArea _playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
private static bool _gameRunning = true;
private static bool _running = true; private static bool _running = true;
private static Snake[] _snakes = { private static Snake[] _snakes = {
new Snake(), new Snake(),
new Snake() new Snake()
@ -59,24 +63,49 @@ namespace ConsoleSnake
private static Int32 _desiredFrameTime = 75; private static Int32 _desiredFrameTime = 75;
private static DateTime _frameTiming = DateTime.Now; private static DateTime _frameTiming = DateTime.Now;
static void Setup()
{
Console.SetWindowSize(MINWIDTH, MINHEIGHT);
Console.SetBufferSize(Console.WindowWidth, Console.WindowHeight);
Console.CursorVisible = false;
}
static void Main(string[] args) static void Main(string[] args)
{ {
Console.ReadKey(); Console.ReadKey();
Setup();
AsciiArt.IntroAnimation();
MainLoop();
}
Console.SetBufferSize(Console.WindowWidth, Console.WindowHeight); private static void ShowMenu()
{
Menu menu = new Menu();
menu.AddItem("Play [1P]", "Play a single-player game.", () => { return false; });
menu.AddItem("Play [2P]", "Play a two-player game.", () => { return false; });
menu.AddItem("Quit", "Quit the game.", () => { return _gameRunning = false; });
menu.Show();
}
DrawPlayArea(); private static void MainLoop()
{
//Console.WindowWidth -= 1; //foreach (ConsoleColor col in Enum.GetValues(typeof(ConsoleColor)))
Console.ReadKey(true); //{
Reset(); // Console.ForegroundColor = col;
// Console.WriteLine(col);
//}
while (_running) while (_gameRunning)
{ {
TimeFrame(); ShowMenu();
HandleInput(); Reset();
AllSnakeThings(); DrawPlayArea();
AsciiArt.Countdown(col: ConsoleColor.Magenta);
while (_running)
{
TimeFrame();
HandleInput();
AllSnakeThings();
}
} }
} }
@ -113,6 +142,10 @@ namespace ConsoleSnake
} }
private static void Reset() private static void Reset()
{ {
Console.ForegroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Black;
Console.Clear();
_playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2); _playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
_running = true; _running = true;
@ -122,6 +155,8 @@ namespace ConsoleSnake
_snakes[1].Color = ConsoleColor.Cyan; _snakes[1].Color = ConsoleColor.Cyan;
_snakes[0].Segments.Clear(); _snakes[0].Segments.Clear();
_snakes[1].Segments.Clear(); _snakes[1].Segments.Clear();
_snakes[0].Alive = true;
_snakes[1].Alive = true;
// Set up anew // Set up anew
_snakes[0].Segments.Add(_snakes[0].HeadPosition = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2)); _snakes[0].Segments.Add(_snakes[0].HeadPosition = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2));
@ -196,13 +231,18 @@ namespace ConsoleSnake
{ {
if (snake.Alive) if (snake.Alive)
{ {
// is this snake running into the other snake or itself? // is this snake running into the other snake or itself? -> pepsi
if (SnakeCollision(snake.HeadPosition)) if (SnakeCollision(snake.HeadPosition))
{ {
KillSnake(snake); KillSnake(snake);
// everyone pepsi? game over?! // everyone pepsi? game over?!
if (!_snakes[0].Alive && !_snakes[1].Alive) if (!_snakes[0].Alive && !_snakes[1].Alive)
{
_running = false; _running = false;
AsciiArt.GameOver();
Console.ReadKey();
}
continue; continue;
} }