Пример #1
0
void Engine::nextMove(int turn, Pattern patt, Graphics* graph) {
    // Big and ugly switch function, but much less work than using functors, for the same effect
    // TODO: change the values that now are magic numbers so that the destruction of the ships in a stage triggers the beginning of another one
    
    switch (patt) {
        case MAIN_STAGE:
// FIRST ENEMY
            if (turn == 0) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn < 20 ) {
                // This is an excellent porting
                graph->printOtherOnScreen(SHIP_PORTING, 60, 60, turn*18, static_cast<double>(turn)/20);
            }
            else if (turn == 20) {
                spawnEnemy(40, 40, EN_FIGHTER, 1);
            }
            else if (turn > 20 && turn < 360) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(0, 2, enemyFleet[0]);
                }
            }
            else if (turn == 360 && enemyOnScreen) {
                // Here I need not use enemy1 and so on because I'm cleaning everything
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 360 && turn < 380) {
                if (expiredEnemy0) {
                    // Maybe turning the lasers a little in the direction of movement helps
                    graph->printOtherOnScreen(SHIP_PORTING, 740, 60, turn*18, static_cast<double>(380 - turn)/20);
                }
            }
            else if (turn == 380) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
            }
            if (turn >= 31 && turn % 15 == 1 && turn < 360) {
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -4; i <= 4; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/24 + (pi*1.5), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
// SECOND ENEMY
            if (turn == 400) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 400 && turn < 420 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 740, 60, (turn-400)*18, static_cast<double>(turn - 400)/20);
            }
            else if (turn == 420) {
                spawnEnemy(720, 40, EN_FIGHTER, 1);
            }
            else if (turn > 420 && turn < 760) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(pi, 2, enemyFleet[0]);
                }
            }
            else if (turn == 760 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 760 && turn < 780) {
                if (expiredEnemy0) {
                    graph->printOtherOnScreen(SHIP_PORTING, 60, 60, turn*18, static_cast<double>(780 - turn)/20);
                }
            }
            else if (turn == 780) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
            }
            if (turn >= 431 && turn % 15 == 1 && turn < 760) {
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -4; i <= 4; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/24 + (pi*1.5), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
// THIRD AND FOURTH ENEMIES
            // They move in sinusoids
            if (turn == 800) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 800 && turn < 820 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 60, 100, (turn-800)*18, static_cast<double>(turn - 800)/20);
                graph->printOtherOnScreen(SHIP_PORTING, 760, 100, (turn-800)*18, static_cast<double>(turn - 800)/20);
            }
            else if (turn == 820) {
                // enemy1 is the one on the right
                spawnEnemy(40, 80, EN_FIGHTER, 0.4);
                spawnEnemy(740, 80, EN_FIGHTER, 0.4);
            }
            else if (turn > 820 && turn < 1160) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(0, 2, enemyFleet[0]);
                    moveEnemyOnMap(pi/2, 5*sin((turn-800)/(2*pi)), enemyFleet[0]);
                }
                if (enemyFleet[1]) {
                    moveEnemyOnMap(pi, 2, enemyFleet[1]);
                    moveEnemyOnMap(pi/2, 5*sin((turn-800)/(2*pi)), enemyFleet[1]);
                }
            }
            else if (turn == 1160 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                if (enemyFleet[1]->isAlive()) {
                    expiredEnemy1 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 1160 && turn < 1180) {
                if (expiredEnemy0 == true) {
                    graph->printOtherOnScreen(SHIP_PORTING, 738, 148, turn*18, static_cast<double>(1180 - turn)/20);
                }
                if (expiredEnemy1 == true) {
                    graph->printOtherOnScreen(SHIP_PORTING, 82, 148, turn*18, static_cast<double>(1180 - turn)/20);
                }
            }
            else if (turn == 1180) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
                expiredEnemy1 = false;
            }
            if (turn >= 831 && turn % 10 == 1 && turn < 1160) {
                bool laserPlayed = false;
                if (enemyFleet[0]->isAlive()) {
                    // Not exactly right, now i'll think
                    for (int i = -1; i<= 1; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(i*pi/6 + 1.5*pi - (pi*(turn-1000)/350), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
                if (enemyFleet[1]->isAlive()) {
                    for (int i = -1; i <= 1; i++) {
                        Laser* tmp = enemyFleet[1]->shootLaser(i*pi/6 + 1.5*pi + (pi*(turn-1000)/350), LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
            }
// FIFTH AND SIXTH ENEMIES
            // They move in circles
            if (turn == 1200) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 1200 && turn < 1220 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 160, 60, (turn-1200)*18, static_cast<double>(turn - 1200)/20);
                graph->printOtherOnScreen(SHIP_PORTING, 640, 60, (turn-1200)*18, static_cast<double>(turn - 1200)/20);
            }
            else if (turn == 1220) {
                // enemy1 is the one on the right
                spawnEnemy(180, 40, EN_FIGHTER, 0.8);
                spawnEnemy(580, 40, EN_FIGHTER, 0.8);
            }
            else if (turn > 1220 && turn < 1940) {
                if (enemyFleet[0]) {
                    moveEnemyOnMap(pi + (turn-1200)*pi/180, 2, enemyFleet[0]);
                }
                if (enemyFleet[1]) {
                    moveEnemyOnMap(-(turn-1200)*pi/180, 2, enemyFleet[1]);
                }
            }
            else if (turn == 1940 && enemyOnScreen) {
                if (enemyFleet[0]->isAlive()) {
                    expiredEnemy0 = true;
                }
                if (enemyFleet[1]->isAlive()) {
                    expiredEnemy1 = true;
                }
                cleanEnemyFleet();
                Mix_PlayChannel(-1, graph->getPortOut(), 0);
            }
            else if (turn > 1940 && turn < 1960) {
                if (expiredEnemy0) {
                    graph->printOtherOnScreen(SHIP_PORTING, 202, 59, turn*18, static_cast<double>(1960 - turn)/20);
                }
                if (expiredEnemy1) {
                    graph->printOtherOnScreen(SHIP_PORTING, 598, 59, turn*18, static_cast<double>(1960 - turn)/20);
                }
            }
            else if (turn == 1940) {
                cleanEnemyFleet();
                expiredEnemy0 = false;
                expiredEnemy1 = false;
            }
            if (turn >= 1231 && turn % 12 == 1 && turn < 1940) {
                double angleToProtagonist0 = atan2( enemyFleet[0]->getY() - protagonist->getY(), -(enemyFleet[0]->getX() - protagonist->getX()));
                double angleToProtagonist1 = atan2( enemyFleet[1]->getY() - protagonist->getY(), -(enemyFleet[1]->getX() - protagonist->getX()));
                // To use as the angle of the central laser in the burst. Redirecting the lasers will require a bunch of new atan2s
                bool laserPlayed = false;
                if (enemyFleet[0]->isAlive()) {
                    for (int i = -2; i<=2; i++) {
                        Laser* tmp = enemyFleet[0]->shootLaser(angleToProtagonist0 + i*pi/50, LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
                if (enemyFleet[1]->isAlive()) {
                    for (int i = -2; i<=2; i++) {
                        Laser* tmp = enemyFleet[1]->shootLaser(angleToProtagonist1 + i*pi/50, LASER_ENEMY);
                        tmp->setSpeed(6);
                        lasersOnMap.push_back(tmp);
                        if (!laserPlayed) {
                            Mix_PlayChannel(-1, graph->getZap(), 0);
                            laserPlayed = true;
                        }
                    }
                }
            }
// SEVENTH AND FINAL ENEMY
            if (turn == 1980) {
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn > 1980 && turn < 2000 ) {
                graph->printOtherOnScreen(SHIP_PORTING, 400, 80, (turn-1980)*18, static_cast<double>(turn - 1980)/20);
            }
            else if (turn == 2000) {
                // enemy1 is the one on the right
                spawnEnemy(380, 60, EN_FIGHTER, 2);
            }
            if (((turn%90 == 10 && turn >= 2000) || turn == 2000) && enemyFleet[0]->isAlive()) {
                bool laserPlayed = false;
                for (int i = 0; i < 18; i++) {
                    Laser* tmp = enemyFleet[0]->shootLaser(i*pi/9, LASER_ENEMY);
                    tmp->setSpeed(4);
                    lasersOnMap.push_back(tmp);
                    if (!laserPlayed) {
                        Mix_PlayChannel(-1, graph->getZap(), 0);
                        laserPlayed = true;
                    }
                }
            }
            if (turn >= 2000 && turn%90 >= 20) {
                int directionSwitch = ((turn-2000)/90)%3;
                moveEnemyOnMap(5*pi/3 - directionSwitch*2*pi/3, 4, enemyFleet[0]);
            }
            if (turn >= 2000) {
                for (int i = 0; i<lasersOnMap.size(); i++) {
                    if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() > 16 && lasersOnMap[i]->getTurnsInLife() <= 20) {
                        lasersOnMap[i]->setSpeed(lasersOnMap[i]->getSpeed() - 1);
                    }
                    else if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() == 40) {
                        double angDest = atan2( lasersOnMap[i]->getCentergY() - protagonist->getCenterY(), -(lasersOnMap[i]->getCentergX() - protagonist->getCenterX()));
                        lasersOnMap[i]->setAngle(angDest);
                    }
                    else if (!lasersOnMap[i]->isSBA() && lasersOnMap[i]->getTurnsInLife() == 50) {
                        lasersOnMap[i]->setSpeed(25);
                    }
                }
            }
            break;
            
// Formerly FLOWER
        case BOSS_STAGE:
            if (turn == 0) {
                cleanEnemyFleet();
                cleanLasers();
                floweringBoss = true;
                bossPosition = 0;
                Mix_PlayChannel(-1, graph->getPortIn(), 0);
            }
            if (turn < 20 ) {
                // This is an excellent porting
                graph->printOtherOnScreen(SHIP_PORTING, 400, 60, turn*18, static_cast<double>(turn)/20);
            }
            else if (turn == 20) {
                if (enemyFleet.size() == 0) {
                    spawnEnemy(380, 40, EN_CORVETTE, 1);
                }
                patternTurnsHelper = 0;   // The pattern is nicer this way
            }
            else if (turn <= 30) {
                // TODO: Adjust values
                moveEnemyOnMap((pi*1.5), 10, enemyFleet[0]);
            }
            
            if (turn >= 31 && turn % 500 <= 400) {
                if (enemyFleet[0]->isAlive() && enemyFleet.size() > 0 && turn%7 == 1) {
                    
                    // When it's the Flowering Night, then time will stop on the Lunar Clock. Only she who possesses the Pocket Watch of Blood will be able to go against the flow in stillness and against the stillness in the flow. She is Sakuya Izayoi, the maid in the Scarlet Devil Mansion.
                    // On unrelated news, the patterny pattern when it's not flowering is given later by manipulating the lazerbeams
                    if (floweringBoss) {
                        for (int i = 0; i<=20; i++) {
                            Laser* tmp = enemyFleet[0]->shootLaser(i*pi/10 + patternTurnsHelper*pi/32, LASER_ENEMY);
                            tmp->setSpeed(8);
                            lasersOnMap.push_back(tmp);
                        }
                    }
                    
                    // The pattern part when you're not flowering is given by shooting harmonically
                    else {
                        for (int i = 0; i<=20; i++) {
                            Laser* tmp = enemyFleet[0]->shootLaser(i*pi/10 + (pi/8)*sin((pi/100)*(turn%500)), LASER_ENEMY);
                            tmp->setSpeed(8);
                            lasersOnMap.push_back(tmp);
                        }
                    }
                    Mix_PlayChannel(-1, graph->getZap(), 0);
                }
            }
            
            /*      Possible pattern?
             *            entry
             *              |
             *      (. . . .V. . . .)
             *      (. 4 . .0. . 2 .)
             *      (. 6 . .8. . 5 .)
             *      (. 1 . .3. . 7 .)
             *      (. . . . . . . .)
             *      (. . . . . . . .)
             */
            
            if (turn >= 31 && turn % 500 >= 400) {
                switch (bossPosition) {
                    case 0:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(-200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(160, 340);
                        }
                        break;
                    case 1:
                        if (turn%500 < 448) {
                            moveEnemyOnMap(atan2(200, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 449) {
                            enemyFleet[0]->teleport(600, 140);
                        }
                        break;
                    case 2:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(-200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(380, 340);
                        }
                        break;
                    case 3:
                        if (turn%500 < 429) {
                            moveEnemyOnMap(atan2(200, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 430) {
                            enemyFleet[0]->teleport(160, 140);
                        }
                        break;
                    case 4:
                        if (turn%500 < 445) {
                            moveEnemyOnMap(atan2(-100, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 446) {
                            enemyFleet[0]->teleport(600, 240);
                        }
                        break;
                    case 5:
                        if (turn%500 < 444) {
                            moveEnemyOnMap(atan2(0, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 445) {
                            enemyFleet[0]->teleport(160, 240);
                        }
                        break;
                    case 6:
                        if (turn%500 < 445) {
                            moveEnemyOnMap(atan2(-100, 440), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 446) {
                            enemyFleet[0]->teleport(600, 340);
                        }
                        break;
                    case 7:
                        if (turn%500 < 424) {
                            moveEnemyOnMap(atan2(100, -220), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 425) {
                            enemyFleet[0]->teleport(380, 240);
                        }
                        break;
                    case 8:
                        if (turn%500 < 410) {
                            moveEnemyOnMap(atan2(100, 0), 10, enemyFleet[0]);
                        }
                        if (turn%500 == 411) {
                            enemyFleet[0]->teleport(380, 140);
                        }
                        break;
                        
                    default:
                        break;
                }
            }
            
            // This must be synced to the rate of fire
            if (turn%7 == 1) {
                if (floweringBoss) {
                    for (int i = 0; i<lasersOnMap.size(); i++) {
                        if (lasersOnMap[i]->getTurnsInLife() == 10 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()+(pi/2));
                        }
                        if (lasersOnMap[i]->getTurnsInLife() > 10 && lasersOnMap[i]->getTurnsInLife() <= 90 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()+(pi/3));
                        }
                        if (lasersOnMap[i]->getTurnsInLife() == 100 && !lasersOnMap[i]->isSBA()) {
                            lasersOnMap[i]->setAngle(lasersOnMap[i]->getAngle()-(pi/2));
                        }
                    }
                }
                patternTurnsHelper++;
            }
            if (turn%500 == 0 && turn != 0) {
                floweringBoss = !floweringBoss;
                bossPosition = (bossPosition+1)%9;
            }
            
            break;
            
        default:
            break;
    }
}
Пример #2
0
void Engine::protagonistShootsSingleLaser() {
    Laser* tmp = protagonist->shootLaser(pi/2, LASER_ALLIED);
    tmp->setSpeed(20);
    lasersOnMap.push_back(tmp);
}