Merge branch 'master' into add-prometheus-metrics

This commit is contained in:
bdring
2019-11-03 18:34:33 -06:00
committed by GitHub
5 changed files with 141 additions and 76 deletions

View File

@@ -20,17 +20,16 @@ This was ported from the [TWANG fork](https://github.com/bdring/TWANG) by bdring
- All of the Arduino version game features are functional. - All of the Arduino version game features are functional.
- The game now has a WiFi access port to get game stats. Connect a smartphone or computer to see them. - The game now has a WiFi access port to get game stats. Connect a smartphone or computer to see them.
- **SSID:** TWANG_AP - **SSID:** TWANG_AP
- **Password:** esp32rocks - **Password:** 12345666
- **URL:** 192.168.4.1 - **URL:** 192.168.4.1
- You can update these settings over WiFi - You can update these settings over WiFi
- LED Count
- LED Brightness - LED Brightness
- Audio Volume - Audio Volume
- Joystick Deadzone (removes drift) - Joystick Deadzone (removes drift)
- Attack Threshold (twang sensitivity) - Attack Threshold (twang sensitivity)
- Lives Per Level - Lives Per Level
![](http://www.buildlog.net/blog/wp-content/uploads/2018/03/20180328_122254.jpg) ![](http://www.buildlog.net/blog/wp-content/uploads/2018/03/20180328_122254.jpg)
## TO DO List: ## TO DO List:
@@ -38,30 +37,15 @@ This was ported from the [TWANG fork](https://github.com/bdring/TWANG) by bdring
- Wireless features~~ - Wireless features~~
- 2 Player features by linking controllers. TBD - 2 Player features by linking controllers. TBD
======= =======
- Setting - Settings:
- I want to figure out a way to have the LED count be set via the web server. I often bring several length LED strings to an event because I don't know which size is most appropriate. A last minute recompile is not a good solution. - Change strip type.
- Wireless features~~
- 2 Player features by linking controllers. TBD
- Digitized Audio - Digitized Audio
- Currently the port uses the same square wave tones of the the Arduino version. - Currently the port uses the same square wave tones of the the Arduino version.
- I want to convert to digitized high quality sound effects. - I want to convert to digitized high quality sound effects.
- Possibly mix multiple sounds so things like lava and movement sound good at the same time. - Possibly mix multiple sounds so things like lava and movement sound good at the same time.
- Custom PCB
- Make wiring easier.
- More robust.
- Integrated audio amplifier.
- Python (it might be fun to make a Python version)
- Digitized Audio
- Currently the port uses the same square wave tones of the the Arduino version.
- I want to convert to digitized high quality sound effects.
- Possibly mix multiple sounds so things like lava and movement sound good at the same time.
- Better looking mobile web interface (looks more like a web app) - Better looking mobile web interface (looks more like a web app)
- Python (it might be fun to make a Python version) **BTW:** Since you have red this far... If you want to contribute, contact me and I might be able to get you some free or discounted hardware.
**BTW:** Since you have red this far... If you want to contribute, contact me and I might be able to get you some free or discounted hardware.
## Required libraries: ## Required libraries:
* [FastLED](http://fastled.io/) * [FastLED](http://fastled.io/)
@@ -127,6 +111,8 @@ They all call different functions and variables to setup the level. Each one is
* ontime: How long (ms) the lava is ON for * ontime: How long (ms) the lava is ON for
* offtime: How long the lava is ON for * offtime: How long the lava is ON for
* offset: How long (ms) after the level starts before the lava turns on, use this to create patterns with multiple lavas * offset: How long (ms) after the level starts before the lava turns on, use this to create patterns with multiple lavas
* grow: This specifies the rate of growth. Use 0 for no growth. Reasonable growth is 0.1 to 0.5
* flow: This specifies the rate/direction of flow. Reasonable numbers are 0.2 to 0.8
**spawnConveyor(startPoint, endPoint, speed);** (2 conveyors max) **spawnConveyor(startPoint, endPoint, speed);** (2 conveyors max)
* startPoint, endPoint: Same as lava * startPoint, endPoint: Same as lava

View File

@@ -3,9 +3,10 @@
class Lava class Lava
{ {
public: public:
void Spawn(int left, int right, int ontime, int offtime, int offset, int state); void Spawn(int left, int right, int ontime, int offtime, int offset, int state, float grow_rate, float flow_vector);
void Kill(); void Kill();
int Alive(); int Alive();
void Update();
int _left; int _left;
int _right; int _right;
int _ontime; int _ontime;
@@ -13,13 +14,18 @@ class Lava
int _offset; int _offset;
long _lastOn; long _lastOn;
int _state; int _state;
float _grow_rate = 0.0; // size grows by this much each tick
float _flow_vector = 0.0; // endpoints move in the direction each tick.
static const int OFF = 0; static const int OFF = 0;
static const int ON = 1; static const int ON = 1;
private: private:
int _alive; int _alive;
float _growth = 0;
float _flow = 0;
int _width;
}; };
void Lava::Spawn(int left, int right, int ontime, int offtime, int offset, int state){ void Lava::Spawn(int left, int right, int ontime, int offtime, int offset, int state, float grow_rate, float flow_vector){
_left = left; _left = left;
_right = right; _right = right;
_ontime = ontime; _ontime = ontime;
@@ -28,6 +34,13 @@ void Lava::Spawn(int left, int right, int ontime, int offtime, int offset, int s
_alive = 1; _alive = 1;
_lastOn = millis()-offset; _lastOn = millis()-offset;
_state = state; _state = state;
_width = _right - _left;
_grow_rate = fabs(grow_rate); // only allow positive growth
_flow_vector = flow_vector;
} }
void Lava::Kill(){ void Lava::Kill(){
@@ -37,3 +50,35 @@ void Lava::Kill(){
int Lava::Alive(){ int Lava::Alive(){
return _alive; return _alive;
} }
// this gets called on every frame.
void Lava::Update() {
// update how much it has changed
if (_grow_rate != 0) {
_growth += _grow_rate;
if (_growth >= 1.0) {
if (_left > 0)
_left -= 1;
if (_right < VIRTUAL_LED_COUNT)
_right += 1;
_growth = 0.0;
}
}
if (_flow_vector != 0) {
_flow += _flow_vector;
if (fabs(_flow) >=1) {
if (_left > 1 && _left < VIRTUAL_LED_COUNT - _width) {
_left += (int)_flow;
}
if (_right > _width && _right < VIRTUAL_LED_COUNT)
_right += (int)_flow;
_flow = 0.0;
}
}
}

View File

@@ -39,12 +39,12 @@
// twang files // twang files
#include "config.h" #include "config.h"
#include "twang_mpu.h" #include "twang_mpu.h"
#include "Enemy.h" #include "enemy.h"
#include "Particle.h" #include "particle.h"
#include "Spawner.h" #include "spawner.h"
#include "Lava.h" #include "lava.h"
#include "Boss.h" #include "boss.h"
#include "Conveyor.h" #include "conveyor.h"
#include "iSin.h" #include "iSin.h"
#include "sound.h" #include "sound.h"
#include "settings.h" #include "settings.h"
@@ -419,12 +419,14 @@ void loadLevel(){
activate: The delay in milliseconds before the first enemy activate: The delay in milliseconds before the first enemy
Lava: You can create 4 pools of lava. Lava: You can create 4 pools of lava.
spawnLava(left, right, ontime, offtime, offset, state); spawnLava(left, right, ontime, offtime, offset, state, grow, flow);
left: the lower end of the lava pool left: the lower end of the lava pool
right: the upper end of the lava pool right: the upper end of the lava pool
ontime: How long the lave stays on. ontime: How long the lave stays on.
offset: the delay before the first switch offset: the delay before the first switch
state: does it start on or off state: does it start on or off
grow: This specifies the rate of growth. Use 0 for no growth. Reasonable growth is 0.1 to 0.5
flow: This specifies the rate/direction of flow. Reasonable numbers are 0.2 to 0.8
Conveyor: You can create 2 conveyors. Conveyor: You can create 2 conveyors.
spawnConveyor(startPoint, endPoint, direction) spawnConveyor(startPoint, endPoint, direction)
@@ -458,17 +460,28 @@ void loadLevel(){
break; break;
case 3: case 3:
// Lava intro // Lava intro
spawnLava(400, 490, 2000, 2000, 0, Lava::OFF); spawnLava(400, 490, 2000, 2000, 0, Lava::OFF, 0, 0);
spawnEnemy(350, 0, 1, 0); spawnEnemy(350, 0, 1, 0);
spawnPool[0].Spawn(1000, 5500, 3, 0, 0); spawnPool[0].Spawn(1000, 5500, 3, 0, 0);
break; break;
case 4: case 4:
// Sin enemy // intro to moving lava (down)
spawnLava(400, 490, 2000, 2000, 0, Lava::OFF, 0, -0.5);
spawnEnemy(350, 0, 1, 0);
spawnPool[0].Spawn(1000, 5500, 3, 0, 0);
break;
case 5:
// lava spreading
spawnLava(400, 450, 2000, 2000, 0, Lava::OFF, 0.25, 0);
spawnEnemy(350, 0, 1, 0);
spawnPool[0].Spawn(1000, 5500, 3, 0, 0);
break;
case 6:
// Sin wave enemy
spawnEnemy(700, 1, 7, 275); spawnEnemy(700, 1, 7, 275);
spawnEnemy(500, 1, 5, 250); spawnEnemy(500, 1, 5, 250);
break; break;
case 5: case 7:
// Sin enemy swarm // Sin enemy swarm
spawnEnemy(700, 1, 7, 275); spawnEnemy(700, 1, 7, 275);
spawnEnemy(500, 1, 5, 250); spawnEnemy(500, 1, 5, 250);
@@ -478,14 +491,20 @@ void loadLevel(){
spawnEnemy(400, 1, 7, 150); spawnEnemy(400, 1, 7, 150);
spawnEnemy(450, 1, 5, 400); spawnEnemy(450, 1, 5, 400);
break; break;
case 6: case 8:
// lava moving up
playerPosition = 200;
spawnLava(10, 180, 2000, 2000, 0, Lava::OFF, 0, 0.5);
spawnEnemy(350, 0, 1, 0);
spawnPool[0].Spawn(1000, 5500, 3, 0, 0);
break;
case 9:
// Conveyor // Conveyor
spawnConveyor(100, 600, -6); spawnConveyor(100, 600, -6);
spawnEnemy(800, 0, 0, 0); spawnEnemy(800, 0, 0, 0);
break; break;
case 7: case 10:
// Conveyor of enemies // Conveyor of enemies
spawnConveyor(50, 1000, 6); spawnConveyor(50, 1000, 6);
spawnEnemy(300, 0, 0, 0); spawnEnemy(300, 0, 0, 0);
@@ -496,30 +515,36 @@ void loadLevel(){
spawnEnemy(800, 0, 0, 0); spawnEnemy(800, 0, 0, 0);
spawnEnemy(900, 0, 0, 0); spawnEnemy(900, 0, 0, 0);
break; break;
case 8: // spawn train; case 11:
// lava spread and fall
spawnLava(400, 450, 2000, 2000, 0, Lava::OFF, 0.2, -0.5);
spawnEnemy(350, 0, 1, 0);
spawnPool[0].Spawn(1000, 5500, 3, 0, 0);
break;
case 12: // spawn train;
spawnPool[0].Spawn(900, 1300, 2, 0, 0); spawnPool[0].Spawn(900, 1300, 2, 0, 0);
break; break;
case 9: // spawn train skinny attack width; case 13: // spawn train skinny attack width;
attack_width = 32; attack_width = 32;
spawnPool[0].Spawn(900, 1800, 2, 0, 0); spawnPool[0].Spawn(900, 1800, 2, 0, 0);
break; break;
case 10: // evil fast split spawner case 14: // evil fast split spawner
spawnPool[0].Spawn(550, 1500, 2, 0, 0); spawnPool[0].Spawn(550, 1500, 2, 0, 0);
spawnPool[1].Spawn(550, 1500, 2, 1, 0); spawnPool[1].Spawn(550, 1500, 2, 1, 0);
break; break;
case 11: // split spawner with exit blocking lava case 15: // split spawner with exit blocking lava
spawnPool[0].Spawn(500, 1200, 2, 0, 0); spawnPool[0].Spawn(500, 1200, 2, 0, 0);
spawnPool[1].Spawn(500, 1200, 2, 1, 0); spawnPool[1].Spawn(500, 1200, 2, 1, 0);
spawnLava(900, 950, 2200, 800, 2000, Lava::OFF); spawnLava(900, 950, 2200, 800, 2000, Lava::OFF, 0, 0);
break; break;
case 12: case 16:
// Lava run // Lava run
spawnLava(195, 300, 2000, 2000, 0, Lava::OFF); spawnLava(195, 300, 2000, 2000, 0, Lava::OFF, 0, 0);
spawnLava(400, 500, 2000, 2000, 0, Lava::OFF); spawnLava(400, 500, 2000, 2000, 0, Lava::OFF, 0, 0);
spawnLava(600, 700, 2000, 2000, 0, Lava::OFF); spawnLava(600, 700, 2000, 2000, 0, Lava::OFF, 0, 0);
spawnPool[0].Spawn(1000, 3800, 4, 0, 0); spawnPool[0].Spawn(1000, 3800, 4, 0, 0);
break; break;
case 13: case 17:
// Sin enemy #2 practice (slow conveyor) // Sin enemy #2 practice (slow conveyor)
spawnEnemy(700, 1, 7, 275); spawnEnemy(700, 1, 7, 275);
spawnEnemy(500, 1, 5, 250); spawnEnemy(500, 1, 5, 250);
@@ -527,7 +552,7 @@ void loadLevel(){
spawnPool[1].Spawn(0, 5500, 5, 1, 10000); spawnPool[1].Spawn(0, 5500, 5, 1, 10000);
spawnConveyor(100, 900, -4); spawnConveyor(100, 900, -4);
break; break;
case 14: case 18:
// Sin enemy #2 (fast conveyor) // Sin enemy #2 (fast conveyor)
spawnEnemy(800, 1, 7, 275); spawnEnemy(800, 1, 7, 275);
spawnEnemy(700, 1, 7, 275); spawnEnemy(700, 1, 7, 275);
@@ -536,7 +561,7 @@ void loadLevel(){
spawnPool[1].Spawn(0, 5500, 5, 1, 10000); spawnPool[1].Spawn(0, 5500, 5, 1, 10000);
spawnConveyor(100, 900, -6); spawnConveyor(100, 900, -6);
break; break;
case 15: // (don't edit last level) case 19: // (don't edit last level)
// Boss this should always be the last level // Boss this should always be the last level
spawnBoss(); spawnBoss();
break; break;
@@ -577,10 +602,10 @@ void spawnEnemy(int pos, int dir, int speed, int wobble){
} }
} }
void spawnLava(int left, int right, int ontime, int offtime, int offset, int state){ void spawnLava(int left, int right, int ontime, int offtime, int offset, int state, float grow, float flow){
for(int i = 0; i<LAVA_COUNT; i++){ for(int i = 0; i<LAVA_COUNT; i++){
if(!lavaPool[i].Alive()){ if(!lavaPool[i].Alive()){
lavaPool[i].Spawn(left, right, ontime, offtime, offset, state); lavaPool[i].Spawn(left, right, ontime, offtime, offset, state, grow, flow);
return; return;
} }
} }
@@ -802,6 +827,7 @@ void tickLava(){
for(i = 0; i<LAVA_COUNT; i++){ for(i = 0; i<LAVA_COUNT; i++){
LP = lavaPool[i]; LP = lavaPool[i];
if(LP.Alive()){ if(LP.Alive()){
LP.Update(); // for grow and flow
A = getLED(LP._left); A = getLED(LP._left);
B = getLED(LP._right); B = getLED(LP._right);
if(LP._state == Lava::OFF){ if(LP._state == Lava::OFF){
@@ -1073,7 +1099,7 @@ bool inLava(int pos){
for(i = 0; i<LAVA_COUNT; i++){ for(i = 0; i<LAVA_COUNT; i++){
LP = lavaPool[i]; LP = lavaPool[i];
if(LP.Alive() && LP._state == Lava::ON){ if(LP.Alive() && LP._state == Lava::ON){
if(LP._left < pos && LP._right > pos) return true; if(LP._left <= pos && LP._right > pos) return true;
} }
} }
return false; return false;

View File

@@ -34,9 +34,9 @@
#define VIRTUAL_LED_COUNT 1000 #define VIRTUAL_LED_COUNT 1000
// what type of LED Strip....uncomment to define only one of these // what type of LED Strip....uncomment to define only one of these
//#define USE_APA102 #define USE_APA102
.#define USE_NEOPIXEL //#define USE_NEOPIXEL
// Check to make sure LED choice was done right // Check to make sure LED choice was done right
#if !defined(USE_NEOPIXEL) && !defined(USE_APA102) #if !defined(USE_NEOPIXEL) && !defined(USE_APA102)
@@ -53,7 +53,7 @@
#define CONVEYOR_BRIGHTNESS 8 #define CONVEYOR_BRIGHTNESS 8
#define LAVA_OFF_BRIGHTNESS 4 #define LAVA_OFF_BRIGHTNESS 4
#define MAX_LEDS VIRTUAL_LED_COUNT // these LEDS can handle the max #define MAX_LEDS VIRTUAL_LED_COUNT // these LEDS can handle the max
#define MIN_REDRAW_INTERVAL 1000.0 / 60.0 // divide by frames per second..if you tweak adjust player speed #define MIN_REDRAW_INTERVAL 1000.0 / 60.0 // divide by frames per second..if you tweak, adjust player speed
#endif #endif
#ifdef USE_NEOPIXEL #ifdef USE_NEOPIXEL

View File

@@ -2,7 +2,7 @@
#include "settings.h" #include "settings.h"
const char* ssid = "TWANG_AP"; const char* ssid = "TWANG_AP";
const char* passphrase = "esp32rocks"; const char* passphrase = "12345666";
WiFiServer server(80); WiFiServer server(80);
@@ -16,8 +16,11 @@ enum PAGE_TO_SEND
}; };
void ap_setup() { void ap_setup() {
bool ret; bool ret;
/* /*
* Set up an access point * Set up an access point
* @param ssid Pointer to the SSID (max 63 char). * @param ssid Pointer to the SSID (max 63 char).
@@ -26,10 +29,15 @@ void ap_setup() {
* @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID) * @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
*/ */
ret = WiFi.softAP(ssid, passphrase, 2, 0); ret = WiFi.softAP(ssid, passphrase, 2, 0);
//Serial.println("\r\nWiFi AP online ...");
server.begin(); server.begin();
}
Serial.print("\r\nWiFi SSID: ");
Serial.println(ssid);
Serial.print("WiFi Password: ");
Serial.println(passphrase);
Serial.println("Web Server Address: http://192.168.4.1");
}
void sendStatsPage(WiFiClient client) { void sendStatsPage(WiFiClient client) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)