clean up and commentary

This commit is contained in:
Baipyrus 2022-10-21 08:21:38 +02:00
parent b60d8efc85
commit 4f7fb23724

View File

@ -26,29 +26,33 @@ namespace Tetris {
// Global Variables
private static int FPS = 60;
public static int frameCount = 0;
private static Color[,] board = new Color[10, 21];
private static readonly Color black = new(0, 0, 0);
private static bool canSwap = true, gameOver = false, startOver = true;
private static int score = 0, bounds = 0;
public static int selectionIndex = 0;
public static bool selection = false;
private static bool canSwap = true, gameOver, startOver = true, hasStarted;
private static Player player = new(), next = new(true);
public static int selectionIndex, frameCount;
private static int score, bounds;
public static bool selection;
// Matrix variables
private static RGBLedMatrix? _matrix = null;
private static RGBLedCanvas? _canvas = null;
private static RGBLedMatrix? _matrix;
private static RGBLedCanvas? _canvas;
// Method to initialize the Game
public static void Init(RGBLedMatrix matrix, RGBLedCanvas canvas) {
_matrix = matrix;
_canvas = canvas;
for (int i = 0; i < board.GetLength(0); i++)
for (int j = 0; j < board.GetLength(1); j++)
board[i, j] = black;
}
public static void Main() {
// Initialize board
if (!hasStarted) {
for (int i = 0; i < board.GetLength(0); i++)
for (int j = 0; j < board.GetLength(1); j++)
board[i, j] = black;
hasStarted = true;
}
// Initialize RGBLedMatrix
RGBLedMatrix matrix;
RGBLedCanvas canvas;
@ -72,16 +76,20 @@ namespace Tetris {
// Initialize stopwatch to measure calculation and display time
Stopwatch stopwatch = new();
// Initialize Console Color and Text-Font and -Color
RGBLedFont font = new("fonts/5x8.bdf");
Console.ForegroundColor = ConsoleColor.White;
Color col = new(255, 255, 255), grey = new(127, 127, 127);
// Outer loop for restarting the Game
startOver = true;
while (startOver) {
// Reset loop
Console.Clear();
canvas.Clear();
canvas = matrix.SwapOnVsync(canvas);
// Inner loop for actual Gameplay
gameOver = false;
while (!gameOver) {
// Start of Frame
@ -95,7 +103,7 @@ namespace Tetris {
break;
}
// Gameplay hahaha
// Display board onto Matrix
for (int i = 0; i < board.GetLength(0); i++)
for (int j = 0; j < board.GetLength(1); j++) {
Color current = board[i, j];
@ -105,19 +113,14 @@ namespace Tetris {
canvas.SetPixel(i * 3 + k, j * 3 + l, current);
}
// Display player onto Matrix
foreach (var current in player.positions) {
for (int k = 0; k < 3; k++)
for (int l = 0; l < 3; l++)
canvas.SetPixel((player.x + current[0]) * 3 + k, (player.y + current[1]) * 3 + l, player.color);
}
// Move Block down every few frames
if (frameCount % 30 == 0 && collisionCheck(player.x, ++player.y, player.positions)) {
player.y--;
placeBlock();
}
// Draw line
// Draw line "in the middle"
for (int i = 0; i < 64; i++)
canvas.SetPixel(30, i, grey);
@ -128,6 +131,7 @@ namespace Tetris {
for (int k = 0; k < 3; k++)
for (int l = 0; l < 3; l++)
canvas.SetPixel((14 + b[0]) * 3 + k, (4+ b[1]) * 3 + l, (Color)player.memCol);
// Statically display next item below the previous
canvas.DrawText(font, 38, 40, col, "Next:");
if (next.memDis != null)
@ -136,8 +140,13 @@ namespace Tetris {
for (int l = 0; l < 3; l++)
canvas.SetPixel((14 + b[0]) * 3 + k, (15+ b[1]) * 3 + l, (Color)next.color);
// Move Player down every few frames
if (frameCount % 30 == 0 && collisionCheck(player.x, ++player.y, player.positions)) {
player.y--;
placeBlock();
}
// End of Frame
// End of Frame
canvas = matrix.SwapOnVsync(canvas);
frameCount = (frameCount+1)%(FPS*4);
@ -147,14 +156,18 @@ namespace Tetris {
Thread.Sleep(1000/FPS - elapsed);
}
// If Player has lost but not yet quit
if (startOver) {
// Start loop to select next step in
frameCount = 0;
selection = true;
while (selection) {
// Display Options and Cursor on Matrix
canvas.Clear();
canvas.DrawText(font, 0, 8, col, "Game Over!");
canvas.DrawText(font, 0, 24, col, " ) Beenden");
canvas.DrawText(font, 0, 32, col, " ) Weiter");
canvas.DrawText(font, 0, 24, col, " ) Weiter");
canvas.DrawText(font, 0, 40, col, " ) Beenden");
// Cursor is a '#' at (0, 24 + i * 8) where i may be [0, 1]
canvas.DrawText(font, 0, 24+selectionIndex*8, col, "#");
canvas = matrix.SwapOnVsync(canvas);
@ -163,18 +176,22 @@ namespace Tetris {
frameCount = 0;
switch (Console.ReadKey(true).Key) {
case ConsoleKey.Escape:
// Exit Game
selection = false;
startOver = false;
break;
case ConsoleKey.DownArrow:
// Increment index
if (selectionIndex < 1)
selectionIndex++;
break;
case ConsoleKey.UpArrow:
// Decrement index
if (selectionIndex > 0)
selectionIndex--;
break;
case ConsoleKey.Enter:
// Enter selected option
enterSelection();
break;
}
@ -194,6 +211,7 @@ namespace Tetris {
}
}
// Method to check whether a block at given coordinates collides with any other block or border
private static bool collisionCheck(int x, int y, int[][] block) {
foreach (int[] b in block) {
int nx = x + b[0], ny = y + b[1];
@ -203,12 +221,13 @@ namespace Tetris {
return false;
}
// Method to place currently held block
private static void placeBlock() {
// Block placing
foreach (int[] current in player.positions)
board[player.x + current[0], player.y + current[1]] = player.color;
// Count rows lines
// Count completed rows
int rows = 0;
for (int j = board.GetLength(1)-1; j >= 0;) {
bool isRow = true;
@ -247,18 +266,21 @@ namespace Tetris {
break;
}
// Generate new player with given parameters
player = new(
blockIndex,
player.memPos,
player.memDis,
player.memCol
);
// Generate new "next Block" with displaySelf State
next = new(true);
// If new block doesnt collide with any other, keep playing (also re-enable swapping)
if (!collisionCheck(player.x, player.y, player.positions))
canSwap = true;
// Otherwise reset game, because player has lost
else {
// Reset Game
gameOver = true;
for (int i = 0; i < board.GetLength(0); i++)
for (int j = 0; j < board.GetLength(1); j++)
@ -310,6 +332,7 @@ namespace Tetris {
return false;
}
// Method to choose what a given index has to do
public static void enterSelection() {
switch (selectionIndex) {
case 0:
@ -323,6 +346,7 @@ namespace Tetris {
}
}
// Depending on currently used block, save its width and height (they're always the same)
public static void calcBounds() {
int blockIndex = 0;
for (int i = 1; i < blocks.Length; i++)
@ -343,8 +367,8 @@ namespace Tetris {
}
}
// Adjust x-positions if necessary due to any previous movement
public static void adjustXPos() {
// Adjust x-postions if necessary
foreach (int[] b in player.positions) {
int nx = player.x + b[0];
while (nx > 9) {
@ -358,12 +382,15 @@ namespace Tetris {
}
}
// Swap current block with the one in memory
public static void swapMemory() {
if (canSwap) {
// Save all data
int[][] tempPos = player.positions;
int[][]? tempMem = player.memPos;
Color tempCol1 = player.color;
Color? tempCol2 = player.memCol;
// Generate new Player and assign saved variables
player = new();
player.memPos = tempPos;
player.memCol = tempCol1;
@ -371,6 +398,7 @@ namespace Tetris {
player.positions = tempMem;
player.color = (Color)tempCol2;
}
// Actually clone the content of block in memory to be displayed without rotating later
player.memDis = new int[tempPos.Length][];
for (int i = 0; i < tempPos.Length; i++) {
player.memDis[i] = new int[tempPos[i].Length];
@ -381,6 +409,7 @@ namespace Tetris {
}
}
// Rotate current block Clockwise
public static void rotateClockwise() {
foreach (int[] a in player.positions) {
int temp = a[0];
@ -389,6 +418,7 @@ namespace Tetris {
}
}
// Rotate current block counter-Clockwise
public static void rotateCounterClockwise() {
foreach (int[] a in player.positions) {
int temp = a[1];
@ -397,32 +427,40 @@ namespace Tetris {
}
}
// Move current block to the right
public static void moveRightSide() {
if (collisionCheck(++player.x, player.y, player.positions))
player.x--;
}
// Move current block to the left
public static void moveLeftSide() {
if (collisionCheck(--player.x, player.y, player.positions))
player.x++;
}
// Move current block downwards
public static void moveDownOnce() {
if (collisionCheck(player.x, ++player.y, player.positions))
player.y--;
}
// Method to be called when the button for placing a block is pressed
public static void placeDownBlock() {
// Move block to the lowest possible point
while (!collisionCheck(player.x, ++player.y, player.positions)) { }
player.y--;
// Place the block
placeBlock();
}
// Method to end the Game
public static void EndGame() {
gameOver = true;
startOver = false;
}
// Data-Class to store a player's variables in
private class Player {
public int[][] positions;
public int[][]? memPos;
@ -431,6 +469,7 @@ namespace Tetris {
public Color color;
public int x, y;
// Constructor to generate new Player
public Player(bool displaySelf=false) {
int randInt = (new Random()).Next(7);
@ -464,6 +503,7 @@ namespace Tetris {
y = 0;
}
// Constructor to carry over variables
public Player(int blockIndex, int[][]? _memPos, int[][]? _memDis, Color? _memCol) {
memPos = _memPos;
memDis = _memDis;