Огляд базового консольного рушія та гри написаної на ньому
Загальний опис бібліотеки ConsoleGameEngine
ConsoleGameEngine - опис та використання.
Бібліотека ConsoleGameEngine керує основними аспектами створення простих ігор у консольному середовищі. Вона надає інструменти для відображення елементів гри в консольному вікні, керування введенням користувача та оновленням стану гри.
Основні функції ConsoleGameEngine:
Відображення елементів гри: Бібліотека дозволяє відображати символи, кольори та текстові дані на екрані консолі.
Керування введенням користувача: Це включає моніторинг клавіатурного вводу та обробку команд користувача для взаємодії з грою.
Оновлення стану гри:
ConsoleGameEngineзабезпечує механізми для оновлення стану та позиції гравців, обробки подій та керування ходом гри.
Загальні завдання та сценарії використання:
Створення простих ігор: Бібліотека дозволяє створювати консольні ігри з базовим функціоналом, таким як рух об'єктів, відображення ігрових об'єктів, та реакція на користувацький ввід.
Керування елементами гри: Розробники можуть використовувати цю бібліотеку для створення та керування елементами гри, такими як збір балів, керування гравцями та малювання ігрового поля.
Взаємодія з користувачем: Вона дозволяє створювати ігри, які реагують на дії користувача, надаючи можливість взаємодії з грою через клавіатуру.
ConsoleGameEngine виступає як інструмент для створення простих консольних ігор, надаючи розробнику зручні та прості інструменти для реалізації логіки гри та відображення її елементів на екрані консолі.
Консольний ігровий рушій (ConsoleGameEngine) складається з кількох файлів, кожен з яких відповідає за певний елемент ігрового середовища:
ConsoleGameEngine.csproj: Це файл проєкту, який містить конфігураційні дані проєкту, зокрема залежності та налаштування компіляції.
ConsolePainter.cs: Цей файл містить клас
ConsolePainter, який відповідає за відображення графічних елементів на екрані консолі, таких як символи, кольори та текстові дані.GameBoard.cs: В цьому файлі знаходиться клас
GameBoard, який відповідає за ігрове поле або дошку, на якій розміщуються ігрові об'єкти.GameObject.cs: Цей файл містить опис класу
GameObject, який репрезентує окремий об'єкт у грі. Це може бути гравець, ворог, або будь-який інший елемент.UserInputManager.cs: В цьому файлі знаходиться клас
UserInputManager, який відповідає за управління введенням користувача та обробку команд, отриманих від користувача під час гри.
Кожен з цих файлів має своє призначення у створенні ігрового середовища: від відображення елементів на екрані до керування введенням користувача та управління об'єктами у грі. Разом вони створюють базову інфраструктуру для розробки консольних ігор за допомогою ConsoleGameEngine.
Файли та проєкт бібліотеки ConsoleGameEngine
ConsoleGameEngine - source code.
ConsoleGameEngine.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>disabled</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>Цей файл, який має розширення .csproj, є файлом проєкту для проєктів, що використовують платформу Microsoft.NET.Sdk. Основні частини цього файлу:
<Project Sdk="Microsoft.NET.Sdk">: Визначає використану SDK для проєкту. У цьому випадку, проєкт використовує SDK від Microsoft.NET.<PropertyGroup>: Ця секція містить рядок властивостей проєкту:<TargetFramework>net8.0</TargetFramework>: Вказує на цільову версію .NET Framework, для якої розробляється проєкт. У цьому випадку, ціль - .NET 8.0, що означає використання функціональності та бібліотек, доступних у версії .NET 8.0.<ImplicitUsings>disabled</ImplicitUsings>: Ця властивість вказує, чи включені неявні простори імен (implicit usings). У випадкуdisabled, неявні простори імен відключені.<Nullable>enable</Nullable>: Ця властивість вказує на використання системи nullable reference types. У цьому випадку, nullable reference types увімкнені для проєкту.
Цей файл .csproj визначає конфігурацію проєкту, таку як версію .NET Framework, налаштування компіляції та інші параметри, необхідні для збирання та виконання проєкту.
ConsolePainter.cs:
using System;
using System.Collections.Generic;
public class ConsolePainter
{
public ConsoleColor[] DrawColors;
public ConsoleColor BorderColor = ConsoleColor.White;
public ConsoleColor TextColor = ConsoleColor.White;
public List<string[]> TextDataToDraw = new List<string[]>();
public char[] DrawChars;
private byte LastColorId = 255;
private void DrawTextData(int startX, int startY)
{
Console.ForegroundColor = TextColor;
for (int i = 0; i < TextDataToDraw.Count; i++)
{
string textToDraw = $"[{TextDataToDraw[i][0]}] is [{TextDataToDraw[i][1]}]";
Console.SetCursorPosition(startX, startY + i);
Console.Write(new string(' ', textToDraw.Length + 5));
Console.SetCursorPosition(startX, startY + i);
Console.Write(textToDraw);
}
Console.ForegroundColor = DrawColors[LastColorId];
}
private void DrawBordersForMatrix(byte[,] matrix)
{
int height = matrix.GetLength(0);
int width = matrix.GetLength(1);
Console.ForegroundColor = BorderColor;
Console.SetCursorPosition(0, 0);
Console.Write('┌');
Console.SetCursorPosition(0, height + 1);
Console.Write('└');
Console.SetCursorPosition(width + 1, 0);
Console.Write('┐');
Console.SetCursorPosition(width + 1, height + 1);
Console.Write('┘');
for (int i = 1; i < height + 1; i++)
{
Console.SetCursorPosition(0, i);
Console.Write('│');
Console.SetCursorPosition(width + 1, i);
Console.Write('│');
}
for (int i = 1; i < width + 1; i++)
{
Console.SetCursorPosition(i, 0);
Console.Write('─');
Console.SetCursorPosition(i, height + 1);
Console.Write('─');
}
Console.ForegroundColor = DrawColors[LastColorId];
}
private void DrawByteMatrixToConsoleCore(byte[,] matrix, int startX, int startY)
{
int height = matrix.GetLength(0);
int width = matrix.GetLength(1);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
byte matrixElemId = matrix[y, x];
if (matrixElemId != LastColorId)
{
LastColorId = matrixElemId;
Console.ForegroundColor = DrawColors[matrixElemId];
}
Console.SetCursorPosition(x + startX, y + startY);
Console.Write(DrawChars[matrixElemId]);
}
}
if (TextDataToDraw.Count > 0)
{
DrawTextData(0, height + startY + 1);
}
}
public void DrawByteMatrixToConsole(byte[,] matrix)
{
DrawByteMatrixToConsoleCore(matrix, 0, 0);
}
public void DrawByteMatrixToConsole(byte[,] matrix, bool drawBorders)
{
if (drawBorders)
{
DrawByteMatrixToConsoleCore(matrix, 1, 1);
DrawBordersForMatrix(matrix);
}
else
{
DrawByteMatrixToConsole(matrix);
}
}
public ConsolePainter(ConsoleColor[] drawColors, char[] drawChars)
{
SetConsoleDefault();
DrawColors = drawColors;
DrawChars = drawChars;
}
public ConsolePainter()
{
SetConsoleDefault();
DrawColors = GetDefaultDrawColors();
DrawChars = GetDefaultDrawChars();
}
private static ConsoleColor[] GetDefaultDrawColors()
{
ConsoleColor[] result = new ConsoleColor[256]; //from 0 to 255
FillArrayWithValue(result, ConsoleColor.Red);
result[0] = ConsoleColor.White;
result[1] = ConsoleColor.DarkBlue;
result[2] = ConsoleColor.DarkGreen;
result[3] = ConsoleColor.DarkCyan;
result[4] = ConsoleColor.DarkMagenta;
result[5] = ConsoleColor.DarkRed;
result[6] = ConsoleColor.DarkYellow;
result[7] = ConsoleColor.Blue;
result[8] = ConsoleColor.Green;
result[9] = ConsoleColor.Cyan;
result[10] = ConsoleColor.Magenta;
result[11] = ConsoleColor.Red;
result[12] = ConsoleColor.Yellow;
result[13] = ConsoleColor.White;
result[14] = ConsoleColor.Gray;
result[15] = ConsoleColor.DarkGray;
result[16] = ConsoleColor.Black;
result[17] = ConsoleColor.DarkBlue;
result[18] = ConsoleColor.DarkGreen;
result[19] = ConsoleColor.DarkCyan;
result[20] = ConsoleColor.DarkMagenta;
result[21] = ConsoleColor.DarkRed;
result[22] = ConsoleColor.DarkYellow;
result[23] = ConsoleColor.Blue;
result[24] = ConsoleColor.Green;
result[25] = ConsoleColor.Cyan;
return result;
}
private static char[] GetDefaultDrawChars()
{
char[] result = new char[256]; //from 0 to 255
FillArrayWithValue(result, '█');
result[0] = '?';
result[1] = '█';
result[2] = '▓';
result[3] = '▒';
result[4] = '░';
result[5] = 'X';
result[6] = '@';
result[7] = '#';
result[8] = '$';
result[9] = '%';
result[10] = '&';
result[11] = '*';
result[12] = '+';
result[13] = '-';
result[14] = '=';
result[15] = '.';
result[16] = '/';
result[17] = '0';
result[18] = '1';
result[19] = '2';
result[20] = '3';
result[21] = '4';
result[22] = '5';
result[23] = '6';
result[24] = '7';
result[25] = '8';
return result;
}
private static void FillArrayWithValue<T>(T[] arr, T fillerValue) where T : struct
{
for (int i = 0; i < arr.Length; i++)
{
arr[i] = fillerValue;
}
}
private static void SetConsoleDefault()
{
Console.Clear();
Console.CursorVisible = false;
}
public void EndDrawing()
{
Console.CursorVisible = true;
}
}Цей файл містить клас ConsolePainter, який відповідає за відображення графічних елементів на екрані консолі для створення графічного інтерфейсу гри. Основні функції цього класу:
Кольори та символи: Клас зберігає масиви кольорів (
DrawColors) та символів (DrawChars), які використовуються для малювання елементів гри на консолі.Відображення тексту: Метод
DrawTextDataвідповідає за вивід текстових даних на екран консолі, розміщуючи їх у відповідному місці.Малювання границь: Функція
DrawBordersForMatrixстворює рамки навколо матриці, яка використовується для відображення елементів гри.Малювання матриці: Метод
DrawByteMatrixToConsoleвідповідає за відображення байтової матриці на екрані консолі. Це основний метод для відображення графічних об'єктів гри.Налаштування за замовчуванням: Конструктори класу
ConsolePainterініціалізують значення за замовчуванням для кольорів та символів, які використовуються для малювання елементів гри.Завершення малювання: Метод
EndDrawingвстановлює видимість курсора на консолі, викликаючи його завершення малювання.
Цей клас використовується для керування візуальною частиною гри у консольному середовищі, дозволяючи відображати та оновлювати елементи гри на екрані консолі.
GameBoard.cs:
// Клас, що репрезентує ігрову дошку
public class GameBoard
{
public int Width { get; set; } // Ширина ігрової дошки
public int Height { get; set; } // Висота ігрової дошки
public byte[,] Matrix { get; set; } // Матриця для зберігання значень на дошці
// Метод для встановлення прямокутника з певним значенням на дошці
public void SetReactangle(int x, int y, int width, int height, byte value)
{
for (int iY = y; iY < y + height; iY++)
{
for (int iX = x; iX < x + width; iX++)
{
Matrix[iY, iX] = value; // Встановлення значення у відповідних координатах матриці
}
}
}
// Метод для очищення матриці (заповнення нулями)
public void ClearMatrix()
{
FillArray<byte>(Matrix, 0); // Заповнення матриці нулями
}
// Конструктор, що ініціалізує ігрову дошку з вказаною шириною та висотою
public GameBoard(int width, int height)
{
Width = width;
Height = height;
Matrix = new byte[Height, Width]; // Створення матриці заданого розміру
}
// Статичний метод для заповнення двовимірного масиву певним значенням
public static void FillArray<T>(T[,] array, T value)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = value; // Заповнення масиву певним значенням
}
}
}
}Цей клас GameBoard репрезентує ігрову дошку у грі. Основні його характеристики та функції:
Ширина та висота: Властивості
WidthтаHeightвизначають розміри ігрової дошки.Матриця для зберігання значень:
Matrix- двовимірний масив типуbyte, що використовується для зберігання значень на самій дошці.Встановлення прямокутника на дошці: Метод
SetRectangleдозволяє встановити певне значення у вказаному прямокутнику на дошці, заданим його початковою точкою(x, y)та розмірами(width, height).Очищення матриці: Метод
ClearMatrixзаповнює всю матрицю нулями, ефективно очищаючи її.Ініціалізація ігрової дошки: Конструктор
GameBoardстворює об'єкт ігрової дошки заданого розміру, ініціалізуючи матрицю відповідним чином.Статичний метод для заповнення масиву значеннями: Метод
FillArrayвикористовується для заповнення будь-якого двовимірного масиву певним значенням.
Цей клас є фундаментальним елементом гри, оскільки він визначає простір, у якому розміщуються та взаємодіють ігрові об'єкти, і надає функціонал для їх розміщення та очищення на ігровій дошці.
GameObject.cs:
// Клас, який репрезентує ігровий об'єкт
public class GameObject
{
public int X { get; set; } = 0; // Позиція по осі X
public int Y { get; set; } = 0; // Позиція по осі Y
// Віртуальний метод, що перевіряє колізію з іншим об'єктом
public virtual bool IsCollidingWith(GameObject gameObject)
{
bool result = gameObject.X == X && gameObject.Y == Y; // Перевірка на співпадіння позицій
return result;
}
// Конструктор без параметрів, встановлює початкові значення позиції
public GameObject()
{
X = 0;
Y = 0;
}
// Конструктор з параметрами, встановлює позицію за заданими координатами
public GameObject(int x, int y)
{
X = x;
Y = y;
}
}Цей клас GameObject репрезентує основні властивості та функціонал для будь-якого ігрового об'єкта в грі:
Позиція об'єкта: Клас має властивості
XтаY, які визначають позицію об'єкта на ігровому полі по відповідним координатам X та Y.Перевірка на колізію: Метод
IsCollidingWithє віртуальним і дозволяє перевірити, чи стикається поточний об'єкт з іншим об'єктом. Він порівнює координати двох об'єктів, щоб визначити, чи знаходяться вони на одній позиції.Конструктори: Клас має два конструктори: один без параметрів, який встановлює початкові значення позиції об'єкта (0, 0), та інший з параметрами, який дозволяє встановити позицію об'єкта за заданими координатами при створенні нового об'єкта.
Цей клас є базовим для будь-якого ігрового об'єкта у грі. Він визначає основні атрибути та функції, які можна розширювати для створення різноманітних типів об'єктів у грі.
UserInputManager.cs:
using System;
using System.Collections.Generic;
using System.Threading;
public class UserInputManager
{
private bool RunMonitorAndCleanerThread { get; set; } = false; // Прапорець для керування роботою потоків
private Thread MonitorThread { get; set; } // Потік для моніторингу введення
private Thread CleanerThread { get; set; } // Потік для очищення даних
public List<ConsoleKeyAndTime> PressedKeys = new List<ConsoleKeyAndTime>(); // Список натиснутих клавіш
// Метод, який перевіряє, чи натиснута певна клавіша за символьним значенням
public bool IsKeyPressed(char key)
{
return IsKeyPressed(key);
}
// Метод, який перевіряє, чи натиснута певна клавіша за рядковим значенням
public bool IsKeyPressed(string key)
{
bool result = false;
// Перебір усіх натиснутих клавіш для перевірки співпадіння з введеним значенням
for (int i = 0; i < PressedKeys.Count; i++)
{
if (PressedKeys[i].ConsoleKey.ToString() == key)
{
PressedKeys.RemoveAt(i); // Видалення клавіші зі списку
result = true;
break;
}
}
return result;
}
// Метод для початку моніторингу натиснутих клавіш
public void StartMonitoring()
{
RunMonitorAndCleanerThread = true;
MonitorThread.Start(); // Запуск потоку моніторингу
CleanerThread.Start(); // Запуск потоку очищення
}
// Метод для зупинки моніторингу натиснутих клавіш
public void StopMonitoring()
{
RunMonitorAndCleanerThread = false;
}
// Функція потоку моніторингу
public void MonitorThreadFunction()
{
while (RunMonitorAndCleanerThread)
{
ConsoleKey input = Console.ReadKey(true).Key; // Отримання натиснутої клавіші
long timeNow = DateTime.Now.Ticks; // Отримання поточного часу
bool alreadyInBuffer = false;
int inBufferId = 0;
// Перевірка наявності клавіші в буфері натиснутих клавіш
for (int i = 0; i < PressedKeys.Count; i++)
{
if (!alreadyInBuffer && input == PressedKeys[i].ConsoleKey)
{
alreadyInBuffer = true;
inBufferId = i;
}
}
// Оновлення часу натискання клавіші або додавання нової клавіші в буфер
if (alreadyInBuffer)
{
PressedKeys[inBufferId].PressTime = timeNow;
}
else
{
PressedKeys.Add(new ConsoleKeyAndTime(input, timeNow));
}
}
Console.WriteLine("Кінець функції потоку моніторингу");
}
// Функція потоку очищення
public void CleanerThreadFunction()
{
while (RunMonitorAndCleanerThread)
{
Thread.Sleep(10); // Пауза для ефективного використання ресурсів
long timeNow = DateTime.Now.Ticks; // Отримання поточного часу
// Перевірка часу натискання клавіш для їхнього видалення зі списку
for (int i = 0; i < PressedKeys.Count; i++)
{
if (PressedKeys[i].PressTime + 5000000 < timeNow)
{
PressedKeys.RemoveAt(i); // Видалення клавіші зі списку
}
}
}
Console.WriteLine("Кінець функції потоку очищення");
}
// Конструктор класу
public UserInputManager()
{
MonitorThread = new Thread(() => MonitorThreadFunction()); // Ініціалізація потоку моніторингу
CleanerThread = new Thread(() => CleanerThreadFunction()); // Ініціалізація потоку очищення
}
}
// Клас, що репрезентує натиснуту клавішу і час натискання
public class ConsoleKeyAndTime
{
public ConsoleKey ConsoleKey { get; set; } // Клавіша консолі
public long PressTime { get; set; } // Час натискання клавіші
// Конструктор класу
public ConsoleKeyAndTime(ConsoleKey consoleKey, long pressTime)
{
ConsoleKey = consoleKey;
PressTime = pressTime;
}
}Цей файл містить клас UserInputManager, який відповідає за отримання введення користувача з консолі у формі клавішних натискань. Основні функції цього класу:
Моніторинг клавішних натискань: Метод
MonitorThreadFunctionзапускає потік, який безперервно чекає на натискання клавіш користувачем. Коли клавіша натиснута, вона додається до спискуPressedKeysразом з часом натискання.Очищення клавішних натискань: Метод
CleanerThreadFunctionтакож працює у власному потоці, видаляючи клавіші, які зберігаються у спискуPressedKeysпісля певного періоду часу.Початок та завершення моніторингу: Методи
StartMonitoringтаStopMonitoringвідповідають відповідно за запуск та зупинку потоків моніторингу натискань.Перевірка натискання клавіш: Методи
IsKeyPressed(char key)таIsKeyPressed(string key)дозволяють перевіряти, чи була натиснута певна клавіша за символьним або рядковим значенням.Конструктор та клас
ConsoleKeyAndTime: КонструкторUserInputManagerініціалізує потоки моніторингу та очищення. КласConsoleKeyAndTimeвикористовується для репрезентації натиснутої клавіші та часу її натискання.
Цей клас дозволяє відстежувати та обробляти клавішні натискання користувача у консольному додатку, використовуючи окремі потоки для моніторингу та очищення введення.
Огляд гри написаної з використання ConsoleGameEngine - Загальний огляд файлів
Файли ConsoleGameExample - опис, структура, логіка.
ConsoleGameExample.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\ConsoleGameEngine\ConsoleGameEngine.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>disabled</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>Цей файл ConsoleGameExample.csproj є проєктним файлом у форматі XML, який визначає конфігурацію проєкту для платформи .NET SDK. Основні елементи цього файлу:
<Project Sdk="Microsoft.NET.Sdk">: Вказує, що цей проєкт базується на SDK для платформи .NET.<ItemGroup>з<ProjectReference>: Визначає посилання на інший проєкт у рішенні. У даному випадку, цей проєкт має посилання наConsoleGameEngine.csproj, що означає залежність від цього проєкту.<PropertyGroup>з конфігурацією проєкту: Встановлює ряд властивостей проєкту:OutputTypeвказує тип вихідного файлу проєкту (Exe - виконуваний файл).TargetFrameworkвизначає версію .NET Framework, для якої буде збудований проєкт (net8.0).ImplicitUsingsвизначає використання неявних директив імпорту для імен просторів імен (в даному випадку вимкнено).Nullableвстановлює ступінь включення можливості використання null-анотацій.
Цей файл містить важливу інформацію для побудови та налаштування проєкту, зокрема вказує на залежності від інших проєктів і налаштовує параметри збірки проєкту.
Public.cs:
using System;
using System.Collections.Generic;
// Статичний клас P, що містить глобальні змінні та об'єкти для гри
public static class P
{
public static int LoopCounterBlocks = 0; // Лічильник для логіки блоків у циклі
public static bool GameIsRunning = true; // Змінна, що вказує, чи триває гра
public static int Score = 0; // Змінна для збереження рахунку гравця
public static ConsolePainter Painter = new ConsolePainter(); // Об'єкт для відображення в консолі
public static UserInputManager UserInputManager = new UserInputManager(); // Об'єкт для управління вводом користувача
public static GameBoard GameBoard = new GameBoard(90, 30); // Ігрова дошка з визначеними розмірами
public static GamePlayer GamePlayer = new GamePlayer(0, 0); // Об'єкт гравця з визначеними координатами
public static int TargetGamePointsCount = 20; // Бажана(максимальна) кількість балів які можуть одночасно існувати на ігровому полі
public static List<GamePoint> GamePoints = new List<GamePoint>(); // Список балів які може збирати гравець
}Файл Public.cs управляє глобальними об'єктами та змінними, що використовуються в проєкті, який використовує ConsoleGameEngine. Основні елементи файлу:
Керування грою:
P.GameIsRunningвказує, чи триває гра. Ця змінна дозволяє визначити, чи продовжувати головний цикл гри.Відображення в консолі:
P.Painterвідповідає за відображення елементів гри в консолі. Цей об'єкт здійснює різні операції, такі як малювання символів, текстових даних та рамок.Управління введенням користувача:
P.UserInputManagerслідкує за введенням користувача через консоль. Це дозволяє гравцю взаємодіяти з грою через клавіатуру.Ігрова дошка та гравець:
P.GameBoardпредставляє ігрову дошку з визначеними розмірами.P.GamePlayerвідображає гравця на цій дошці.Рахунок та бали:
P.Scoreзберігає поточний рахунок гравця.P.TargetGamePointsCountвказує максимальну кількість балів, які можуть одночасно існувати на ігровому полі.
Цей файл створює статичний клас P, який містить різні об'єкти та змінні, необхідні для функціонування гри, підключеної до ConsoleGameEngine.
Program.cs:
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleGameExample
{
class Program
{
static void Main(string[] args)
{
// Початок моніторингу введення користувача
P.UserInputManager.StartMonitoring();
// Ініціалізація символів для малювання та встановлення кольорів
P.Painter.DrawChars[0] = ' ';
P.Painter.DrawChars[1] = '%';
P.Painter.DrawChars[2] = '+';
P.Painter.DrawColors[1] = ConsoleColor.Green;
P.Painter.DrawColors[2] = ConsoleColor.Red;
// Встановлення кольору рамки
P.Painter.BorderColor = ConsoleColor.Yellow;
// Додавання текстових даних для малювання
P.Painter.TextDataToDraw.Add(new string[] { "X", "test_val" });
P.Painter.TextDataToDraw.Add(new string[] { "Y", "test_val" });
P.Painter.TextDataToDraw.Add(new string[] { "Score", "0" });
// Встановлення початкових координат персонажа
P.GamePlayer.X = P.GameBoard.Width / 4;
P.GamePlayer.Y = P.GameBoard.Height / 2;
// Головний цикл гри
MainLoop();
// Зупинка моніторингу введення користувача та завершення малювання
P.UserInputManager.StopMonitoring();
P.Painter.EndDrawing();
}
public static void MainLoop()
{
while (P.GameIsRunning)
{
Thread.Sleep(50);
P.GameBoard.ClearMatrix();
// Обробка балів
GamePointsInLoop();
// Оновлення положення персонажа
GamePlayerInLoop();
P.Painter.TextDataToDraw[2][1] = P.Score.ToString();
// Малювання матриці у консоль
P.Painter.DrawByteMatrixToConsole(P.GameBoard.Matrix, true);
}
}
private static void GamePointsInLoop()
{
// Додавання випадкових геймпоінтів, поки не досягнуто потрібну кількість
if (P.GamePoints.Count < P.TargetGamePointsCount)
{
P.GamePoints.Add(GamePoint.GetNewRandomPoint(P.GameBoard));
}
// Перевірка колізій геймпоінтів з гравцем та їх видалення у разі зіткнення
// А також відображення геймпоінтів на ігровій дошці
for (int i = 0; i < P.GamePoints.Count; i++)
{
if (P.GamePoints[i].IsCollidingWith(P.GamePlayer))
{
P.GamePoints.RemoveAt(i);
P.Score++;
}
else
{
P.GameBoard.Matrix[P.GamePoints[i].Y, P.GamePoints[i].X] = 2;
}
}
}
private static void GamePlayerInLoop()
{
// Керування персонажем та оновлення його положення
P.GamePlayer.Control(P.UserInputManager, P.GameBoard);
P.GamePlayer.OneTick();
// Оновлення текстових даних про положення персонажа та його місцезнаходження на ігровій дошці
P.Painter.TextDataToDraw[0][1] = Convert.ToString(P.GamePlayer.X);
P.Painter.TextDataToDraw[1][1] = Convert.ToString(P.GamePlayer.Y);
P.GameBoard.Matrix[P.GamePlayer.Y, P.GamePlayer.X] = 1;
}
}
}Цей файл Program.cs керує основним ходом програми, яка використовує бібліотеку ConsoleGameEngine. Основні елементи файлу:
Mainметод: Це вхідна точка програми. Він починає моніторинг введення користувача, ініціалізує символи для малювання, встановлює кольори та додає текстові дані для малювання в консоль. Також встановлюються початкові координати персонажа і запускається головний цикл гри.MainLoopметод: Це головний цикл гри. Він продовжується, доки гра продовжується (P.GameIsRunning). У цьому циклі очищується ігрова дошка, обробляються геймпоінти та оновлюється положення персонажа, а потім матриця малюється у консоль.Методи обробки геймпоінтів та персонажа:
GamePointsInLoopвідповідає за додавання випадкових геймпоінтів та їх взаємодію з гравцем.GamePlayerInLoopвідповідає за керування персонажем та оновлення його положення на ігровій дошці.
Цей файл забезпечує основну логіку гри, яка використовує ConsoleGameEngine, включаючи обробку введення користувача, оновлення гри та відображення її елементів у консольному інтерфейсі.
GamePoint.cs:
using System;
public class GamePoint : GameObject
{
public static Random Random = new Random(); // Об'єкт для генерації випадкових чисел
// Статичний метод, який повертає нову випадкову точку на ігровій дошці
public static GamePoint GetNewRandomPoint(GameBoard GameBoard)
{
int x = 0;
int y = 0;
// Генеруємо випадкові координати для точки в межах ширини та висоти ігрової дошки
x = Random.Next(0, GameBoard.Width);
y = Random.Next(0, GameBoard.Height);
return new GamePoint(x, y); // Повертаємо новий об'єкт GamePoint з випадковими координатами
}
// Конструктор класу GamePoint, що приймає координати X та Y для створення нової точки
public GamePoint(int X, int Y) : base(X, Y){}
}Файл GamePoint.cs містить клас GamePoint, що представляє точку на ігровій дошці. Основні елементи файлу:
Успадкування від
GameObject:GamePointуспадковує функціонал від класуGameObject, який містить базові властивості об'єктів у грі.Створення нової випадкової точки: Метод
GetNewRandomPointстворює новий об'єктGamePointз випадковими координатами на ігровій дошці. Використовується об'єктRandom, щоб генерувати координати всередині меж ширини та висоти ігрової дошки.Конструктор класу
GamePoint: Приймає координати X та Y для створення нової точки на ігровій дошці.
Цей файл надає методи для створення нових випадкових точок на ігровій дошці, що дозволяє динамічно розміщувати об'єкти у грі.
GamePlayer.cs:
using System;
public class GamePlayer : GameObject
{
public int TickCounter = 0; // Лічильник тиків
public GamePlayer() : base(){} // Конструктор за замовчуванням
public GamePlayer(int x, int y) : base(x, y){} // Конструктор з параметрами
public virtual void Control(UserInputManager userInputManager, GameBoard gameBoard)
{
if (Y < gameBoard.Height - 1 && userInputManager.IsKeyPressed("S"))
{
Y++; // Зміщення вниз
}
if (Y > 0 && userInputManager.IsKeyPressed("W"))
{
Y--; // Зміщення вгору
}
if (X < gameBoard.Width - 1 && userInputManager.IsKeyPressed("D"))
{
X++; // Зміщення вправо
}
if (X > 0 && userInputManager.IsKeyPressed("A"))
{
X--; // Зміщення вліво
}
}
public virtual void OneTick(){
TickCounter++; // Інкрементування лічильник тиків
if (TickCounter >= 1000)
{
TickCounter = 0; // Обнулити лічильник при досягненні межі
}
}
}Файл GamePlayer.cs визначає клас GamePlayer, який представляє гравця в грі. Основні аспекти цього класу:
Координати та лічильник тиків:
GamePlayerмає поляXтаY, що представляють його координати на ігровій дошці.TickCounterвідстежує кількість тиків або кроків гравця.Конструктори: Є два конструктори: один за замовчуванням та інший із визначенням початкових координат гравця.
Методи управління:
Controlприймає об'єктиUserInputManagerтаGameBoardдля обробки введення гравця та керування його рухом в межах ігрового поля. Гравець може рухатися вгору, вниз, вліво та вправо в залежності від введених клавіш.Один тик:
OneTickвикликається кожен тик гри та інкрементуєTickCounter. При досягненніTickCounterзначення 1000, лічильник обнуляється.
Клас GamePlayer відображає гравця на ігровому полі та реагує на введення користувача, виконуючи відповідні дії в межах ігрового середовища.
Огляд гри написаної з використання ConsoleGameEngine - Загальний огляд її логіки
Логіка ConsoleGameExample - опис, структура.
Код Program.cs відповідає за виконання основного циклу гри та містить наступні етапи:
Початок гри:
P.UserInputManager.StartMonitoring();Починається моніторинг введення користувача за допомогою
UserInputManager.Ініціалізація візуальних елементів:
P.Painter.DrawChars[0] = ' '; P.Painter.DrawChars[1] = '%'; P.Painter.DrawChars[2] = '+'; P.Painter.DrawColors[1] = ConsoleColor.Green; P.Painter.DrawColors[2] = ConsoleColor.Red; P.Painter.BorderColor = ConsoleColor.Yellow; P.Painter.TextDataToDraw.Add(new string[] { "X", "test_val" }); P.Painter.TextDataToDraw.Add(new string[] { "Y", "test_val" }); P.Painter.TextDataToDraw.Add(new string[] { "Score", "0" });Здійснюється ініціалізація параметрів для малювання в консолі через об'єкт
ConsolePainter.Ініціалізація гравця:
P.GamePlayer.X = P.GameBoard.Width / 4; P.GamePlayer.Y = P.GameBoard.Height / 2;Встановлюються початкові координати гравця на ігровій дошці.
Головний цикл гри (
MainLoop):while (P.GameIsRunning) { Thread.Sleep(50); P.GameBoard.ClearMatrix(); GamePointsInLoop(); GamePlayerInLoop(); P.Painter.TextDataToDraw[2][1] = P.Score.ToString(); P.Painter.DrawByteMatrixToConsole(P.GameBoard.Matrix, true); }Головний ігровий цикл, який працює, поки
P.GameIsRunningзалишаєтьсяtrue.Обробка геймпоінтів (
GamePointsInLoop):if (P.GamePoints.Count < P.TargetGamePointsCount) { P.GamePoints.Add(GamePoint.GetNewRandomPoint(P.GameBoard)); } for (int i = 0; i < P.GamePoints.Count; i++) { if (P.GamePoints[i].IsCollidingWith(P.GamePlayer)) { P.GamePoints.RemoveAt(i); P.Score++; } else { P.GameBoard.Matrix[P.GamePoints[i].Y, P.GamePoints[i].X] = 2; } }Додаються нові геймпоінти на ігрову дошку, перевіряється колізія геймпоінтів з гравцем, та оновлюється рахунок.
Оновлення гравця (
GamePlayerInLoop):P.GamePlayer.Control(P.UserInputManager, P.GameBoard); P.GamePlayer.OneTick(); P.Painter.TextDataToDraw[0][1] = Convert.ToString(P.GamePlayer.X); P.Painter.TextDataToDraw[1][1] = Convert.ToString(P.GamePlayer.Y); P.GameBoard.Matrix[P.GamePlayer.Y, P.GamePlayer.X] = 1;Гравець керується за допомогою клавіш, оновлюється його положення та відображення на ігровій дошці.
Малювання гри в консолі:
P.Painter.DrawByteMatrixToConsole(P.GameBoard.Matrix, true);Матриця ігрової дошки відображається в консолі через метод
DrawByteMatrixToConsole.Зупинка гри:
P.UserInputManager.StopMonitoring(); P.Painter.EndDrawing();Зупиняється моніторинг введення користувача та завершується малювання в консолі.
build info
- compiler
- 2.0.5.1 · 4054EF9BF6C4510A
- built
- 2026-11-08 14:31:25 UTC
WebUniverse