REFACTOR: removed Display members: cursorX, cursorY, foreground, background

This commit is contained in:
Patrick Haßel 2025-01-25 22:21:13 +01:00
parent 4efc101e56
commit 687e6cf70d
16 changed files with 116 additions and 148 deletions

View File

@ -13,3 +13,6 @@ Hardware:
Heatsink Heatsink
Extend Matrix (double?) Extend Matrix (double?)
Microphone Microphone
MQTT:
register globally, so the values are already there when switching mode

View File

@ -6,11 +6,6 @@
#define X true #define X true
#define _ false #define _ false
#define ____ 0
#define QUAR 64
#define HALF 128
#define FULL 255
typedef int64_t microseconds_t; typedef int64_t microseconds_t;
typedef unsigned long milliseconds_t; typedef unsigned long milliseconds_t;

View File

@ -117,8 +117,8 @@ inline void web_player(AsyncWebServerRequest *request) {
request->send(400, "text/plain", "Missing 'index'"); request->send(400, "text/plain", "Missing 'index'");
return; return;
} }
double value = request->getParam("index")->value().toDouble(); const auto value = request->getParam("index")->value().toDouble();
int index = (int) value; const auto index = static_cast<int>(value);
auto *response = request->beginResponseStream("text/html"); auto *response = request->beginResponseStream("text/html");
@ -161,6 +161,7 @@ inline void web_player(AsyncWebServerRequest *request) {
} }
inline void web_player_move(AsyncWebServerRequest *request) { inline void web_player_move(AsyncWebServerRequest *request) {
// ReSharper disable once CppJoinDeclarationAndAssignment
double value; double value;
if (!request->hasParam("index")) { if (!request->hasParam("index")) {
@ -168,21 +169,21 @@ inline void web_player_move(AsyncWebServerRequest *request) {
return; return;
} }
value = request->getParam("index")->value().toDouble(); value = request->getParam("index")->value().toDouble();
int index = (int) value; const auto index = static_cast<int>(value);
if (!request->hasParam("x")) { if (!request->hasParam("x")) {
request->send(400, "text/plain", "Missing 'x'"); request->send(400, "text/plain", "Missing 'x'");
return; return;
} }
value = request->getParam("x")->value().toDouble(); value = request->getParam("x")->value().toDouble();
int x = (int) value; const auto x = static_cast<int>(value);
if (!request->hasParam("y")) { if (!request->hasParam("y")) {
request->send(400, "text/plain", "Missing 'y'"); request->send(400, "text/plain", "Missing 'y'");
return; return;
} }
value = request->getParam("y")->value().toDouble(); value = request->getParam("y")->value().toDouble();
int y = (int) value; const auto y = static_cast<int>(value);
modeMove(index, x, y); modeMove(index, x, y);
@ -190,6 +191,7 @@ inline void web_player_move(AsyncWebServerRequest *request) {
} }
inline void web_player_fire(AsyncWebServerRequest *request) { inline void web_player_fire(AsyncWebServerRequest *request) {
// ReSharper disable once CppJoinDeclarationAndAssignment
double value; double value;
if (!request->hasParam("index")) { if (!request->hasParam("index")) {
@ -197,7 +199,7 @@ inline void web_player_fire(AsyncWebServerRequest *request) {
return; return;
} }
value = request->getParam("index")->value().toDouble(); value = request->getParam("index")->value().toDouble();
int index = (int) value; const auto index = static_cast<int>(value);
modeFire(index); modeFire(index);
@ -209,12 +211,12 @@ inline void web_setMode(AsyncWebServerRequest *request) {
request->send(400, "text/plain", "Missing 'mode'"); request->send(400, "text/plain", "Missing 'mode'");
return; return;
} }
double value = request->getParam("mode")->value().toDouble(); auto value = request->getParam("mode")->value().toDouble();
if (isnan(value)) { if (isnan(value)) {
request->send(400, "text/plain", "'mode' not a number"); request->send(400, "text/plain", "'mode' not a number");
return; return;
} }
setMode((ModeId) value); setMode(static_cast<ModeId>(value));
request->send(200); request->send(200);
} }
@ -278,8 +280,6 @@ public:
display.setup(); display.setup();
display.setBrightness(10); display.setBrightness(10);
display.clear(); display.clear();
display.foreground = Blue;
display.printf("Test");
} }
void loop() override { void loop() override {

View File

@ -7,49 +7,47 @@ class Vector {
public: public:
double x; double x;
double y; double y;
double length; double length;
Vector() : Vector() : x(0.0), y(0.0), length(0.0) {
x(0.0), y(0.0), length(0.0) { //
// nothing }
}
Vector(double x, double y) : Vector(const double x, const double y) : x(x), y(y), length(sqrt(x * x + y * y)) {
x(x), y(y), length(sqrt(x * x + y * y)) { //
// nothing }
}
static Vector polar(long degrees, double length) { static Vector polar(const long degrees, const double length) {
double radians = (double) degrees * DEG_TO_RAD; const auto radians = static_cast<double>(degrees) * DEG_TO_RAD;
return { return {
cos(radians) * length, cos(radians) * length,
sin(radians) * length, sin(radians) * length,
}; };
} }
Vector plus(double _x, double _y) const { Vector plus(const double _x, const double _y) const {
return {x + _x, y + _y}; return {x + _x, y + _y};
} }
Vector plus(Vector vector) const { Vector plus(const Vector vector) const {
return {x + vector.x, y + vector.y}; return {x + vector.x, y + vector.y};
} }
Vector minus(double _x, double _y) const { Vector minus(const double _x, const double _y) const {
return {x - _x, y - _y}; return {x - _x, y - _y};
} }
Vector minus(Vector vector) const { Vector minus(const Vector vector) const {
return {x - vector.x, y - vector.y}; return {x - vector.x, y - vector.y};
} }
Vector multiply(double i) const { Vector multiply(const double i) const {
return {x * i, y * i}; return {x * i, y * i};
} }
}; };

View File

@ -2,14 +2,14 @@
#include "mode/Border/Border.h" #include "mode/Border/Border.h"
#include "mode/Clock/Clock.h" #include "mode/Clock/Clock.h"
#include "mode/GameOfLife/GameOfLife.h"
#include "mode/Pong/Pong.h"
#include "mode/SpaceInvaders/SpaceInvaders.h"
#include "mode/CountDown/CountDown.h" #include "mode/CountDown/CountDown.h"
#include "mode/Starfield/Starfield.h"
#include "mode/Matrix/Matrix.h"
#include "mode/Power/Power.h"
#include "mode/Energy/Energy.h" #include "mode/Energy/Energy.h"
#include "mode/GameOfLife/GameOfLife.h"
#include "mode/Matrix/Matrix.h"
#include "mode/Pong/Pong.h"
#include "mode/Power/Power.h"
#include "mode/SpaceInvaders/SpaceInvaders.h"
#include "mode/Starfield/Starfield.h"
#include "mode/Timer/Timer.h" #include "mode/Timer/Timer.h"
Config config("/main.json"); Config config("/main.json");
@ -147,6 +147,7 @@ void loadNewMode(Display& display) {
} }
if (mode != nullptr) { if (mode != nullptr) {
info("Loaded mode: %s", mode->getName()); info("Loaded mode: %s", mode->getName());
mode->loadConfig();
mode->start(); mode->start();
} }
modeStepLastMicros = 0; modeStepLastMicros = 0;

View File

@ -19,10 +19,10 @@ protected:
void draw(Display& display) override { void draw(Display& display) override {
display.clear(); display.clear();
display.drawLineWH(0, 0, display.width, 0, 1); display.drawLine(0, 0, display.width, 0, 1, White);
display.drawLineWH(0, 0, 0, display.height, 1); display.drawLine(0, 0, 0, display.height, 1, White);
display.drawLineWH(display.width - 1, display.height - 1, -display.width, 0, 1); display.drawLine(display.width - 1, display.height - 1, -display.width, 0, 1, White);
display.drawLineWH(display.width - 1, display.height - 1, 0, -display.height, 1); display.drawLine(display.width - 1, display.height - 1, 0, -display.height, 1, White);
} }
}; };

