game over

This commit is contained in:
Wolfgang Hottgenroth 2024-03-22 11:59:28 +01:00
parent 5b1dfde819
commit 611c56b329
3 changed files with 92 additions and 34 deletions

View File

@ -83,6 +83,13 @@ void canvasWipeRow(uint8_t row) {
memset(canvas.canvas, 0x80, canvas.width); memset(canvas.canvas, 0x80, canvas.width);
} }
void canvasFillRow(uint8_t row, uint8_t color) {
for (uint8_t c = 0; c < canvas.width; c++) {
canvasSetPixel(c, row, color);
}
}
uint8_t canvasIsRowFilled(uint8_t row) { uint8_t canvasIsRowFilled(uint8_t row) {
uint8_t res = 1; uint8_t res = 1;
for (uint8_t column = 0; column < canvas.width; column++) { for (uint8_t column = 0; column < canvas.width; column++) {

View File

@ -24,6 +24,7 @@ void canvasSetPixel(uint8_t column, uint8_t row, uint8_t color);
void miniCanvasSetPixel(uint8_t column, uint8_t row, uint8_t color); void miniCanvasSetPixel(uint8_t column, uint8_t row, uint8_t color);
uint8_t canvasIsPixelFree(uint8_t column, uint8_t row); uint8_t canvasIsPixelFree(uint8_t column, uint8_t row);
void canvasWipeRow(uint8_t row); void canvasWipeRow(uint8_t row);
void canvasFillRow(uint8_t row, uint8_t color);
uint8_t canvasIsRowFilled(uint8_t row); uint8_t canvasIsRowFilled(uint8_t row);
#endif // _CANVAS_H_ #endif // _CANVAS_H_

View File

@ -5,69 +5,119 @@
#include "scheduler.h" #include "scheduler.h"
#include "shapes.h" #include "shapes.h"
#include "canvas.h" #include "canvas.h"
#include "../rgb-driver/colors.h"
typedef enum { e_idle, e_start, e_newStone, e_down, e_gameOver, e_delay } state_t; #define GAME_CYCLE_TIME 100
#define GAMEOVER_DELAY 10
static uint8_t delayFactor(uint8_t level) {
return 11 - level;
}
typedef enum {
e_Phase_Game, e_Phase_GameOver
} phase_t;
typedef enum {
e_Start, e_NewStone, e_Down, e_DownDelay, e_ClearRows,
e_GameOver, e_GameOverFill, e_GameOverWipe, e_GameOverDelay
} state_t;
void gameExec(void *handle) { void gameExec(void *handle) {
static state_t state = e_start; static phase_t phase;
static uint8_t delay; static state_t state = e_Start;
static uint8_t gameOverDelay;
static uint8_t rowIndex;
static uint8_t proceedDelay;
static uint8_t level;
// --- engine begin -------------------------------------------------------
switch (state) { switch (state) {
case e_idle: // --- game ---------------------------------------------------------------
break; case e_Start:
case e_start:
canvasClear(); canvasClear();
state = e_newStone; level = 1;
phase = e_Phase_Game;
state = e_NewStone;
break; break;
case e_newStone: case e_NewStone:
stoneCreate(); stoneCreate();
if (stoneDraw()) { if (stoneDraw()) {
state = e_down; proceedDelay = delayFactor(level);
state = e_DownDelay;
} else { } else {
state = e_gameOver; state = e_GameOver;
} }
break; break;
case e_DownDelay:
proceedDelay--;
if (proceedDelay == 0) {
rowIndex = 0;
state = e_ClearRows;
}
break;
case e_ClearRows:
state = e_Down;
break;
case e_down: case e_Down:
if (! stoneMoveDown()) { if (! stoneMoveDown()) {
state = e_newStone; state = e_NewStone;
} else {
proceedDelay = delayFactor(level);
state = e_DownDelay;
} }
break; break;
case e_gameOver: // --- game over ----------------------------------------------------------
for (uint8_t c = 0; c < CANVAS_WIDTH; c++) { case e_GameOver:
canvasSetPixel(c, 0, 0x0d); rowIndex = CANVAS_HEIGHT;
canvasSetPixel(c, CANVAS_HEIGHT - 1, 0x0d); phase = e_Phase_GameOver;
} state = e_GameOverFill;
for (uint8_t r = 0; r < CANVAS_HEIGHT; r++) {
canvasSetPixel(0, r, 0x0d);
canvasSetPixel(CANVAS_WIDTH - 1, r, 0x0d);
}
delay = 10;
state = e_delay;
break; break;
case e_delay: case e_GameOverFill:
delay--; rowIndex--;
if (delay == 0) { canvasFillRow(rowIndex, _red);
state = e_start; if (rowIndex == 0) {
state = e_GameOverWipe;
}
break;
case e_GameOverWipe:
canvasWipeRow(rowIndex);
rowIndex++;
if (rowIndex == CANVAS_HEIGHT) {
gameOverDelay = GAMEOVER_DELAY;
state = e_GameOverDelay;
}
break;
case e_GameOverDelay:
gameOverDelay--;
if (gameOverDelay == 0) {
state = e_Start;
} }
break; break;
} }
// --- engine end ---------------------------------------------------------
canvasShow(); canvasShow();
for (uint8_t r = 0; r < CANVAS_HEIGHT; r++) { if (phase == e_Phase_Game) {
if (canvasIsRowFilled(r)) { for (uint8_t r = 0; r < CANVAS_HEIGHT; r++) {
canvasWipeRow(r); if (canvasIsRowFilled(r)) {
canvasShow(); canvasWipeRow(r);
canvasShow();
}
} }
} }
} }
void gameInit() { void gameInit() {
schAdd(gameExec, NULL, 0, 1000); schAdd(gameExec, NULL, 0, GAME_CYCLE_TIME);
} }