/* * ORXONOX - the hottest 3D action shooter ever to exist * > www.orxonox.net < * * * License notice: * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: * Leo Merholz * Pascal Schärli * Co-authors: * ... * */ /** @file FlappyOrx.cc @brief Implementation of the FlappyOrx class. */ #include "FlappyOrx.h" #include "Highscore.h" #include "core/CoreIncludes.h" #include "core/EventIncludes.h" #include "core/command/Executor.h" #include "core/config/ConfigValueIncludes.h" #include "core/XMLPort.h" #include "gamestates/GSLevel.h" #include "chat/ChatManager.h" // ! HACK #include "infos/PlayerInfo.h" #include "FlappyOrxShip.h" #include "core/command/ConsoleCommand.h" #include "worldentities/ExplosionPart.h" #include namespace orxonox { RegisterUnloadableClass(FlappyOrx); FlappyOrx::FlappyOrx(Context* context) : Deathmatch(context) { RegisterObject(FlappyOrx); point = 0; //number of cleared tubes bIsDead = true; firstGame = true; //needed for the HUD speedBase = 0; speedIncrease = 0; tubeDistanceBase = 0; tubeDistanceIncrease = 0; tubeDistance = 200.0f; //distance between tubes tubeOffsetX = 500.0f; //tube offset (so that we can't see them spawn) circlesUsed=0; setHUDTemplate("FlappyOrxHUD"); scoreboardTemplate_ = ""; } void FlappyOrx::updatePlayerPos(float x){ //Spawn a new Tube when the spawn distance is reached if(this->tubes.size()==0||x-tubes.back()+tubeOffsetX>tubeDistance){ spawnTube(); this->tubes.push(x+tubeOffsetX); } //Delete Tubes when we pass through them if(this->tubes.size()!=0&&x>this->tubes.front()){ this->tubes.pop(); levelUp(); } //Delete Asteroids which are not visible anymore while(this->asteroids.size()!=0&&(this->asteroids.front())->getPosition().xdestroy(); } } //Gets called when we pass through a Tube void FlappyOrx::levelUp(){ point++; tubeDistance = tubeDistanceBase-tubeDistanceIncrease*point; //smaller spawn Distance getPlayer()->setSpeed(speedBase+speedIncrease*point); //increase speed } //Returns our Ship FlappyOrxShip* FlappyOrx::getPlayer(){ if (player == nullptr){ for (FlappyOrxShip* ship : ObjectList()) { player = ship; } } return player; } //Spawn new Tube void FlappyOrx::spawnTube(){ if (getPlayer() == nullptr) return; float space = 130.0f; //vertical space between top and bottom tube float height = (rnd()-0.5f)*(280.0f-space); //Randomize height Vector3 pos = player->getPosition(); //create the two Asteroid fields (Tubes) asteroidField(pos.x+tubeOffsetX,height-space/2,0.8f); //bottom asteroidField(pos.x+tubeOffsetX,height+space/2,-0.8f); //top } //Creates a new asteroid Field void FlappyOrx::asteroidField(float x, float y, float slope){ float r = 20.0f; //Radius of added Asteroids int noadd = 0; //how many times we failed to add a new asteroid clearCircles(); //Delete Circles (we use circles to make sure we don't spawn two asteroids on top of eachother) Circle newAsteroid = Circle(); newAsteroid.x=x; newAsteroid.y=y; newAsteroid.r=r; addIfPossible(newAsteroid); //Add Asteroid at peak //Fill up triangle with asteroids while(noadd<5&&circlesUsed0) newAsteroid.y=rnd(150+y)-150; //create asteroid on bottom else newAsteroid.y=rnd(150-y)+y; //create asteroid on top newAsteroid.x=x+(rnd()-0.5f)*(y-newAsteroid.y)/slope; newAsteroid.r=r; int i = addIfPossible(newAsteroid); //Add Asteroid if it doesn't collide if(i==0) noadd++; else if(i==2) noadd=5; } } //Create a new Asteroid void FlappyOrx::createAsteroid(Circle &c){ MovableEntity* newAsteroid = new MovableEntity(player->getContext()); //Add Model fitting the Size of the Asteroid if(c.r<=5) newAsteroid->addTemplate(Asteroid5[rand()%NUM_ASTEROIDS]); else if(c.r<=10) newAsteroid->addTemplate(Asteroid10[rand()%NUM_ASTEROIDS]); else if(c.r<=15) newAsteroid->addTemplate(Asteroid15[rand()%NUM_ASTEROIDS]); else newAsteroid->addTemplate(Asteroid20[rand()%NUM_ASTEROIDS]); //Set position newAsteroid->setPosition(Vector3(c.x, 0, c.y)); //Randomize orientation newAsteroid->setOrientation(Vector3::UNIT_Z, Degree(rnd(360))); newAsteroid->setOrientation(Vector3::UNIT_Y, Degree(rnd(360))); //add to Queue (so that we can delete it again) asteroids.push(newAsteroid); } //Deletes Asteroids array which stores all the circles used to make sure no asteroids collide when spawning void FlappyOrx::clearCircles(){ circlesUsed=0; for(int i = 0; icircles[i].r!=0 && c.r>0;i++){ while(circleCollision(c,this->circles[i])){ c.r-=5; //when it collides, try to make it smaller } } if(c.r<=0){ return 0; } circlesUsed++; this->circles[i].x=c.x; this->circles[i].y=c.y; this->circles[i].r=c.r; createAsteroid(c); return 1; } bool FlappyOrx::isDead(){ return bIsDead; } void FlappyOrx::setDead(bool value){ bIsDead = value; if(not value){ point = -1; levelUp(); } } void FlappyOrx::start() { // Set variable to temporarily force the player to spawn. this->bForceSpawn_ = true; // Call start for the parent class. Deathmatch::start(); } //RIP void FlappyOrx::death(){ bIsDead = true; firstGame = false; //Set randomized deathmessages if(point<7) sDeathMessage = DeathMessage7[rand()%(DeathMessage7.size())]; else if(point<20) sDeathMessage = DeathMessage20[rand()%(DeathMessage20.size())]; else if(point<30) sDeathMessage = DeathMessage30[rand()%(DeathMessage30.size())]; else sDeathMessage = DeathMessageover30[rand()%(DeathMessageover30.size())]; //Update Highscore if (Highscore::exists()) { int score = this->getPoints(); Highscore::getInstance().storeScore("Flappy Orx", score, this->getPlayer()->getPlayer()); } //Delete all Tubes and asteroids while (!tubes.empty()){ tubes.pop(); } while (!asteroids.empty()){ MovableEntity* deleteMe = asteroids.front(); asteroids.pop(); deleteMe->destroy(); } } void FlappyOrx::end() { GSLevel::startMainMenu(); } }