Starfield

This commit is contained in:
Patrick Haßel 2023-01-03 18:43:31 +01:00
parent 82445efda4
commit eaf3dcea91
8 changed files with 114 additions and 60 deletions

View File

@ -107,8 +107,8 @@ public:
return DISPLAY_CHAR_WIDTH;
}
void set(Vector *pos, Color color) {
set((uint8_t) round(pos->x), (uint8_t) round(pos->y), color);
void set(Vector pos, Color color) {
set((uint8_t) round(pos.x), (uint8_t) round(pos.y), color);
}
void set(uint8_t x, uint8_t y, Color color) {

View File

@ -11,63 +11,66 @@ public:
double y;
double length;
Vector() :
x(0.0), y(0.0) {
x(0.0), y(0.0), length(0.0) {
// nothing
}
Vector(double x, double y) :
x(x), y(y) {
x(x), y(y), length(sqrt(x * x + y * y)) {
// nothing
}
Vector(long degrees, double length) {
static Vector polar(long degrees, double length) {
double radians = (double) degrees * DEG_TO_RAD;
x = cos(radians) * length;
y = sin(radians) * length;
return {
cos(radians) * length,
sin(radians) * length,
};
}
Vector *set(Vector that) {
this->x = that.x;
this->y = that.y;
return this;
Vector plus(double _x, double _y) const {
return {x + _x, y + _y};
}
Vector *set(double _x, double _y) {
this->x = _x;
this->y = _y;
return this;
Vector plus(Vector vector) const {
return {x + vector.x, y + vector.y};
}
Vector *add(double _x, double _y) {
this->x += _x;
this->y += _y;
return this;
Vector minus(double _x, double _y) const {
return {x - _x, y - _y};
}
Vector *add(Vector that) {
this->x += that.x;
this->y += that.y;
return this;
Vector minus(Vector vector) const {
return {x - vector.x, y - vector.y};
}
Vector *bounceInBox(uint8_t width, uint8_t height) {
while (x < 0 || x >= width) {
if (x < 0) {
x = -x;
} else if (x >= width) {
x = 2 * width - x;
Vector multiply(double i) const {
return {x * i, y * i};
}
Vector bounceInBox(uint8_t width, uint8_t height) const {
double x2 = this->x;
double y2 = this->y;
while (x2 < 0 || x2 >= width) {
if (x2 < 0) {
x2 = -x2;
} else if (x2 >= width) {
x2 = 2 * width - x2;
}
}
while (y < 0 || y >= height) {
if (y < 0) {
y = -y;
} else if (y >= height) {
y = 2 * height - y;
while (y2 < 0 || y2 >= height) {
if (y2 < 0) {
y2 = -y2;
} else if (y2 >= height) {
y2 = 2 * height - y2;
}
}
return this;
return {x2, y2};
}
};
#endif

View File

@ -6,6 +6,7 @@
#include "mode/Pong/Pong.h"
#include "mode/SpaceInvaders/SpaceInvaders.h"
#include "mode/NewYear/NewYear.h"
#include "mode/Starfield/Starfield.h"
#include "display.h"
ModeId currentModeId = NONE;
@ -85,6 +86,9 @@ void loadNewMode() {
case NEW_YEAR:
mode = new NewYear(&display);
break;
case STARFIELD:
mode = new Starfield(&display);
break;
default:
Serial.print("No mode loaded.\n");
display.clear();

View File

@ -19,6 +19,7 @@ enum ModeId {
PONG,
SPACE_INVADERS,
NEW_YEAR,
STARFIELD,
};
template<typename T>

View File

@ -13,7 +13,7 @@ class Firework {
Display *display{};
Color color;
Color color = MAGENTA;
State state = RISE;
@ -37,7 +37,7 @@ public:
}
void reset() {
position.set((double) random(display->width), display->height);
position = Vector((double) random(display->width), display->height);
color = randomColor();
state = INITIAL;
@ -93,38 +93,37 @@ public:
}
void draw() {
Vector p;
switch (state) {
case INITIAL:
break;
case RISE:
display->set(&position, YELLOW);
display->set(position, YELLOW);
break;
case EXPLODE:
drawParticle(p, +0.0, +1.0);
drawParticle(p, +0.7, +0.7);
drawParticle(p, +1.0, +0.0);
drawParticle(p, +0.7, -0.7);
drawParticle(p, +0.0, -1.0);
drawParticle(p, -0.7, -0.7);
drawParticle(p, -1.0, +0.0);
drawParticle(p, -0.7, +0.7);
drawParticle(+0.0, +1.0);
drawParticle(+0.7, +0.7);
drawParticle(+1.0, +0.0);
drawParticle(+0.7, -0.7);
drawParticle(+0.0, -1.0);
drawParticle(-0.7, -0.7);
drawParticle(-1.0, +0.0);
drawParticle(-0.7, +0.7);
break;
case SPARKLE:
if (randomBool(2)) drawParticle(p, +0.0, +1.0);
if (randomBool(2)) drawParticle(p, +0.7, +0.7);
if (randomBool(2)) drawParticle(p, +1.0, +0.0);
if (randomBool(2)) drawParticle(p, +0.7, -0.7);
if (randomBool(2)) drawParticle(p, +0.0, -1.0);
if (randomBool(2)) drawParticle(p, -0.7, -0.7);
if (randomBool(2)) drawParticle(p, -1.0, +0.0);
if (randomBool(2)) drawParticle(p, -0.7, +0.7);
if (randomBool(2)) drawParticle(+0.0, +1.0);
if (randomBool(2)) drawParticle(+0.7, +0.7);
if (randomBool(2)) drawParticle(+1.0, +0.0);
if (randomBool(2)) drawParticle(+0.7, -0.7);
if (randomBool(2)) drawParticle(+0.0, -1.0);
if (randomBool(2)) drawParticle(-0.7, -0.7);
if (randomBool(2)) drawParticle(-1.0, +0.0);
if (randomBool(2)) drawParticle(-0.7, +0.7);
break;
}
}
void drawParticle(Vector &p, double x, double y) {
display->set(p.set(position)->add(x * explosion, y * explosion), color);
void drawParticle(double x, double y) {
display->set(position.plus(x * explosion, y * explosion), color);
}
bool isAlive() {

View File

@ -43,7 +43,7 @@ private:
}
break;
case PLAY:
position.add(velocity);
position = position.plus(velocity);
player0.randomMove(display->height);
player1.randomMove(display->height);
paddleBounce();
@ -63,7 +63,7 @@ private:
}
void topBottomBounce() {
position.bounceInBox(display->width, display->height);
position = position.bounceInBox(display->width, display->height);
}
void checkScoring() {
@ -132,7 +132,7 @@ public:
explicit Pong(Display *display) :
Mode(display),
position(display->width / 2.0, display->height / 2.0),
velocity(random(360), exp10(1)) {
velocity(Vector::polar(random(360), exp10(1))) {
instance = this;
createTimer(100, [](Timer *timer, uint32_t counter, uint32_t currentCount) { instance->tick(timer, counter, currentCount); });
spawnBall(random(2) == 0 ? -1 : +1);

View File

@ -0,0 +1,46 @@
#ifndef MEDIATABLE_STARFIELD_H
#define MEDIATABLE_STARFIELD_H
#include "mode/Mode.h"
#define STAR_COUNT 20
class Starfield : public Mode<Starfield> {
private:
Vector center;
Vector stars[STAR_COUNT];
public:
explicit Starfield(Display *display) :
Mode(display),
center(display->width / 2.0, display->height / 2.0) {
for (auto &star: stars) {
star.x = random(display->width);
star.y = random(display->height);
}
}
const char *getName() override {
return "Starfield";
}
void doStep(microseconds_t dt) override {
display->clear();
for (auto &star: stars) {
const Vector velocity = star.minus(center).multiply((double) dt / 200000.0);
star = star.plus(velocity);
if (star.x < 0 || star.x >= display->width || star.y < 0 || star.y >= display->height) {
star = center.plus(Vector::polar(random(360), 1));
}
uint8_t brightness = (uint8_t) round(255.0 * star.minus(center).length / (display->width / 2.0));
display->set(star, gray(brightness));
}
}
};
#endif

View File

@ -59,6 +59,7 @@ void web_index() {
server.sendContent(R"(<a href="/mode?mode=7">PONG</a><br>)");
server.sendContent(R"(<a href="/mode?mode=8">SPACE_INVADERS</a><br>)");
server.sendContent(R"(<a href="/mode?mode=9">NEW_YEAR</a><br>)");
server.sendContent(R"(<a href="/mode?mode=10">STARFIELD</a><br>)");
server.sendContent(R"(Helligkeit: <a href="/brighter">+</a> / <a href="/darker">-</a><br>)");
server.sendContent(R"(Geschwindigkeit: <a href="/faster">+</a> / <a href="/slower">-</a><br>)");