View File

@ -27,9 +27,7 @@ protected:
void draw(Display& display) override { void draw(Display& display) override {
display.clear(); display.clear();
display.cursorX = 2; display.printf(2, 1, White, "%2d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec);
display.cursorY = 1;
display.printf(true, "%2d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec);
} }
}; };

View File

@ -3,12 +3,10 @@
#define MAX_FIREWORKS 6 #define MAX_FIREWORKS 6
#include <patrix/display/DisplayMatrix_FontSpecial.h>
#include "mode/Mode.h"
#include "CountDownFirework.h" #include "CountDownFirework.h"
#include "mode/Mode.h"
class CountDown : public Mode { class CountDown final : public Mode {
Firework fireworks[MAX_FIREWORKS]; Firework fireworks[MAX_FIREWORKS];
@ -45,7 +43,7 @@ public:
return "CountDown (Numbers)"; return "CountDown (Numbers)";
} }
void start() override { void loadConfig() override {
targetEpochSeconds = config.get("targetEpochSeconds", 1767222000); targetEpochSeconds = config.get("targetEpochSeconds", 1767222000);
} }
@ -74,11 +72,6 @@ protected:
hours = static_cast<int>(floor(diffSeconds / (60 * 60))) % 24; hours = static_cast<int>(floor(diffSeconds / (60 * 60))) % 24;
minutes = static_cast<int>(floor(diffSeconds / 60)) % 60; minutes = static_cast<int>(floor(diffSeconds / 60)) % 60;
seconds = static_cast<int>(diffSeconds) % 60; seconds = static_cast<int>(diffSeconds) % 60;
// Serial.printf("now=%4d.%02d.%02d (%ld), conf=%4d.%02d.%02d (%ld), diff=%f, %dd %2d:%02d:%02d\n",
// now.tm_year, now.tm_mon, now.tm_mday, nowEpochSeconds,
// target.tm_year, target.tm_mon, target.tm_mday, targetEpochSeconds,
// diffSeconds,
// days, hours, minutes, seconds);
setMode(COUNTDOWN); setMode(COUNTDOWN);
if (days == 0) { if (days == 0) {
loopLastDay(); loopLastDay();
@ -148,7 +141,7 @@ private:
void drawSleepingCount(Display& display) const { void drawSleepingCount(Display& display) const {
const auto sleepCount = days + 1; const auto sleepCount = days + 1;
display.printf(true, "%3d TAG%s", sleepCount, sleepCount == 1 ? "" : "E"); display.printf(1, 1, White, "%3d %s", sleepCount, sleepCount == 1 ? "TAG" : "TAGE");
} }
void drawCountdownBars(Display& display) const { void drawCountdownBars(Display& display) const {
@ -157,6 +150,19 @@ private:
drawBar(display, 5, 30, 2, 60, seconds, Green, Yellow, 5); drawBar(display, 5, 30, 2, 60, seconds, Green, Yellow, 5);
} }
void drawCountdownNumbers(Display& display) const {
if (days >= 10) {
display.printf(1, 1, White, "%3d TAGE", days);
drawSecondsBar(display, seconds);
} else if (days > 0) {
display.printf(1, 1, White, "%d %2d:%02d", days, hours, minutes);
drawSecondsBar(display, seconds);
} else {
display.printf(1, 1, White, "%d:%02d:%02d", hours, minutes, seconds);
drawSubSecondsBar(display);
}
}
static void drawBar(Display& display, const uint8_t _y, const uint8_t _w, const uint8_t _h, const uint8_t max, const uint8_t value, const RGBA& color, const RGBA& tickColor, const uint8_t ticks) { static void drawBar(Display& display, const uint8_t _y, const uint8_t _w, const uint8_t _h, const uint8_t max, const uint8_t value, const RGBA& color, const RGBA& tickColor, const uint8_t ticks) {
const auto totalOnCount = static_cast<uint8_t>(round(static_cast<double>(value) / max * _w * _h)); const auto totalOnCount = static_cast<uint8_t>(round(static_cast<double>(value) / max * _w * _h));
uint8_t doneOnCount = 0; uint8_t doneOnCount = 0;
@ -177,18 +183,8 @@ private:
} }
} }
void drawCountdownNumbers(Display& display) const {
if (days > 0) {
display.printf(true, "%02d. %2d:%02d", days, hours, minutes);
drawSecondsBar(display, seconds);
} else {
display.printf(true, "%2d:%02d:%02d", hours, minutes, seconds);
drawSubSecondsBar(display);
}
}
static void drawNoTime(Display& display) { static void drawNoTime(Display& display) {
display.print("--:--:--"); display.print(1, 1, Red, "--:--:--");
} }
static void drawSecondsBar(Display& display, const int seconds) { static void drawSecondsBar(Display& display, const int seconds) {
@ -211,11 +207,9 @@ private:
void drawYear(Display& display, const int year) const { void drawYear(Display& display, const int year) const {
if (plus1DayForSleepingCount) { if (plus1DayForSleepingCount) {
display.printf(true, "Emil 5"); display.printf(1, 1, White, "EMIL 5");
display.cursorX = 32 - 8;
display.cursorY = 0;
} else { } else {
display.printf(true, "%5d", year); display.printf(1, 1, White, "%5d", year);
} }
} }

View File

@ -89,7 +89,7 @@ public:
case INITIAL: case INITIAL:
break; break;
case RISE: case RISE:
display.setPixel(static_cast<int>(position.x), static_cast<int>(position.y), Yellow.factor(DARKER_FACTOR)); display.setPixel(position.x, position.y, Yellow.factor(DARKER_FACTOR));
break; break;
case EXPLODE: case EXPLODE:
drawParticle(display, +0.0, +1.0); drawParticle(display, +0.0, +1.0);
@ -132,7 +132,7 @@ private:
void drawParticle(Display& display, const double x, const double y) const { void drawParticle(Display& display, const double x, const double y) const {
const auto p = position.plus(x * explosion, y * explosion); const auto p = position.plus(x * explosion, y * explosion);
display.setPixel(static_cast<int>(p.x), static_cast<int>(p.y), color.factor(DARKER_FACTOR)); display.setPixel(p.x, p.y, color.factor(DARKER_FACTOR));
} }
}; };

