Starfield
This commit is contained in:
parent
82445efda4
commit
eaf3dcea91
@ -107,8 +107,8 @@ public:
|
|||||||
return DISPLAY_CHAR_WIDTH;
|
return DISPLAY_CHAR_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(Vector *pos, Color color) {
|
void set(Vector pos, Color color) {
|
||||||
set((uint8_t) round(pos->x), (uint8_t) round(pos->y), color);
|
set((uint8_t) round(pos.x), (uint8_t) round(pos.y), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(uint8_t x, uint8_t y, Color color) {
|
void set(uint8_t x, uint8_t y, Color color) {
|
||||||
|
|||||||
@ -11,63 +11,66 @@ public:
|
|||||||
|
|
||||||
double y;
|
double y;
|
||||||
|
|
||||||
|
double length;
|
||||||
|
|
||||||
Vector() :
|
Vector() :
|
||||||
x(0.0), y(0.0) {
|
x(0.0), y(0.0), length(0.0) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(double x, double y) :
|
Vector(double x, double y) :
|
||||||
x(x), y(y) {
|
x(x), y(y), length(sqrt(x * x + y * y)) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(long degrees, double length) {
|
static Vector polar(long degrees, double length) {
|
||||||
double radians = (double) degrees * DEG_TO_RAD;
|
double radians = (double) degrees * DEG_TO_RAD;
|
||||||
x = cos(radians) * length;
|
return {
|
||||||
y = sin(radians) * length;
|
cos(radians) * length,
|
||||||
|
sin(radians) * length,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *set(Vector that) {
|
Vector plus(double _x, double _y) const {
|
||||||
this->x = that.x;
|
return {x + _x, y + _y};
|
||||||
this->y = that.y;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *set(double _x, double _y) {
|
Vector plus(Vector vector) const {
|
||||||
this->x = _x;
|
return {x + vector.x, y + vector.y};
|
||||||
this->y = _y;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *add(double _x, double _y) {
|
Vector minus(double _x, double _y) const {
|
||||||
this->x += _x;
|
return {x - _x, y - _y};
|
||||||
this->y += _y;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *add(Vector that) {
|
Vector minus(Vector vector) const {
|
||||||
this->x += that.x;
|
return {x - vector.x, y - vector.y};
|
||||||
this->y += that.y;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *bounceInBox(uint8_t width, uint8_t height) {
|
Vector multiply(double i) const {
|
||||||
while (x < 0 || x >= width) {
|
return {x * i, y * i};
|
||||||
if (x < 0) {
|
}
|
||||||
x = -x;
|
|
||||||
} else if (x >= width) {
|
Vector bounceInBox(uint8_t width, uint8_t height) const {
|
||||||
x = 2 * width - x;
|
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) {
|
while (y2 < 0 || y2 >= height) {
|
||||||
if (y < 0) {
|
if (y2 < 0) {
|
||||||
y = -y;
|
y2 = -y2;
|
||||||
} else if (y >= height) {
|
} else if (y2 >= height) {
|
||||||
y = 2 * height - y;
|
y2 = 2 * height - y2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return {x2, y2};
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "mode/Pong/Pong.h"
|
#include "mode/Pong/Pong.h"
|
||||||
#include "mode/SpaceInvaders/SpaceInvaders.h"
|
#include "mode/SpaceInvaders/SpaceInvaders.h"
|
||||||
#include "mode/NewYear/NewYear.h"
|
#include "mode/NewYear/NewYear.h"
|
||||||
|
#include "mode/Starfield/Starfield.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
ModeId currentModeId = NONE;
|
ModeId currentModeId = NONE;
|
||||||
@ -85,6 +86,9 @@ void loadNewMode() {
|
|||||||
case NEW_YEAR:
|
case NEW_YEAR:
|
||||||
mode = new NewYear(&display);
|
mode = new NewYear(&display);
|
||||||
break;
|
break;
|
||||||
|
case STARFIELD:
|
||||||
|
mode = new Starfield(&display);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Serial.print("No mode loaded.\n");
|
Serial.print("No mode loaded.\n");
|
||||||
display.clear();
|
display.clear();
|
||||||
|
|||||||
@ -19,6 +19,7 @@ enum ModeId {
|
|||||||
PONG,
|
PONG,
|
||||||
SPACE_INVADERS,
|
SPACE_INVADERS,
|
||||||
NEW_YEAR,
|
NEW_YEAR,
|
||||||
|
STARFIELD,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class Firework {
|
|||||||
|
|
||||||
Display *display{};
|
Display *display{};
|
||||||
|
|
||||||
Color color;
|
Color color = MAGENTA;
|
||||||
|
|
||||||
State state = RISE;
|
State state = RISE;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
position.set((double) random(display->width), display->height);
|
position = Vector((double) random(display->width), display->height);
|
||||||
color = randomColor();
|
color = randomColor();
|
||||||
state = INITIAL;
|
state = INITIAL;
|
||||||
|
|
||||||
@ -93,38 +93,37 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
void draw() {
|
||||||
Vector p;
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case INITIAL:
|
case INITIAL:
|
||||||
break;
|
break;
|
||||||
case RISE:
|
case RISE:
|
||||||
display->set(&position, YELLOW);
|
display->set(position, YELLOW);
|
||||||
break;
|
break;
|
||||||
case EXPLODE:
|
case EXPLODE:
|
||||||
drawParticle(p, +0.0, +1.0);
|
drawParticle(+0.0, +1.0);
|
||||||
drawParticle(p, +0.7, +0.7);
|
drawParticle(+0.7, +0.7);
|
||||||
drawParticle(p, +1.0, +0.0);
|
drawParticle(+1.0, +0.0);
|
||||||
drawParticle(p, +0.7, -0.7);
|
drawParticle(+0.7, -0.7);
|
||||||
drawParticle(p, +0.0, -1.0);
|
drawParticle(+0.0, -1.0);
|
||||||
drawParticle(p, -0.7, -0.7);
|
drawParticle(-0.7, -0.7);
|
||||||
drawParticle(p, -1.0, +0.0);
|
drawParticle(-1.0, +0.0);
|
||||||
drawParticle(p, -0.7, +0.7);
|
drawParticle(-0.7, +0.7);
|
||||||
break;
|
break;
|
||||||
case SPARKLE:
|
case SPARKLE:
|
||||||
if (randomBool(2)) drawParticle(p, +0.0, +1.0);
|
if (randomBool(2)) drawParticle(+0.0, +1.0);
|
||||||
if (randomBool(2)) drawParticle(p, +0.7, +0.7);
|
if (randomBool(2)) drawParticle(+0.7, +0.7);
|
||||||
if (randomBool(2)) drawParticle(p, +1.0, +0.0);
|
if (randomBool(2)) drawParticle(+1.0, +0.0);
|
||||||
if (randomBool(2)) drawParticle(p, +0.7, -0.7);
|
if (randomBool(2)) drawParticle(+0.7, -0.7);
|
||||||
if (randomBool(2)) drawParticle(p, +0.0, -1.0);
|
if (randomBool(2)) drawParticle(+0.0, -1.0);
|
||||||
if (randomBool(2)) drawParticle(p, -0.7, -0.7);
|
if (randomBool(2)) drawParticle(-0.7, -0.7);
|
||||||
if (randomBool(2)) drawParticle(p, -1.0, +0.0);
|
if (randomBool(2)) drawParticle(-1.0, +0.0);
|
||||||
if (randomBool(2)) drawParticle(p, -0.7, +0.7);
|
if (randomBool(2)) drawParticle(-0.7, +0.7);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawParticle(Vector &p, double x, double y) {
|
void drawParticle(double x, double y) {
|
||||||
display->set(p.set(position)->add(x * explosion, y * explosion), color);
|
display->set(position.plus(x * explosion, y * explosion), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAlive() {
|
bool isAlive() {
|
||||||
|
|||||||
@ -43,7 +43,7 @@ private:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAY:
|
case PLAY:
|
||||||
position.add(velocity);
|
position = position.plus(velocity);
|
||||||
player0.randomMove(display->height);
|
player0.randomMove(display->height);
|
||||||
player1.randomMove(display->height);
|
player1.randomMove(display->height);
|
||||||
paddleBounce();
|
paddleBounce();
|
||||||
@ -63,7 +63,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void topBottomBounce() {
|
void topBottomBounce() {
|
||||||
position.bounceInBox(display->width, display->height);
|
position = position.bounceInBox(display->width, display->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkScoring() {
|
void checkScoring() {
|
||||||
@ -132,7 +132,7 @@ public:
|
|||||||
explicit Pong(Display *display) :
|
explicit Pong(Display *display) :
|
||||||
Mode(display),
|
Mode(display),
|
||||||
position(display->width / 2.0, display->height / 2.0),
|
position(display->width / 2.0, display->height / 2.0),
|
||||||
velocity(random(360), exp10(1)) {
|
velocity(Vector::polar(random(360), exp10(1))) {
|
||||||
instance = this;
|
instance = this;
|
||||||
createTimer(100, [](Timer *timer, uint32_t counter, uint32_t currentCount) { instance->tick(timer, counter, currentCount); });
|
createTimer(100, [](Timer *timer, uint32_t counter, uint32_t currentCount) { instance->tick(timer, counter, currentCount); });
|
||||||
spawnBall(random(2) == 0 ? -1 : +1);
|
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=7">PONG</a><br>)");
|
||||||
server.sendContent(R"(<a href="/mode?mode=8">SPACE_INVADERS</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=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"(Helligkeit: <a href="/brighter">+</a> / <a href="/darker">-</a><br>)");
|
||||||
server.sendContent(R"(Geschwindigkeit: <a href="/faster">+</a> / <a href="/slower">-</a><br>)");
|
server.sendContent(R"(Geschwindigkeit: <a href="/faster">+</a> / <a href="/slower">-</a><br>)");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user