Starfield
This commit is contained in:
parent
82445efda4
commit
eaf3dcea91
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -19,6 +19,7 @@ enum ModeId {
|
||||
PONG,
|
||||
SPACE_INVADERS,
|
||||
NEW_YEAR,
|
||||
STARFIELD,
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
|
||||
46
src/mode/Starfield/Starfield.h
Normal file
46
src/mode/Starfield/Starfield.h
Normal 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
|
||||
@ -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>)");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user