diff --git a/Asteroid.h b/Asteroid.h index 2898f98..471f23b 100644 --- a/Asteroid.h +++ b/Asteroid.h @@ -18,10 +18,10 @@ public: return size; } - void hit(vector &animations, Sound &sound, Texture &explosion, default_random_engine &gen) { + void hit(vector &animations, Sound &sound, Texture &explosion, default_random_engine &gen) { uniform_int_distribution angle(0, 359); - animations.push_back(new MySprite(explosion, getSize()*65, getXPos(), getYPos(), 0, angle(gen))); - animations[animations.size() - 1]->makeAnimated(5, 5, 0.01,23); + animations.emplace_back(explosion, getSize()*65, getXPos(), getYPos(), 0, angle(gen)); + animations[animations.size() - 1].makeAnimated(5, 5, 0.01,23); sound.setVolume(100.0/((4-size)/1.5)); sound.play(); diff --git a/Entity.h b/Entity.h index 72e3ffe..c9ed06e 100644 --- a/Entity.h +++ b/Entity.h @@ -5,9 +5,9 @@ #ifndef SFML_TEMPLATE_ENTITY_H #define SFML_TEMPLATE_ENTITY_H -class Entity : public MySprite { +class Entity : public Mount { public: - Entity(int health, int points, const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : MySprite(texture, scale, xPos, yPos, velocity, direction) { + Entity(int health, int points, const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : Mount(texture, scale, xPos, yPos, velocity, direction) { this->health = health; this->points = points; } @@ -22,17 +22,11 @@ public: void hit() {}; - string getType() { - return type; - } - int getPoints() const { return points; } protected: int health, points; - - string type = "entity"; }; diff --git a/Game.h b/Game.h index 50f3b69..d14e668 100644 --- a/Game.h +++ b/Game.h @@ -1,20 +1,78 @@ class Game { public: - int result; + int result, loop; + Time mTime; - Game() { - result = init(); + Game(int loopNum, Time mTime) { + loop = loopNum; + result = init(mTime); } private: bool ended = false; - int init() { + sf::Texture loadingBarEmpty; + sf::Texture loadingBarFull; + + //update total + int totalTextures = 50; + int loadedTextures = 0; + + sf::Font oxan; + + void updateLoader(sf::RenderWindow &window, const std::string& msg = "") { + loadedTextures++; + window.clear(sf::Color::Black); + + //auto start = std::chrono::high_resolution_clock::now(); + MySprite barEmpty(loadingBarEmpty, 100); + MySprite barFull(loadingBarFull, 100); + barFull.setScale(1.1, 0.87); + sf::FloatRect fullBarRect = barFull.getLocalBounds(); + barFull.setOrigin(fullBarRect.width/2.0, fullBarRect.height/2.0); + + barEmpty.setPosition(window.getSize().x/(float)2, window.getSize().y/(float)2); + barFull.setPosition(barEmpty.getPosition().x, barEmpty.getPosition().y); + barFull.setTextureRect(sf::IntRect(fullBarRect.left, fullBarRect.top, fullBarRect.width/(float)totalTextures * (float)loadedTextures, fullBarRect.height)); + + sf::Text loadingMessage(msg, oxan, 15); + loadingMessage.setOrigin(loadingMessage.getGlobalBounds().width/2.0, loadingMessage.getGlobalBounds().height/2.0); + loadingMessage.setPosition(window.getSize().x/2.0, window.getSize().y/2.0 + 50); + + window.draw(barEmpty); + window.draw(barFull); + window.draw(loadingMessage); + + window.display(); + } + + int init(Time mTime) { // display "Hello, World!" -- this still appears in our Run terminal as before cout << "Hello, World!" << endl; - default_random_engine gen(random_device{}()); + default_random_engine gen(std::chrono::system_clock::now().time_since_epoch().count()); Clock fireClock, spawnClock, shieldTimer; + bool poweredUpRapid = false; + Clock rapidFireClock; + + bool poweredUpDamage = false; + Clock damageClock; + + bool poweredUpSpray = false; + Clock sprayFireClock; + + bool poweredUpbackwards = false; + Clock backwardsClock; + + bool poweredUpFighter = false; + Clock fighterClock; + + bool poweredUpTurret = false; + Clock turretClock, turretFireClock; + + bool poweredUpTime = false; + Clock timeClock; + // create a RenderWindow object // specify the size to be 640x640 // set the title to be "SFML Example Window" @@ -22,43 +80,120 @@ private: window.setFramerateLimit(30); window.setPosition(sf::Vector2i(window.getPosition().x, window.getPosition().y - 50)); + //******************************************** + // FONTS + //******************************************** + + oxan.loadFromFile("data/Fonts/Oxanium-Light.ttf"); + updateLoader(window, "Preparing load screen..."); + auto start = std::chrono::high_resolution_clock::now(); + loadingBarEmpty.loadFromFile("data/Gui/LoadingBarEmpty.png"); + updateLoader(window, "Preparing load screen..."); + loadingBarFull.loadFromFile("data/Gui/LoadingBarFull.png"); + updateLoader(window, "Preparing load screen..."); + loadingBarFull.setRepeated(false); + + //******************************************** + // FONTS + //******************************************** + + Font sk; + sk.loadFromFile("data\\Fonts\\Sk.ttf"); + updateLoader(window, "Loading fonts..."); + + Font monkirta; + monkirta.loadFromFile("data\\Fonts\\Monkirta Pursuit NC.ttf"); + updateLoader(window, "Loading fonts..."); + //******************************************** // GRAPHICS //******************************************** Texture ship; ship.loadFromFile("data\\Ship.png"); + updateLoader(window, "Loading textures..."); Texture shield; shield.loadFromFile("data\\bubble.png"); + updateLoader(window, "Loading textures..."); Texture background; background.loadFromFile("data\\back.png"); + updateLoader(window, "Loading textures..."); + + Texture turretGun; + turretGun.loadFromFile("data\\turret.png"); + updateLoader(window, "Loading textures..."); Texture blueLaser; Collision::CreateTextureAndBitmask(blueLaser, "data\\blue.png"); + updateLoader(window, "Loading textures..."); + + Texture greenLaser; + Collision::CreateTextureAndBitmask(greenLaser, "data\\greenLaser.png"); + updateLoader(window, "Loading textures..."); + + Texture redLaser; + Collision::CreateTextureAndBitmask(redLaser, "data\\redLaser.png"); + updateLoader(window, "Loading textures..."); Texture explosion; explosion.loadFromFile("data\\explodeSheet.png"); + updateLoader(window, "Loading textures..."); - vector < Texture * > largeAsteroids; + Texture rapidFire; + rapidFire.loadFromFile("data\\Gui\\rapidFire.png"); + updateLoader(window, "Loading textures..."); + + Texture damage; + damage.loadFromFile("data\\Gui\\damage.png"); + updateLoader(window, "Loading textures..."); + + Texture spray; + spray.loadFromFile("data\\Gui\\spray.png"); + updateLoader(window, "Loading textures..."); + + Texture backwards; + backwards.loadFromFile("data\\Gui\\directions.png"); + updateLoader(window, "Loading textures..."); + + Texture shieldUp; + shieldUp.loadFromFile("data\\Gui\\shield.png"); + updateLoader(window, "Loading textures..."); + + Texture slowTime; + slowTime.loadFromFile("data\\Gui\\slowTime.png"); + updateLoader(window, "Loading textures..."); + + Texture wingman; + wingman.loadFromFile("data\\Gui\\fighter.png"); + updateLoader(window, "Loading textures..."); + + Texture turret; + turret.loadFromFile("data\\Gui\\turret.png"); + updateLoader(window, "Loading textures..."); + + vector < Texture > largeAsteroids; for (int i = 1; i <= 7; i++) { - largeAsteroids.push_back(new Texture); - Collision::CreateTextureAndBitmask(*largeAsteroids[largeAsteroids.size() - 1], + largeAsteroids.emplace_back(); + Collision::CreateTextureAndBitmask(largeAsteroids[largeAsteroids.size() - 1], "data\\Asteroids\\(" + to_string(i) + ").png"); + updateLoader(window, "Loading textures..."); } - vector < Texture * > mediumAsteroids; + vector < Texture > mediumAsteroids; for (int i = 8; i <= 17; i++) { - mediumAsteroids.push_back(new Texture); - Collision::CreateTextureAndBitmask(*mediumAsteroids[mediumAsteroids.size() - 1], + mediumAsteroids.emplace_back(); + Collision::CreateTextureAndBitmask(mediumAsteroids[mediumAsteroids.size() - 1], "data\\Asteroids\\(" + to_string(i) + ").png"); + updateLoader(window, "Loading textures..."); } - vector < Texture * > smallAsteroids; + vector < Texture > smallAsteroids; for (int i = 18; i <= 23; i++) { - smallAsteroids.push_back(new Texture); - Collision::CreateTextureAndBitmask(*smallAsteroids[smallAsteroids.size() - 1], + smallAsteroids.emplace_back(); + Collision::CreateTextureAndBitmask(smallAsteroids[smallAsteroids.size() - 1], "data\\Asteroids\\(" + to_string(i) + ").png"); + updateLoader(window, "Loading textures..."); } //******************************************** @@ -68,36 +203,71 @@ private: Sound pew; SoundBuffer pewBuff; pewBuff.loadFromFile("data\\Sounds\\pew.wav"); + updateLoader(window, "Loading sounds..."); pew.setBuffer(pewBuff); pew.setVolume(25); Sound enemyBoom; SoundBuffer enemyBoomBuff; enemyBoomBuff.loadFromFile("data\\Sounds\\explosions.wav"); + updateLoader(window, "Loading sounds..."); enemyBoom.setBuffer(enemyBoomBuff); + Sound playerBoom; + SoundBuffer playerBoomBuff; + playerBoomBuff.loadFromFile("data\\Sounds\\boom.wav"); + updateLoader(window, "Loading sounds..."); + playerBoom.setBuffer(playerBoomBuff); + + Sound playerLost; + SoundBuffer playerBoomLost; + playerBoomLost.loadFromFile("data\\Sounds\\lost.wav"); + updateLoader(window, "Loading sounds..."); + playerLost.setBuffer(playerBoomLost); + Sound newLife; SoundBuffer newLifeBuff; newLifeBuff.loadFromFile("data\\Sounds\\pling.wav"); + updateLoader(window, "Loading sounds..."); newLife.setBuffer(newLifeBuff); + Sound powerUpSound; + SoundBuffer powerUpBuff; + powerUpBuff.loadFromFile("data\\Sounds\\powerUp.wav"); + updateLoader(window, "Loading sounds..."); + powerUpSound.setBuffer(powerUpBuff); + + sf::Music musicLoop1; + musicLoop1.openFromFile("data/Sounds/Unknown Theme.wav"); + updateLoader(window, "Loading sounds..."); + musicLoop1.setVolume(60); + + sf::Music musicLoop2; + musicLoop2.openFromFile("data/Sounds/loop.wav"); + updateLoader(window, "Loading sounds..."); + + if (loop == 1) { + musicLoop1.setPlayingOffset(mTime); + musicLoop1.play(); + } + else { + musicLoop2.setPlayingOffset(mTime); + musicLoop2.play(); + } + //******************************************** // Text //******************************************** Text score; - Font f; score.setFillColor(Color::White); score.setPosition(10, 10); - f.loadFromFile("data\\Fonts\\arial.ttf"); - score.setFont(f); + score.setFont(oxan); score.setString("Score: 0"); score.setCharacterSize(20); Text destroyed; - Font sk; destroyed.setFillColor(Color::White); - sk.loadFromFile("data\\Fonts\\Sk.ttf"); destroyed.setFont(sk); destroyed.setCharacterSize(70); destroyed.setString("Destroyed"); @@ -105,64 +275,139 @@ private: destroyed.setPosition(window.getSize().x/2.0, window.getSize().y/3.0); Text pressEnter; - Font monkirta; pressEnter.setFillColor(Color::White); - monkirta.loadFromFile("data\\Fonts\\Monkirta Pursuit NC.ttf"); pressEnter.setFont(monkirta); pressEnter.setCharacterSize(20); pressEnter.setString("Press ENTER to return to the menu..."); pressEnter.setOrigin(pressEnter.getGlobalBounds().width/2.0, pressEnter.getGlobalBounds().height/2.0); pressEnter.setPosition(window.getSize().x/2.0, window.getSize().y/2.25); + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start); + std::cout << duration.count() << " milliseconds" << std::endl; + + std::cout << loadedTextures << std::endl; + if (loadedTextures != totalTextures) std::cout << "UPDATE!!!" << std::endl; + //******************************************** // Resource loading above here //******************************************** - vector < MySprite * > projectiles; - vector < MySprite * > animations; + vector < MySprite > projectiles; + vector < MySprite > animations; vector < Entity * > enemies; vector < Drawable * > gui; + vector < MySprite > lives; vector < Drawable * > lost; lost.push_back(&destroyed); lost.push_back(&pressEnter); - gui.push_back(new MySprite(background, 100, window.getSize().x / 2, window.getSize().y / 2, 0, 0)); + MySprite backSprite(background, 100, window.getSize().x / 2, + window.getSize().y / 2, 0, 0); + Ship player(ship, 30, window.getSize().x / 2, window.getSize().y / 2, 0, 0); player.setMaxVelocity(15); player.setMinVelocity(-7); player.setEdgeBehavior(MySprite::EdgeBehavior::LOOP); player.setShield(true, &shield, 12, &shieldTimer); - for (int i = 0; i < player.getLives(); i++) - gui.push_back(new MySprite(ship, 20, window.getSize().x - (i * 40 + 25), 25, 0, 270)); - + gui.push_back(&backSprite); gui.push_back(&score); + for (int i = 0; i < player.getLives(); i++) + lives.emplace_back(ship, 20, window.getSize().x - (i * 40 + 25), 25, 0, 270); + // while our window is open, keep it open // this is our draw loop while (window.isOpen()) { window.clear(Color::Black); // clear the contents of the old frame // by setting the window to black - if (shieldTimer.getElapsedTime().asSeconds() > 5) { - player.setShield(false); - } + if (shieldTimer.getElapsedTime().asSeconds() > 5) player.setShield(false); + if (poweredUpRapid && rapidFireClock.getElapsedTime().asSeconds() > 12) poweredUpRapid = false; + if (poweredUpDamage && damageClock.getElapsedTime().asSeconds() > 12) poweredUpDamage = false; + if (poweredUpSpray && sprayFireClock.getElapsedTime().asSeconds() > 12) poweredUpSpray = false; + if (poweredUpbackwards && backwardsClock.getElapsedTime().asSeconds() > 12) poweredUpbackwards = false; + if (poweredUpFighter && fighterClock.getElapsedTime().asSeconds() > 12) poweredUpFighter = false; + if (poweredUpTurret && turretClock.getElapsedTime().asSeconds() > 12) { + poweredUpTurret = false; + player.removeRider(0); + } if (poweredUpTime && timeClock.getElapsedTime().asSeconds() > 5) poweredUpTime = false; //**************************************** // Handle keypresses below here //**************************************** - if ((Keyboard::isKeyPressed(Keyboard::Up) || Keyboard::isKeyPressed(Keyboard::W))) player.accelerate(0.5); - if ((Keyboard::isKeyPressed(Keyboard::Down) || Keyboard::isKeyPressed(Keyboard::S))) player.accelerate(-.5); - if ((Keyboard::isKeyPressed(Keyboard::Right) || Keyboard::isKeyPressed(Keyboard::D))) player.turn(10); - if ((Keyboard::isKeyPressed(Keyboard::Left) || Keyboard::isKeyPressed(Keyboard::A))) player.turn(-10); - if (Keyboard::isKeyPressed(Keyboard::Space) && fireClock.getElapsedTime().asSeconds() > 0.4) { - player.shoot(&projectiles, pew, blueLaser, 0.3, player.getPosition().x, player.getPosition().y, 20, - player.getDirection()); - fireClock.restart(); + if (!ended) { + if ((Keyboard::isKeyPressed(Keyboard::Up) || Keyboard::isKeyPressed(Keyboard::W))) + player.accelerate(0.5); + if ((Keyboard::isKeyPressed(Keyboard::Down) || Keyboard::isKeyPressed(Keyboard::S))) + player.accelerate(-.5); + if ((Keyboard::isKeyPressed(Keyboard::Right) || Keyboard::isKeyPressed(Keyboard::D))) player.turn(10); + if ((Keyboard::isKeyPressed(Keyboard::Left) || Keyboard::isKeyPressed(Keyboard::A))) player.turn(-10); + if (Keyboard::isKeyPressed(Keyboard::Space) && ((!poweredUpRapid && fireClock.getElapsedTime().asSeconds() > 0.4) || (poweredUpRapid && fireClock.getElapsedTime().asSeconds() > 0.2))) { + if (!poweredUpRapid) + player.shoot(projectiles, pew, blueLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection()); + else + player.shoot(projectiles, pew, greenLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection()); + + if (poweredUpDamage) { + projectiles[projectiles.size() - 1].setType("Damage"); + projectiles[projectiles.size() - 1].setTexture(redLaser); + } + + if (poweredUpbackwards) { + if (!poweredUpRapid) + player.shoot(projectiles, pew, blueLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection() +180); + else + player.shoot(projectiles, pew, greenLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection() +180); + + if (poweredUpDamage) { + projectiles[projectiles.size() - 1].setType("Damage"); + projectiles[projectiles.size() - 1].setTexture(redLaser); + } + } + + if (poweredUpSpray) { + for (int offset = -15; offset <= 15; offset += 30) { + if (!poweredUpRapid) + player.shoot(projectiles, pew, blueLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection() + offset); + else + player.shoot(projectiles, pew, greenLaser, 0.3, player.getPosition().x, + player.getPosition().y, 20, + player.getDirection() + offset); + + if (poweredUpDamage) { + projectiles[projectiles.size() - 1].setType("Damage"); + projectiles[projectiles.size() - 1].setTexture(redLaser); + } + } + } + + fireClock.restart(); + } + } + + if (Keyboard::isKeyPressed(Keyboard::Enter) && ended) { + if (loop == 1) this->mTime = musicLoop1.getPlayingOffset(); + else this->mTime = musicLoop2.getPlayingOffset(); + + musicLoop1.stop(); + musicLoop2.stop(); + + return 0; } - if (Keyboard::isKeyPressed(Keyboard::Enter) && ended) return 0; //**************************************** // Handle keypresses above here @@ -172,7 +417,8 @@ private: // Spawn cycle below here //**************************************** - uniform_int_distribution stroidChance(1, 4), stroidSize(1, 3), + uniform_int_distribution stroidChance(1, 4), powerUpChance(9, 10), + powerUp(7, 8), stroidSize(1, 3), smallTexture(0, smallAsteroids.size() - 1), mediumTexture(0, mediumAsteroids.size() - 1), largeTexture(0, largeAsteroids.size() - 1), side(1, 4), @@ -239,21 +485,60 @@ private: int size = stroidSize(gen); switch (size) { case 1: - enemies.push_back( - new Asteroid(size, size * 100, *smallAsteroids[smallTexture(gen)], scale(gen), x, y, + enemies.push_back(new Asteroid(size, size * 100, smallAsteroids[smallTexture(gen)], scale(gen), x, y, velocity(gen), (360 + angle(gen)) % 360)); break; case 2: - enemies.push_back( - new Asteroid(size, size * 100, *mediumAsteroids[mediumTexture(gen)], scale(gen), x, + enemies.push_back(new Asteroid(size, size * 100, mediumAsteroids[mediumTexture(gen)], scale(gen), x, y, velocity(gen), (360 + angle(gen)) % 360)); break; case 3: - enemies.push_back( - new Asteroid(size, size * 100, *largeAsteroids[largeTexture(gen)], scaleLarge(gen), + enemies.push_back(new Asteroid(size, size * 100, largeAsteroids[largeTexture(gen)], scaleLarge(gen), x, y, velocity(gen), (360 + angle(gen)) % 360)); break; } + + if (size == 3 && powerUpChance(gen) == 10) { + Texture *temp; + string type; + switch (powerUp(gen)) { + case 1: + temp = &rapidFire; + type = "Rapid"; + break; + case 2: + temp = &damage; + type = "Damage"; + break; + case 3: + temp = &spray; + type = "Spray"; + break; + case 4: + temp = &backwards; + type = "Backwards"; + break; + case 5: + temp = &shieldUp; + type = "Shield"; + break; + case 6: + temp = &slowTime; + type = "Time"; + break; + case 7: + temp = &wingman; + type = "Wingman"; + break; + case 8: + temp = &turret; + type = "Turret"; + break; + } + Rider moveEntity(*temp, 25); + moveEntity.setType(type); + enemies[enemies.size() - 1]->addRider(moveEntity); + } } spawnClock.restart(); } @@ -268,10 +553,39 @@ private: player.update(&window); - for (int i = 0; i < projectiles.size(); i++) { - projectiles[i]->update(&window); + if (poweredUpTurret) { + int closest = 0; + for (int i = 1; i < enemies.size(); i++) { + float xDistClosest = enemies[closest]->getXPos() - player.getXPos(); + float yDistClosest = enemies[closest]->getYPos() - player.getYPos(); + float xDistTest = enemies[i]->getXPos() - player.getXPos(); + float yDistTest = enemies[i]->getYPos() - player.getYPos(); + float closeDist = xDistClosest*xDistClosest + yDistClosest*yDistClosest; + float testDist = xDistTest*xDistTest + yDistTest*yDistTest; + //float edgeOffsetClosest = player.getGlobalBounds().width/2 + enemies[closest]->getGlobalBounds().width/2; + //float edgeOffsetTest = player.getGlobalBounds().width/2 + enemies[i]->getGlobalBounds().width/2; - if (projectiles[i]->toBeErased()) { + if ((testDist/* - (edgeOffsetTest*edgeOffsetTest)*/) < (closeDist/* - (edgeOffsetClosest*edgeOffsetClosest)*/) ) + closest = i; + } + + float xDistClosest = enemies[closest]->getXPos() - player.getXPos(); + float yDistClosest = enemies[closest]->getYPos() - player.getYPos(); + + player.getRidersForEdit()->at(0).setDirection(-(180.0/MySprite::PI) * atan2(yDistClosest, xDistClosest)); + + if (turretFireClock.getElapsedTime().asSeconds() > 0.4) { + player.shoot(projectiles, pew, blueLaser, 0.2, player.getPosition().x, + player.getPosition().y, 20, + player.getRiders()[0].getDirection()); + turretFireClock.restart(); + } + } + + for (int i = 0; i < projectiles.size(); i++) { + projectiles[i].update(&window); + + if (projectiles[i].toBeErased()) { projectiles.erase(projectiles.begin() + i); } } @@ -280,25 +594,63 @@ private: enemies[i]->update(&window); if (enemies[i]->toBeErased()) { + delete enemies[i]; enemies.erase(enemies.begin() + i); } } for (int i = 0; i < enemies.size(); i++) { for (int j = 0; j < projectiles.size(); j++) { - if (Collision::PixelPerfectTest(*enemies[i], *projectiles[j], 0)) { + if (Collision::PixelPerfectTest(*enemies[i], projectiles[j], 0)) { uniform_int_distribution angle(0, 359); - enemies[i]->setHealth(enemies[i]->getHealth() - 1); + if (projectiles[j].getType() != "Damage") enemies[i]->setHealth(enemies[i]->getHealth() - 1); + else enemies[i]->setHealth(enemies[i]->getHealth() - 2); if (enemies[i]->getHealth() <= 0) { if (enemies[i]->getType() == "asteroid") - ((Asteroid *) enemies[i])->hit(animations, enemyBoom, explosion, gen); + ((Asteroid *)enemies[i])->hit(animations, enemyBoom, explosion, gen); player.setScore(player.getScore() + enemies[i]->getPoints()); + + if (enemies[i]->hasRider()) { + powerUpSound.play(); + + if (enemies[i]->getRiders()[0].getType() == "Rapid") { + poweredUpRapid = true; + rapidFireClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Damage") { + poweredUpDamage = true; + damageClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Spray") { + poweredUpSpray = true; + sprayFireClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Backwards") { + poweredUpbackwards = true; + backwardsClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Fighter") { + poweredUpFighter = true; + fighterClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Turret") { + if (!poweredUpTurret) { + Rider temp(turretGun, 20); + player.addRider(temp, 0); + } + + poweredUpTurret = true; + turretClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Time") { + poweredUpTime = true; + timeClock.restart(); + } else if (enemies[i]->getRiders()[0].getType() == "Shield") { + shieldTimer.restart(); + player.setShield(true, &shield, 12, &shieldTimer); + } + } + + delete enemies[i]; enemies.erase(enemies.begin() + i); } else { - animations.push_back( - new MySprite(explosion, 20, projectiles[j]->getXPos(), projectiles[j]->getYPos(), 0, - angle(gen))); - animations[animations.size() - 1]->makeAnimated(5, 5, 0.01, 23); + animations.emplace_back(explosion, 20, projectiles[j].getXPos(), projectiles[j].getYPos(), 0, + angle(gen)); + animations[animations.size() - 1].makeAnimated(5, 5, 0.01, 23); } projectiles.erase(projectiles.begin() + j); @@ -307,29 +659,38 @@ private: } for (int i = 0; i < enemies.size(); i++) { - if (player.hasShield() && Collision::CircleTest(*enemies[i], *player.getRider().sprite)) { - if (enemies[i]->getType() == "asteroid") - ((Asteroid *) enemies[i])->hit(animations, enemyBoom, explosion, gen); - enemies.erase(enemies.begin() + i); - } else if (Collision::CircleTest(*enemies[i], player)) { - if (!ended && player.hit(window, animations, explosion, gen, shield, 12, shieldTimer)) { - ended = true; + if (!ended && player.hasShield()) { + int shieldIndex; + if (poweredUpTurret) shieldIndex = 1; + else shieldIndex = 0; + + if (Collision::CircleTest(*enemies[i], player.getRiders()[shieldIndex])) { + if (enemies[i]->getType() == "asteroid") + ((Asteroid *) enemies[i])->hit(animations, enemyBoom, explosion, gen); + delete enemies[i]; + enemies.erase(enemies.begin() + i); } - gui.erase(gui.begin() + player.getLives() + 1); //remove player icon from top corner + } else if (!ended && Collision::CircleTest(*enemies[i], player)) { + if (player.hit(window, animations, explosion, gen, shield, 12, shieldTimer)) { + ended = true; + playerLost.play(); + } else playerBoom.play(); + lives.erase(lives.begin() + player.getLives()); //remove player icon from top corner } } for (int i = 0; i < animations.size(); i++) { - animations[i]->update(&window); - if (animations[i]->getAnimation().isPlayed) + animations[i].update(&window); + if (animations[i].getAnimation().isPlayed) { animations.erase(animations.begin() + i); + } } score.setString("Score: " + to_string(player.getScore())); if (player.getScore() - (player.getNewLifeScore() * player.getNumLivesAdded()) >= player.getNewLifeScore()) { - player.newLife(gui, ship, window, newLife); + player.newLife(lives, ship, window, newLife); } //**************************************** @@ -342,32 +703,55 @@ private: window.draw(*gui[0]); //draw background - for (int i = 0; i < projectiles.size(); i++) - window.draw(*projectiles[i]); - for (int i = 0; i < enemies.size(); i++) - window.draw(*enemies[i]); + for (const auto & projectile : projectiles) + window.draw(projectile); + for (const auto & enemy : enemies){ + window.draw(*enemy); + if (enemy->hasRider()) { + for (const auto& r : enemy->getRiders()) { + window.draw(r); + } + } + } - for (MySprite *a : animations) - window.draw(*a); + for (const MySprite& a : animations) + window.draw(a); if (!ended) { window.draw(player); - if (player.getRider().sprite != nullptr) - window.draw(*player.getRider().sprite); + if (player.hasRider()) { + for (const auto& r : player.getRiders()) { + window.draw(r); + } + } } else { - for (auto d : lost) window.draw(*d); + for (auto & i : lost) window.draw(*i); } for (int i = 1; i < gui.size(); i++) { window.draw(*gui[i]); } + + for (auto i: lives) { + window.draw(i); + } //**************************************** // ADD ALL OF OUR DRAWING ABOVE HERE //**************************************** window.display(); // display the window + if (loop == 1 && musicLoop1.getStatus() == Music::Stopped) { + musicLoop2.setPlayingOffset(Time::Zero); + musicLoop2.play(); + loop = 2; + } else if (loop == 2 && musicLoop2.getStatus() == Music::Stopped) { + musicLoop1.setPlayingOffset(Time::Zero); + musicLoop1.play(); + loop = 1; + } + //**************************************** // HANDLE EVENTS BELOW HERE //**************************************** diff --git a/Menu.h b/Menu.h index 786cceb..8429e4d 100644 --- a/Menu.h +++ b/Menu.h @@ -11,18 +11,21 @@ class Menu { public: - int result; + int result, musicPicked = 0; bool soundOn = true, musicOn = true; - Menu() { - result = init(); + Time mTime; + + Menu(int loop, Time time) { + musicPicked = loop; + result = init(time); } private: sf::SoundBuffer bip; sf::Sound bipSound; bool playedBip = false; - int init() { + int init(Time time) { const int MENU = 0, CREDITS = 1; int screen = 0; @@ -85,10 +88,26 @@ private: sf::Texture initials; initials.loadFromFile("data/Morgan Ben initials.png"); - sf::Music menuLoop; - menuLoop.openFromFile("data/Sounds/Unknown Theme.wav"); - menuLoop.setLoop(true); - menuLoop.play(); + if (musicPicked == 0) { + default_random_engine gen(std::chrono::system_clock::now().time_since_epoch().count()); + uniform_int_distribution loopPicker(1, 2); + musicPicked = loopPicker(gen); + } + + sf::Music menuLoop1; + menuLoop1.openFromFile("data/Sounds/Unknown Theme.wav"); + menuLoop1.setVolume(60); + + sf::Music menuLoop2; + menuLoop2.openFromFile("data/Sounds/loop.wav"); + + if (musicPicked == 1) { + menuLoop1.setPlayingOffset(time); + menuLoop1.play(); + } else { + menuLoop2.setPlayingOffset(time); + menuLoop2.play(); + } bip.loadFromFile("data/Sounds/rollover.wav"); @@ -248,6 +267,7 @@ private: sf::Text devText1("ben@benrmorgan.com", oxan, 12); devText1.setPosition(mainView.getSize().x/(float)11.5 + devLabel1.getGlobalBounds().width, mainView.getSize().y/(float)3.05); devText1.setFillColor(sf::Color::White); + devText1.setStyle(sf::Text::Style::Underlined); sf::Text devLabel2("Repo - ", monkirta, 15); devLabel2.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)2.87); @@ -367,6 +387,16 @@ private: window.display(); // display the window + if (musicPicked == 1 && menuLoop1.getStatus() == Music::Stopped) { + menuLoop2.setPlayingOffset(Time::Zero); + menuLoop2.play(); + musicPicked = 2; + } else if (musicPicked == 2 && menuLoop2.getStatus() == Music::Stopped) { + menuLoop1.setPlayingOffset(Time::Zero); + menuLoop1.play(); + musicPicked = 1; + } + sf::Event event{}; while( window.pollEvent(event) ) { // ask the window if any events occurred @@ -386,22 +416,32 @@ private: return EXIT_FAILURE; } else if (startButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { playBip(); + + if (musicPicked == 1) mTime = menuLoop1.getPlayingOffset(); + else mTime = menuLoop2.getPlayingOffset(); + + menuLoop1.stop(); + menuLoop2.stop(); + return EXIT_SUCCESS; } else if (creditsButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { playBip(); screen = CREDITS; } else if (issueButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { playBip(); - ShellExecute(nullptr, "open", "https://github.com/bMorgan01/StarCap/issues", nullptr, nullptr, SW_SHOWNORMAL); + ShellExecute(nullptr, "open", "https://github.com/bMorgan01/Asteroids/issues", nullptr, nullptr, SW_SHOWNORMAL); } else if (devText.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { playBip(); ShellExecute(nullptr, "open", "https://www.benrmorgan.com", nullptr, nullptr, SW_SHOWNORMAL); } else if (devText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { playBip(); ShellExecute(nullptr, "open", "https://github.com/bMorgan01", nullptr, nullptr, SW_SHOWNORMAL); + } else if (devText1.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "mailto:ben@benrmorgan.com", nullptr, nullptr, SW_SHOWNORMAL); } else if (devText2.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { playBip(); - ShellExecute(nullptr, "open", "https://github.com/bMorgan01/StarCap", nullptr, nullptr, SW_SHOWNORMAL); + ShellExecute(nullptr, "open", "https://github.com/bMorgan01/Asteroids", nullptr, nullptr, SW_SHOWNORMAL); } else if (musicText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { playBip(); ShellExecute(nullptr, "open", "https://www.instagram.com/river.schreck/", nullptr, nullptr, SW_SHOWNORMAL); @@ -417,8 +457,13 @@ private: } else if (musicButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { playBip(); musicOn = !musicOn; - if (!musicOn) menuLoop.setVolume(0); - else menuLoop.setVolume(100); + if (!musicOn) { + menuLoop1.setVolume(0); + menuLoop2.setVolume(0); + } else { + menuLoop1.setVolume(60); + menuLoop2.setVolume(100); + } } break; case sf::Event::MouseMoved: @@ -428,6 +473,7 @@ private: else if (issueButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) issueButton.setColor(sf::Color::Green); else if (devText.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText.setFillColor(sf::Color::Red); else if (devText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText0.setFillColor(sf::Color::Red); + else if (devText1.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText1.setFillColor(sf::Color::Red); else if (devText2.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText2.setFillColor(sf::Color::Red); else if (musicText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) musicText0.setFillColor(sf::Color::Red); else if (musicText1.getGlobalBounds().contains(mousePosF) && screen == CREDITS) musicText1.setFillColor(sf::Color::Red); @@ -445,6 +491,7 @@ private: if (!issueButton.getGlobalBounds().contains(mousePosF)) issueButton.setColor(sf::Color::Red); if (!devText.getGlobalBounds().contains(mousePosF)) devText.setFillColor(sf::Color::White); if (!devText0.getGlobalBounds().contains(mousePosF)) devText0.setFillColor(sf::Color::White); + if (!devText1.getGlobalBounds().contains(mousePosF)) devText1.setFillColor(sf::Color::White); if (!devText2.getGlobalBounds().contains(mousePosF)) devText2.setFillColor(sf::Color::White); if (!musicText0.getGlobalBounds().contains(mousePosF)) musicText0.setFillColor(sf::Color::White); if (!musicText1.getGlobalBounds().contains(mousePosF)) musicText1.setFillColor(sf::Color::White); diff --git a/Mount.h b/Mount.h new file mode 100644 index 0000000..4d986d2 --- /dev/null +++ b/Mount.h @@ -0,0 +1,47 @@ +// +// Created by benmo on 10/12/2020. +// + +#ifndef SFML_TEMPLATE_MOUNT_H +#define SFML_TEMPLATE_MOUNT_H + + +class Mount : public MySprite { +protected: + vector riders; +public: + Mount(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : MySprite(texture, scale, xPos, yPos, velocity, direction) {} + + bool hasRider() { + return !riders.empty(); + } + void update(RenderWindow* window = nullptr) { + MySprite::update(window); + + for (Rider &r : riders) { + if (r.doesFollowPosition()) r.setPosition(getPosition()); + if (r.doesFollowDirection()) r.setDirection(getDirection()); + } + } + + void addRider(Rider &sprite, int index = -1) { + if (index == -1) riders.push_back(sprite); + else riders.insert(riders.begin() + index, sprite); + } + + void removeRider(int index = -1) { + if (index == -1) riders.pop_back(); + else riders.erase(riders.begin() + index); + } + + vector getRiders() { + return riders; + } + + vector* getRidersForEdit() { + return &riders; + } +}; + + +#endif //SFML_TEMPLATE_MOUNT_H diff --git a/MySprite.h b/MySprite.h index 5f2b671..4d69420 100644 --- a/MySprite.h +++ b/MySprite.h @@ -27,18 +27,13 @@ protected: IntRect textureRect; }; - struct Rider { - MySprite* sprite; - bool followsDirection = false, followsPosition = true; - }; - Physics spritePhysics{}; Animation spriteAnimation{}; - Rider spriteRider{}; - bool toErase = false, circularHitbox = false; + + string type = "Sprite"; public: enum EdgeBehavior { IGNORE, LOOP, BOUNCE @@ -164,9 +159,9 @@ public: setOrigin(spriteAnimation.width/2.0, spriteAnimation.height/2.0); } - void update(RenderWindow* window = nullptr) { - spritePhysics.xPos += cos(spritePhysics.direction * (PI/180)) * spritePhysics.velocity; - spritePhysics.yPos += -(sin(spritePhysics.direction * (PI/180)) * spritePhysics.velocity); + virtual void update(RenderWindow* window = nullptr) { + spritePhysics.xPos += cos(spritePhysics.direction * (PI/180.0)) * spritePhysics.velocity; + spritePhysics.yPos += -(sin(spritePhysics.direction * (PI/180.0)) * spritePhysics.velocity); if (edgeBehavior == LOOP) { if (spritePhysics.xPos <= -getGlobalBounds().width) @@ -215,12 +210,6 @@ public: } } - if (spriteRider.sprite != nullptr) { - if (spriteRider.followsPosition) spriteRider.sprite->setPosition(spritePhysics.xPos, spritePhysics.yPos); - - if (spriteRider.followsDirection) spriteRider.sprite->setDirection(spritePhysics.direction); - } - setPosition(spritePhysics.xPos, spritePhysics.yPos); setRotation(-spritePhysics.direction); } @@ -311,17 +300,17 @@ public: return toErase; } - void setRider(MySprite* sprite) { - spriteRider.sprite = sprite; - } - - Rider getRider() { - return spriteRider; - } - Animation getAnimation() { return spriteAnimation; } + + string getType() { + return type; + } + + void setType(string type) { + this->type = std::move(type); + } }; diff --git a/Rider.h b/Rider.h new file mode 100644 index 0000000..ee87e88 --- /dev/null +++ b/Rider.h @@ -0,0 +1,25 @@ +// +// Created by benmo on 10/13/2020. +// + +#ifndef SFML_TEMPLATE_RIDER_H +#define SFML_TEMPLATE_RIDER_H + + +class Rider : public MySprite { +protected: + bool followsDirection = false, followsPosition = true; +public: + Rider(const sf::Texture &texture, float scale) : MySprite(texture, scale) {} + + bool doesFollowDirection() const { + return followsDirection; + } + + bool doesFollowPosition() const { + return followsPosition; + } +}; + + +#endif //SFML_TEMPLATE_RIDER_H diff --git a/Ship.h b/Ship.h index 4ab4bbf..6cc0ffa 100644 --- a/Ship.h +++ b/Ship.h @@ -6,19 +6,19 @@ #define SFML_TEMPLATE_SHIP_H -class Ship : public MySprite { +class Ship : public Mount { public: - Ship(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : MySprite(texture, scale, xPos, yPos, velocity, direction) {} + Ship(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : Mount(texture, scale, xPos, yPos, velocity, direction) {} - static void shoot(std::vector* projectiles, Sound &sound, sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) { - projectiles->push_back(new MySprite(texture, scale, xPos, yPos, velocity, direction)); + void shoot(std::vector &projectiles, Sound &sound, sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) { + projectiles.emplace_back(texture, scale, xPos, yPos, velocity, direction); sound.play(); } - bool hit(RenderWindow &window, vector &animations, Texture &explosionTexture, default_random_engine &gen, Texture &shieldTexture, int scale, Clock &timer) { + bool hit(RenderWindow &window, vector &animations, Texture &explosionTexture, default_random_engine &gen, Texture &shieldTexture, int scale, Clock &timer) { uniform_int_distribution angle(0, 359); - animations.push_back(new MySprite(explosionTexture, 100, getXPos(), getYPos(), 0, angle(gen))); - animations[animations.size() - 1]->makeAnimated(5, 5, 0.01,23); + animations.emplace_back(explosionTexture, 100, getXPos(), getYPos(), 0, angle(gen)); + animations[animations.size() - 1].makeAnimated(5, 5, 0.01,23); setPosition(window.getSize().x/2, window.getSize().y/2); setDirection(0); @@ -29,10 +29,10 @@ public: return lives <= 0; } - void newLife(vector &gui, Texture &life, RenderWindow &window, Sound &sound) { + void newLife(vector &lifeVec, Texture &life, RenderWindow &window, Sound &sound) { setNumLivesAdded(getNumLivesAdded() + 1); setLives(getLives() + 1); - gui.insert(gui.begin() + getLives(),new MySprite(life, 20, window.getSize().x - ((getLives()-1)*40 + 25), 25, 0, 270)); + lifeVec.emplace_back(life, 20,window.getSize().x - ((getLives() - 1) * 40 + 25), 25, 0,270); sound.play(); } @@ -44,14 +44,19 @@ public: this->lives = lives; } - void setShield(bool shield, Texture* texture = nullptr, int scale = 0, Clock* timer = nullptr) { + void setShield(bool shield, Texture* texture = nullptr, float scale = 0, Clock* timer = nullptr) { this->shield = shield; if (shield) { - setRider(new MySprite(*texture, scale)); + Rider temp(*texture, scale); + temp.setType("Shield"); + addRider(temp); timer->restart(); - } else - setRider(nullptr); + } else { + for (int i = 0; i < riders.size(); i++) { + if (riders[i].getType() == "Shield") removeRider(i); + } + } } bool hasShield() const { diff --git a/data/Gui/Bonus_BTN_02.png b/data/Gui/Bonus_BTN_02.png new file mode 100644 index 0000000..9b19df5 Binary files /dev/null and b/data/Gui/Bonus_BTN_02.png differ diff --git a/data/Gui/Hangar_BTN.png b/data/Gui/Hangar_BTN.png new file mode 100644 index 0000000..d1e9703 Binary files /dev/null and b/data/Gui/Hangar_BTN.png differ diff --git a/data/Gui/arrow.png b/data/Gui/arrow.png deleted file mode 100644 index ffade9a..0000000 Binary files a/data/Gui/arrow.png and /dev/null differ diff --git a/data/Gui/ball.png b/data/Gui/ball.png deleted file mode 100644 index 3d707e5..0000000 Binary files a/data/Gui/ball.png and /dev/null differ diff --git a/data/Gui/damage.png b/data/Gui/damage.png new file mode 100644 index 0000000..7166a3c Binary files /dev/null and b/data/Gui/damage.png differ diff --git a/data/Gui/directions.png b/data/Gui/directions.png new file mode 100644 index 0000000..63aa4da Binary files /dev/null and b/data/Gui/directions.png differ diff --git a/data/Gui/fighter.png b/data/Gui/fighter.png new file mode 100644 index 0000000..edb3cd1 Binary files /dev/null and b/data/Gui/fighter.png differ diff --git a/data/Gui/filter.xcf b/data/Gui/filter.xcf deleted file mode 100644 index ead01df..0000000 Binary files a/data/Gui/filter.xcf and /dev/null differ diff --git a/data/Gui/mapBox.png b/data/Gui/mapBox.png deleted file mode 100644 index 431ec92..0000000 Binary files a/data/Gui/mapBox.png and /dev/null differ diff --git a/data/Gui/planetDialog.xcf b/data/Gui/planetDialog.xcf deleted file mode 100644 index 45a42b7..0000000 Binary files a/data/Gui/planetDialog.xcf and /dev/null differ diff --git a/data/Gui/rapidFire.png b/data/Gui/rapidFire.png new file mode 100644 index 0000000..6ee848c Binary files /dev/null and b/data/Gui/rapidFire.png differ diff --git a/data/Gui/shield.png b/data/Gui/shield.png new file mode 100644 index 0000000..fd9a95a Binary files /dev/null and b/data/Gui/shield.png differ diff --git a/data/Gui/slowTime.png b/data/Gui/slowTime.png new file mode 100644 index 0000000..c1b1c8b Binary files /dev/null and b/data/Gui/slowTime.png differ diff --git a/data/Gui/space.xcf b/data/Gui/space.xcf deleted file mode 100644 index ac39d9a..0000000 Binary files a/data/Gui/space.xcf and /dev/null differ diff --git a/data/Gui/spray.png b/data/Gui/spray.png new file mode 100644 index 0000000..9d00055 Binary files /dev/null and b/data/Gui/spray.png differ diff --git a/data/Gui/turret.png b/data/Gui/turret.png new file mode 100644 index 0000000..4fbc162 Binary files /dev/null and b/data/Gui/turret.png differ diff --git a/data/Gui/unexplored.png b/data/Gui/unexplored.png deleted file mode 100644 index 7f14cae..0000000 Binary files a/data/Gui/unexplored.png and /dev/null differ diff --git a/data/Gui/unexplored.xcf b/data/Gui/unexplored.xcf deleted file mode 100644 index 1697c0f..0000000 Binary files a/data/Gui/unexplored.xcf and /dev/null differ diff --git a/data/Ship_Main_Icon.png b/data/Ship_Main_Icon.png new file mode 100644 index 0000000..fe0dc60 Binary files /dev/null and b/data/Ship_Main_Icon.png differ diff --git a/data/Sounds/boom.wav b/data/Sounds/boom.wav new file mode 100644 index 0000000..e382783 Binary files /dev/null and b/data/Sounds/boom.wav differ diff --git a/data/Sounds/loop.wav b/data/Sounds/loop.wav new file mode 100644 index 0000000..1e1e4ef Binary files /dev/null and b/data/Sounds/loop.wav differ diff --git a/data/Sounds/lost.wav b/data/Sounds/lost.wav new file mode 100644 index 0000000..e628489 Binary files /dev/null and b/data/Sounds/lost.wav differ diff --git a/data/Sounds/powerUp.wav b/data/Sounds/powerUp.wav new file mode 100644 index 0000000..a2f9cd5 Binary files /dev/null and b/data/Sounds/powerUp.wav differ diff --git a/data/greenLaser.png b/data/greenLaser.png new file mode 100644 index 0000000..781d324 Binary files /dev/null and b/data/greenLaser.png differ diff --git a/data/redLaser.png b/data/redLaser.png new file mode 100644 index 0000000..c35cc9e Binary files /dev/null and b/data/redLaser.png differ diff --git a/data/turret.png b/data/turret.png new file mode 100644 index 0000000..d53d11e Binary files /dev/null and b/data/turret.png differ diff --git a/main.cpp b/main.cpp index 4507d5a..e592695 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include // for standard input/output #include +#include using namespace std; // using the standard namespace #include // include the SFML Graphics Library @@ -8,6 +9,8 @@ using namespace std; // using the standard namespace using namespace sf; // using the sf namespace #include "MySprite.h" +#include "Rider.h" +#include "Mount.h" #include "Ship.h" #include "Asteroid.h" #include "Menu.h" @@ -15,12 +18,17 @@ using namespace sf; // using the sf namespace int main() { bool play = true; + Time mTime = Time::Zero; + int loop = 0; while (play) { - Menu menu; + Menu menu(loop, mTime); if (menu.result == EXIT_SUCCESS) { - Game game; + Game game(menu.musicPicked, menu.mTime); if (game.result == 1) play = false; + + loop = game.loop; + mTime = game.mTime; } else play = false; }