Added effect 'gol': Conway's Game of Life.
This commit is contained in:
parent
291a3be623
commit
1e23936374
@ -7,11 +7,12 @@ class Window {
|
||||
public:
|
||||
const uint8_t x, y;
|
||||
const uint8_t width, height;
|
||||
uint16_t count;
|
||||
static Window* getFullWindow();
|
||||
|
||||
Window(): Window(0, 0, LED_WIDTH, LED_HEIGHT) {};
|
||||
Window(uint8_t x, uint8_t y) : Window(x, y, LED_WIDTH-x, LED_HEIGHT-y) {};
|
||||
Window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) : x(x), y(y), width(width), height(height) {};
|
||||
Window(uint8_t x, uint8_t y, uint8_t width, uint8_t height) : x(x), y(y), width(width), height(height) { count = width*height; };
|
||||
|
||||
void clear();
|
||||
void clear(CRGB* color);
|
||||
|
@ -69,7 +69,9 @@
|
||||
#define EFFECT_FIREWORK_BLUR 200
|
||||
#define EFFECT_FIREWORK_FADEOUT_SPEED 5
|
||||
|
||||
|
||||
#define EFFECT_GOL_START_PERCENTAGE 128
|
||||
#define EFFECT_GOL_BLEND_SPEED 5
|
||||
|
||||
// Stop editing here
|
||||
|
||||
#ifdef DEBUG
|
||||
|
23
include/effect_gol.h
Normal file
23
include/effect_gol.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "Effect.h"
|
||||
|
||||
class GolEffect : public Effect {
|
||||
private:
|
||||
uint8_t *_data;
|
||||
uint8_t *_old;
|
||||
uint8_t _blend;
|
||||
uint8_t _hue = 0;
|
||||
uint8_t _old_hue = 0;
|
||||
uint16_t _step;
|
||||
|
||||
void _advance();
|
||||
void _draw();
|
||||
void _initialize();
|
||||
|
||||
public:
|
||||
GolEffect();
|
||||
void start();
|
||||
void stop();
|
||||
void loop();
|
||||
bool can_be_shown_with_clock();
|
||||
};
|
98
src/effect_gol.cpp
Normal file
98
src/effect_gol.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include "effect_gol.h"
|
||||
#include "my_fastled.h"
|
||||
|
||||
GolEffect::GolEffect() {
|
||||
this->window = new Window(0, 0, LED_WIDTH, LED_HEIGHT-6);
|
||||
}
|
||||
|
||||
bool GolEffect::can_be_shown_with_clock() { return true; }
|
||||
|
||||
void GolEffect::start() {
|
||||
_data = new uint8_t[this->window->count];
|
||||
_old = new uint8_t[this->window->count];
|
||||
for(uint16_t i=0; i<this->window->count; i++) {
|
||||
_old[i] = 0;
|
||||
}
|
||||
_initialize();
|
||||
}
|
||||
|
||||
void GolEffect::_initialize() {
|
||||
for(uint16_t i=0; i<this->window->count; i++) {
|
||||
_data[i] = random8() < EFFECT_GOL_START_PERCENTAGE ? 1 : 0;
|
||||
}
|
||||
_old_hue = _hue;
|
||||
_hue = random8();
|
||||
_step = 0;
|
||||
}
|
||||
|
||||
void GolEffect::stop() {
|
||||
delete[] _data;
|
||||
delete[] _old;
|
||||
}
|
||||
|
||||
void GolEffect::loop() {
|
||||
if (EFFECT_GOL_BLEND_SPEED + _blend > 255) {
|
||||
_blend = 0;
|
||||
_advance();
|
||||
} else {
|
||||
_blend += EFFECT_GOL_BLEND_SPEED;
|
||||
}
|
||||
|
||||
_draw();
|
||||
}
|
||||
|
||||
void GolEffect::_advance() {
|
||||
_step++;
|
||||
_old_hue = _hue;
|
||||
if (_step >= EFFECT_GOL_RESTART_AFTER_STEPS) {
|
||||
_initialize();
|
||||
} else {
|
||||
for(uint16_t i=0; i<this->window->count; i++) {
|
||||
_old[i] = _data[i];
|
||||
}
|
||||
uint8_t w = this->window->width;
|
||||
uint16_t changes = 0;
|
||||
for(uint8_t x=0; x<this->window->width; x++) for(uint8_t y=0; y<this->window->height; y++) {
|
||||
uint16_t index = y*w + x;
|
||||
uint8_t count =
|
||||
(x>0 && y>0 && _old[index - w - 1]) +
|
||||
(y>0 && _old[index - w]) +
|
||||
(x<this->window->width-1 && y>0 && _old[index - w + 1]) +
|
||||
|
||||
(x>0 && _old[index - 1]) +
|
||||
(x<this->window->width-1 && _old[index + 1]) +
|
||||
|
||||
(x>0 && y<this->window->height-1 && _old[index + w - 1]) +
|
||||
(y<this->window->height-1 && _old[index + w]) +
|
||||
(x<this->window->width-1 && y<this->window->height-1 && _old[index + w + 1]);
|
||||
if (_old[index]==0 && count==3) {
|
||||
// birth
|
||||
_data[index]=1;
|
||||
changes++;
|
||||
}
|
||||
if (_old[index]>0) {
|
||||
if (count<2 || count>3) {
|
||||
//death
|
||||
_data[index]=0;
|
||||
changes++;
|
||||
} else if (_data[index] < 255) {
|
||||
//ageing
|
||||
_data[index]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changes == 0) {
|
||||
_initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GolEffect::_draw() {
|
||||
for(uint16_t i=0; i<this->window->count; i++) {
|
||||
CRGB o = _old[i]==0 ? CRGB::Black : (CRGB)CHSV(_old_hue, 180, 255);
|
||||
CRGB n = _data[i]==0 ? CRGB::Black : (CRGB)CHSV(_hue, 180, 255);
|
||||
CRGB result = nblend(o, n, _blend);
|
||||
this->window->setPixelByIndex(i, &result);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
#include "effect_snake.h"
|
||||
#include "effect_fire.h"
|
||||
#include "effect_firework.h"
|
||||
#include "effect_gol.h"
|
||||
|
||||
SimpleList<EffectEntry>* effects;
|
||||
SimpleList<Effect*>* cycle_effects;
|
||||
@ -38,6 +39,7 @@ ConfettiEffect effect_confetti;
|
||||
SnakeEffect effect_snake;
|
||||
FireEffect effect_fire;
|
||||
FireworkEffect effect_firework;
|
||||
GolEffect effect_gol;
|
||||
|
||||
Effect* current_effect;
|
||||
|
||||
@ -62,6 +64,7 @@ void setup_effects() {
|
||||
effects->add((EffectEntry){"snake", (Effect *)&effect_snake});
|
||||
effects->add((EffectEntry){"fire", (Effect *)&effect_fire});
|
||||
effects->add((EffectEntry){"firework", (Effect *)&effect_firework});
|
||||
effects->add((EffectEntry){"gol", (Effect *)&effect_gol});
|
||||
|
||||
cycle_effects->add(&effect_sinematrix3);
|
||||
cycle_effects->add(&effect_multi_dynamic);
|
||||
@ -69,6 +72,7 @@ void setup_effects() {
|
||||
cycle_effects->add(&effect_confetti);
|
||||
cycle_effects->add(&effect_single_dynamic);
|
||||
cycle_effects->add(&effect_snake);
|
||||
cycle_effects->add(&effect_gol);
|
||||
|
||||
current_effect = &effect_cycle;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user