View File

@ -72,23 +72,15 @@ protected:
const auto amortisationPercent = selfConsumedKWh / PV_COST_AMORTISATION_KWH * 100; const auto amortisationPercent = selfConsumedKWh / PV_COST_AMORTISATION_KWH * 100;
display.clear(); display.clear();
display.cursorX = 0;
display.cursorY = 1;
if (page == 0) { if (page == 0) {
display.foreground = Green; display.printf(0, 1, Green, "%3.0f€", costSaved);
display.printf(true, "%3.0f€", costSaved); display.printf(16, 1, White, "%3.0f%%", amortisationPercent);
display.foreground = White;
display.printf(true, " %3.0f%%", amortisationPercent);
} else if (page == 1) { } else if (page == 1) {
display.foreground = Blue; display.printf(0, 1, Blue, "%3.0f", photovoltaicEnergyKWh);
display.printf(true, "%3.0f", photovoltaicEnergyKWh); display.printf(16, 1, Green, "%3.0f", selfConsumedKWh);
display.foreground = Green;
display.printf(true, " %3.0f", selfConsumedKWh);
} else { } else {
display.foreground = Yellow; display.printf(0, 1, Orange, "%4.0f", gridImportKWh);
display.printf(true, "%4.0f", gridImportKWh); display.printf(16, 1, Magenta, "%3.0f", gridExportKWh);
display.foreground = Magenta;
display.printf(true, " %3.0f", gridExportKWh);
} }
} }

