|
|
|
|
@@ -65,8 +65,6 @@
|
|
|
|
|
#define USE_GRAVITY 0 // 0/1 use gravity (LED strip going up wall)
|
|
|
|
|
#define BEND_POINT 550 // 0/1000 point at which the LED strip goes up the wall
|
|
|
|
|
|
|
|
|
|
// Players settings
|
|
|
|
|
#define MAX_PLAYERS 4
|
|
|
|
|
// this can become a setting in the future
|
|
|
|
|
#define NUM_PLAYERS 2
|
|
|
|
|
|
|
|
|
|
@@ -141,7 +139,7 @@ Conveyor conveyorPool[CONVEYOR_COUNT] = {
|
|
|
|
|
|
|
|
|
|
Boss boss = Boss();
|
|
|
|
|
|
|
|
|
|
Player player[NUM_PLAYERS] = {
|
|
|
|
|
Player players[NUM_PLAYERS] = {
|
|
|
|
|
Player(0, LIVES_PER_LEVEL, ATTACK_DURATION),
|
|
|
|
|
Player(1, LIVES_PER_LEVEL, ATTACK_DURATION)
|
|
|
|
|
};
|
|
|
|
|
@@ -256,9 +254,9 @@ void setup() {
|
|
|
|
|
stageStartTime = millis();
|
|
|
|
|
|
|
|
|
|
// set players color
|
|
|
|
|
player[0].setColor(0,255,0);
|
|
|
|
|
player[1].setColor(127,2,255);
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
players[0].setColor(0,255,0);
|
|
|
|
|
players[1].setColor(127,2,255);
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Lives ( user_settings.lives_per_level );
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
@@ -272,7 +270,7 @@ void loop() {
|
|
|
|
|
|
|
|
|
|
if(stage == PLAY){
|
|
|
|
|
bool attacking = false;
|
|
|
|
|
for (const Player& p: player) attacking = attacking || p.attacking;
|
|
|
|
|
for (const Player& p: players) attacking = attacking || p.attacking;
|
|
|
|
|
|
|
|
|
|
if(attacking){
|
|
|
|
|
SFXattacking();
|
|
|
|
|
@@ -331,7 +329,7 @@ void loop() {
|
|
|
|
|
// allow selecting player color during first sec of first level
|
|
|
|
|
if (levelNumber == 0) {
|
|
|
|
|
if ((stageStartTime + COLOR_SELECT_DUR) > mm) {
|
|
|
|
|
for (Player& p : player) {
|
|
|
|
|
for (Player& p : players) {
|
|
|
|
|
if (joystickWobble[p.Id()] >= user_settings.attack_threshold) {
|
|
|
|
|
random_player_color(p);
|
|
|
|
|
stageStartTime = mm;
|
|
|
|
|
@@ -342,7 +340,7 @@ void loop() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// real action here
|
|
|
|
|
for (Player& p : player) {
|
|
|
|
|
for (Player& p : players) {
|
|
|
|
|
|
|
|
|
|
if (p.captured) continue;
|
|
|
|
|
|
|
|
|
|
@@ -386,16 +384,16 @@ void loop() {
|
|
|
|
|
// exploding players during PLAY stage
|
|
|
|
|
tickParticles();
|
|
|
|
|
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
tickConveyors(p);
|
|
|
|
|
|
|
|
|
|
tickSpawners();
|
|
|
|
|
tickBoss();
|
|
|
|
|
tickLava();
|
|
|
|
|
|
|
|
|
|
for (Player& p : player) if (!p.captured) tickEnemies(p);
|
|
|
|
|
for (const Player& p : player) if (!p.captured) drawAttack(p);
|
|
|
|
|
for (const Player& p : player) if (!p.captured) drawPlayer(p);
|
|
|
|
|
for (Player& p : players) if (!p.captured) tickEnemies(p);
|
|
|
|
|
for (const Player& p : players) if (!p.captured) drawAttack(p);
|
|
|
|
|
for (const Player& p : players) if (!p.captured) drawPlayer(p);
|
|
|
|
|
|
|
|
|
|
drawExit();
|
|
|
|
|
}else if(stage == DEAD){
|
|
|
|
|
@@ -421,7 +419,7 @@ void loop() {
|
|
|
|
|
// restart from the beginning
|
|
|
|
|
stage = STARTUP;
|
|
|
|
|
stageStartTime = millis();
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Lives ( user_settings.lives_per_level );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -442,7 +440,7 @@ void loadLevel(){
|
|
|
|
|
|
|
|
|
|
/// Defaults...OK to change the following items in the levels below
|
|
|
|
|
attack_width = DEFAULT_ATTACK_WIDTH;
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Spawn( 0 + p.Id()*10 ); // slightly displace players
|
|
|
|
|
|
|
|
|
|
/* ==== Level Editing Guide ===============
|
|
|
|
|
@@ -506,7 +504,7 @@ void loadLevel(){
|
|
|
|
|
*/
|
|
|
|
|
switch(levelNumber){
|
|
|
|
|
case 0: // basic introduction
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Spawn( 200 + p.Id()*10 );
|
|
|
|
|
spawnEnemy(1, 0, 0, 0);
|
|
|
|
|
break;
|
|
|
|
|
@@ -554,7 +552,7 @@ void loadLevel(){
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
// lava moving up
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Spawn( 200 + p.Id()*10 );
|
|
|
|
|
spawnLava(10, 180, 2000, 2000, 0, Lava::OFF, 0, 0.5);
|
|
|
|
|
spawnEnemy(350, 0, 1, 0);
|
|
|
|
|
@@ -658,7 +656,7 @@ void spawnEnemy(int pos, int dir, int speed, int wobble){
|
|
|
|
|
if(!enemyPool[e].Alive()){
|
|
|
|
|
enemyPool[e].Spawn(pos, dir, speed, wobble);
|
|
|
|
|
// for each player, save if it is above or below
|
|
|
|
|
for (const Player& p : player)
|
|
|
|
|
for (const Player& p : players)
|
|
|
|
|
enemyPool[e].playersSide[p.Id()] = pos > p.position?1:-1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -711,7 +709,7 @@ void levelComplete(){
|
|
|
|
|
}
|
|
|
|
|
if (levelNumber != 0) // no points for the first level
|
|
|
|
|
{
|
|
|
|
|
score = score + (player[0].Lives() * 10); //
|
|
|
|
|
for (Player& p : players) score = score + (p.Lives() * 10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -722,11 +720,11 @@ void nextLevel(){
|
|
|
|
|
stage = STARTUP;
|
|
|
|
|
stageStartTime = millis();
|
|
|
|
|
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
p.Lives ( user_settings.lives_per_level );
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
for (Player& p : player) {
|
|
|
|
|
for (Player& p : players) {
|
|
|
|
|
if (!p.Alive()) p.Lives ( user_settings.lives_per_level );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -749,7 +747,7 @@ void die(Player& p){
|
|
|
|
|
int stillPlaying = 0;
|
|
|
|
|
// how many players have lives?
|
|
|
|
|
bool allDead = true;
|
|
|
|
|
for (const Player& pp : player) {
|
|
|
|
|
for (const Player& pp : players) {
|
|
|
|
|
stillPlaying += !pp.captured;
|
|
|
|
|
allDead &= !pp.Alive();
|
|
|
|
|
}
|
|
|
|
|
@@ -861,7 +859,7 @@ void tickBoss(){
|
|
|
|
|
leds[i] %= 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Player& p : player)
|
|
|
|
|
for (Player& p : players)
|
|
|
|
|
{
|
|
|
|
|
// CHECK COLLISION
|
|
|
|
|
if(getLED(p.position) > getLED(boss._pos - BOSS_WIDTH/2) && getLED(p.position) < getLED(boss._pos + BOSS_WIDTH)){
|
|
|
|
|
@@ -1092,13 +1090,13 @@ void tickGameover(long mm) {
|
|
|
|
|
if(stageStartTime+GAMEOVER_SPREAD_DURATION > mm) // Spread red from player position to top and bottom
|
|
|
|
|
{
|
|
|
|
|
// fill to top
|
|
|
|
|
int n = _max(map(((mm-stageStartTime)), 0, GAMEOVER_SPREAD_DURATION, getLED(player[0].position), user_settings.led_count), 0);
|
|
|
|
|
for(int i = getLED(player[0].position); i<= n; i++){
|
|
|
|
|
int n = _max(map(((mm-stageStartTime)), 0, GAMEOVER_SPREAD_DURATION, getLED(killPos), user_settings.led_count), 0);
|
|
|
|
|
for(int i = getLED(killPos); i<= n; i++){
|
|
|
|
|
leds[i] = CRGB(255, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
// fill to bottom
|
|
|
|
|
n = _max(map(((mm-stageStartTime)), 0, GAMEOVER_SPREAD_DURATION, getLED(player[0].position), 0), 0);
|
|
|
|
|
for(int i = getLED(player[0].position); i>= n; i--){
|
|
|
|
|
n = _max(map(((mm-stageStartTime)), 0, GAMEOVER_SPREAD_DURATION, getLED(killPos), 0), 0);
|
|
|
|
|
for(int i = getLED(killPos); i>= n; i--){
|
|
|
|
|
leds[i] = CRGB(255, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
SFXgameover();
|
|
|
|
|
@@ -1149,7 +1147,7 @@ void drawLives()
|
|
|
|
|
SFXcomplete(); // stop any sounds
|
|
|
|
|
FastLED.clear();
|
|
|
|
|
|
|
|
|
|
for (const Player& p : player) {
|
|
|
|
|
for (const Player& p : players) {
|
|
|
|
|
int pos = 0;
|
|
|
|
|
for (int i = 0; i < p.Lives(); i++)
|
|
|
|
|
{
|
|
|
|
|
|