View File

@ -49,10 +49,10 @@ protected:
display.clear(); display.clear();
for (const auto& glyph: glyphs) { for (const auto& glyph: glyphs) {
for (auto i = 0; i < glyph.length; ++i) { for (auto i = 0; i < glyph.length; ++i) {
display.setPixel(static_cast<int>(round(glyph.x)), static_cast<int>(round(glyph.y - i)), {64, 128, 64}); display.setPixel(glyph.x, glyph.y - i, {64, 128, 64});
} }
if ((static_cast<int>(round(glyph.y)) + glyph.length) % 2 == 0) { if ((static_cast<int>(round(glyph.y)) + glyph.length) % 2 == 0) {
display.setPixel(static_cast<int>(round(glyph.x)), static_cast<int>(round(glyph.y)), {0, 255, 0}); display.setPixel(glyph.x, glyph.y, {0, 255, 0});
} }
} }
} }

View File

@ -144,14 +144,14 @@ private:
void realtimeMillisecondsUpdate() { void realtimeMillisecondsUpdate() {
if (lastSecond < 0 || lastSecond != now.tm_sec) { if (lastSecond < 0 || lastSecond != now.tm_sec) {
lastSecond = (int8_t) now.tm_sec; lastSecond = static_cast<int8_t>(now.tm_sec);
lastSecondChange_Milliseconds = millis(); lastSecondChange_Milliseconds = millis();
} }
realtimeMilliseconds = millis() - lastSecondChange_Milliseconds; realtimeMilliseconds = millis() - lastSecondChange_Milliseconds;
} }
void handleTimers(const microseconds_t microseconds) { void handleTimers(const microseconds_t microseconds) {
for (Timer *timer = timers; timer < timers + countof(timers); timer++) { for (auto timer = timers; timer < timers + countof(timers); timer++) {
if (timer->interval > 0) { if (timer->interval > 0) {
if (microseconds >= timer->rest) { if (microseconds >= timer->rest) {
timer->rest = timer->interval; timer->rest = timer->interval;

View File

@ -94,11 +94,8 @@ protected:
display.clear(); display.clear();
switch (status) { switch (status) {
case SCORE: case SCORE:
display.foreground = Green; display.printf(1, 1, Green, "%d", player0.score);
display.printf(true, "%d", player0.score); display.printf(28, 1, Red, "%d", player1.score);
display.foreground = Red;
display.printf(true, "%5d", player1.score);
break; break;
case PLAY: case PLAY:
for (auto i = 0; i < player0.size; ++i) { for (auto i = 0; i < player0.size; ++i) {
@ -111,17 +108,11 @@ protected:
break; break;
case OVER: case OVER:
if (player0.score > player1.score) { if (player0.score > player1.score) {
display.foreground = Green; display.printf(1, 1, Green, "W", player0.score);
display.printf(true, "W", player0.score); display.printf(28, 1, Red, "L", player1.score);
display.foreground = Red;
display.printf(true, " L", player1.score);
} else if (player0.score < player1.score) { } else if (player0.score < player1.score) {
display.foreground = Red; display.printf(1, 1, Red, "L", player0.score);
display.printf(true, "L", player0.score); display.printf(26, 1, Green, "W", player1.score);
display.foreground = Green;
display.printf(true, " W", player1.score);
} }
break; break;
} }
@ -155,11 +146,11 @@ private:
void checkScoring() { void checkScoring() {
if (ball.x < 0) { if (ball.x < 0) {
player1.score++; player1.score++;
Serial.println("Player 1 scored"); Serial.printf("Player 1 scored: %d\n", player1.score);
spawnBall(+1); spawnBall(+1);
} else if (ball.x >= width) { } else if (ball.x >= width) {
player0.score++; player0.score++;
Serial.println("Player 0 scored"); Serial.printf("Player 0 scored: %d\n", player0.score);
spawnBall(-1); spawnBall(-1);
} }
if (player0.score >= 10 || player1.score >= 10) { if (player0.score >= 10 || player1.score >= 10) {
@ -171,7 +162,6 @@ private:
void paddleBounce() { void paddleBounce() {
const auto paddleHitPosition0 = ball.y - player0.y; const auto paddleHitPosition0 = ball.y - player0.y;
if (ball.x >= 1 && ball.x < 2 && paddleHitPosition0 >= 0 && paddleHitPosition0 < player0.size) { if (ball.x >= 1 && ball.x < 2 && paddleHitPosition0 >= 0 && paddleHitPosition0 < player0.size) {
Serial.printf("Player 0 hit: paddleHitPosition0=%.2f\n", paddleHitPosition0);
velocity.x = -velocity.x; velocity.x = -velocity.x;
velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition0 - 1)); velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition0 - 1));
ball.x = 3; ball.x = 3;
@ -179,7 +169,6 @@ private:
} }
const auto paddleHitPosition1 = ball.y - player1.y; const auto paddleHitPosition1 = ball.y - player1.y;
if (ball.x >= width - 2 && ball.x < width - 1 && paddleHitPosition1 >= 0 && paddleHitPosition1 < player1.size) { if (ball.x >= width - 2 && ball.x < width - 1 && paddleHitPosition1 >= 0 && paddleHitPosition1 < player1.size) {
Serial.printf("Player 1 hit: paddleHitPosition1=%.2f\n", paddleHitPosition1);
velocity.x = -velocity.x; velocity.x = -velocity.x;
velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition1 - 1)); velocity.y = max(-2.0, min(+2.0, velocity.y + paddleHitPosition1 - 1));
ball.x = width - 4; ball.x = width - 4;

View File

@ -58,11 +58,11 @@ protected:
void draw(Display& display) override { void draw(Display& display) override {
display.clear(); display.clear();
display.foreground = photovoltaicPowerW >= 100 ? Green : photovoltaicPowerW >= 20 ? Yellow : Red; const auto pvColor = photovoltaicPowerW >= 100 ? Green : photovoltaicPowerW >= 20 ? Yellow : Red;
display.printf(true, "%3.0f", photovoltaicPowerW); display.printf(0, 1, pvColor, "%3.0f", photovoltaicPowerW);
display.foreground = gridPowerW >= 20 ? Yellow : gridPowerW >= -20 ? Green : Magenta; const auto gridColor = gridPowerW >= 20 ? Orange : gridPowerW >= -20 ? Green : Magenta;
display.printf(true, " %4.0f", gridPowerW); display.printf(16, 1, gridColor, "%4.0f", gridPowerW);
} }
}; };

View File

@ -60,13 +60,13 @@ public:
~SpaceInvaders() override { ~SpaceInvaders() override {
free(swarmBegin); free(swarmBegin);
free(rocketsBegin); free(rocketsBegin);
}; }
const char *getName() override { const char *getName() override {
return "Space Invaders"; return "Space Invaders";
} }
void move(int index, int x, int y) override { void move(int index, const int x, int y) override {
randomEnabled = false; randomEnabled = false;
heroX = max(1, min(width - 2, heroX + x)); heroX = max(1, min(width - 2, heroX + x));
} }
@ -78,7 +78,7 @@ public:
protected: protected:
void step(microseconds_t microseconds) override { void step(const microseconds_t microseconds) override {
stepRockets(microseconds); stepRockets(microseconds);
stepInvaders(microseconds); stepInvaders(microseconds);
if (randomEnabled) { if (randomEnabled) {
@ -109,7 +109,7 @@ protected:
private: private:
void stepRockets(microseconds_t microseconds) { void stepRockets(const microseconds_t microseconds) {
rocketRuntime += microseconds; rocketRuntime += microseconds;
if (rocketRuntime > 200000) { if (rocketRuntime > 200000) {
rocketRuntime = rocketRuntime % 200000; rocketRuntime = rocketRuntime % 200000;
@ -131,7 +131,7 @@ private:
} }
} }
void stepInvaders(microseconds_t microseconds) { void stepInvaders(const microseconds_t microseconds) {
swarmRuntime += microseconds; swarmRuntime += microseconds;
if (swarmDown && swarmRuntime > 500000) { if (swarmDown && swarmRuntime > 500000) {
@ -158,7 +158,7 @@ private:
} }
} }
void randomStepHero(microseconds_t microseconds) { void randomStepHero(const microseconds_t microseconds) {
heroRuntime += microseconds; heroRuntime += microseconds;
if (heroRuntime >= 50000) { if (heroRuntime >= 50000) {
heroRuntime = heroRuntime % 50000; heroRuntime = heroRuntime % 50000;
@ -182,7 +182,7 @@ private:
} }
} }
void shoot() { void shoot() const {
for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) { for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) {
if (!rocket->alive && rocket->flash == 0) { if (!rocket->alive && rocket->flash == 0) {
rocket->alive = true; rocket->alive = true;
@ -218,7 +218,7 @@ private:
&& swarmX + invader->x * 3 + 1 >= rocket->x; && swarmX + invader->x * 3 + 1 >= rocket->x;
} }
void drawInvaders(Display& display) { void drawInvaders(Display& display) const {
for (auto invader = swarmBegin; invader < swarmEnd; invader++) { for (auto invader = swarmBegin; invader < swarmEnd; invader++) {
if (invader->alive) { if (invader->alive) {
display.setPixel(swarmX + invader->x * 3 + 0, swarmY + invader->y * 2, Red); display.setPixel(swarmX + invader->x * 3 + 0, swarmY + invader->y * 2, Red);
@ -227,7 +227,7 @@ private:
} }
} }
void drawRockets(Display& display) { void drawRockets(Display& display) const {
for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) { for (auto rocket = rocketsBegin; rocket < rocketsEnd; rocket++) {
if (rocket->alive) { if (rocket->alive) {
display.setPixel(rocket->x, rocket->y, Yellow); display.setPixel(rocket->x, rocket->y, Yellow);
@ -241,7 +241,7 @@ private:
} }
} }
void drawHero(Display& display) { void drawHero(Display& display) const {
display.setPixel(heroX - 1, height - 1, Blue); display.setPixel(heroX - 1, height - 1, Blue);
display.setPixel(heroX + 0, height - 1, Blue); display.setPixel(heroX + 0, height - 1, Blue);
display.setPixel(heroX + 1, height - 1, Blue); display.setPixel(heroX + 1, height - 1, Blue);

View File

@ -66,18 +66,16 @@ protected:
void draw(Display& display) override { void draw(Display& display) override {
display.clear(); display.clear();
display.cursorX = 1; if (days > 10) {
display.cursorY = 1; display.printf(1, 1, White, "%3d TAGE", days);
if (days > 1) {
display.printf(true, "%4d TAGE", days);
} else if (days > 0) { } else if (days > 0) {
display.printf(true, "%2d. %02d:%02d", days, hours, minutes); display.printf(1, 1, White, "%d %2d:%02d", days, hours, minutes);
} else if (hours > 0) { } else if (hours > 0) {
display.printf(true, "%2d:%02d:%02d", hours, minutes, seconds); display.printf(1, 1, White, "%2d:%02d:%02d", hours, minutes, seconds);
} else if (minutes > 0) { } else if (minutes > 0) {
display.printf(true, "%2d:%02d", minutes, seconds); display.printf(1, 1, White, "%2d:%02d", minutes, seconds);
} else { } else {
display.printf(true, "%2d", seconds); display.printf(1, 1, Orange, "%2d", seconds);
} }
} }