#include "Game.hpp" #include "AudioEmitter.hpp" #include "GameData.hpp" #include "NoteSprite.hpp" #include "NoteTile.hpp" #include "TilePattern.hpp" #include #include #include #include #include #include #include #include #include #include #include const sf::Time Game::TimePerFrame = sf::seconds(1.f / 60.f); sf::Texture bgTexture; sf::Texture paperTexture; sf::Texture endScreenTexture; Game::Game() : backGround(PLACE_HOLDER_TEXTURE), paper(PLACE_HOLDER_TEXTURE), endScreen(PLACE_HOLDER_TEXTURE), carrot(ANGRY_PATHS, NEUTRAL_PATHS, HAPPY_PATHS, mFont) { assert(mFont.openFromFile("media/Sansation.ttf")); mStatisticsText.setPosition({5.f, 5.f}); mStatisticsText.setCharacterSize(10); leftPressZone = sf::RectangleShape(sf::Vector2f(50, 10)); middlePressZone = sf::RectangleShape(sf::Vector2f(50, 10)); rightPressZone = sf::RectangleShape(sf::Vector2f(50, 10)); leftPressZone.setPosition( sf::Vector2f(NOTE_PLACE_X_POS[0], NOTE_PRESS_HEIGHT)); middlePressZone.setPosition( sf::Vector2f(NOTE_PLACE_X_POS[1], NOTE_PRESS_HEIGHT)); rightPressZone.setPosition( sf::Vector2f(NOTE_PLACE_X_POS[2], NOTE_PRESS_HEIGHT)); leftPressZone.setFillColor(sf::Color::Black); middlePressZone.setFillColor(sf::Color::Black); rightPressZone.setFillColor(sf::Color::Black); leftPressZone.setOrigin(leftPressZone.getSize() * 0.5f); middlePressZone.setOrigin(middlePressZone.getSize() * 0.5f); rightPressZone.setOrigin(rightPressZone.getSize() * 0.5f); ScoreText.setPosition({SCREEN_WIDTH - 150, 70}); ScoreText.setFillColor(sf::Color::Black); ScoreText.setCharacterSize(40); ScoreMultiplierText.setPosition({SCREEN_WIDTH - 100, 25}); ScoreMultiplierText.setFillColor(sf::Color::Black); ScoreMultiplierText.setCharacterSize(40); if (!bgTexture.loadFromFile("media/sprites/bureau.png")) { printf("sprite bureau not loaded\n"); } backGround.setTexture(bgTexture, true); float sx = backGround.getTexture().getSize().x; float sy = backGround.getTexture().getSize().y; backGround.setScale(sf::Vector2f(SCREEN_WIDTH / sx, SCREEN_HEIGHT / sy)); if (!endScreenTexture.loadFromFile("media/sprites/end_screen.png")) { printf("sprite end_screen not loaded\n"); } endScreen.setTexture(endScreenTexture, true); endScreen.setScale(sf::Vector2f(SCREEN_WIDTH / sx, SCREEN_HEIGHT / sy)); if (!paperTexture.loadFromFile("media/sprites/feuille.png")) { printf("paper not loaded\n"); } paper.setPosition(PAPER_POS); paper.setTexture(paperTexture, true); paper.setScale(sf::Vector2f(SCREEN_WIDTH / sx, SCREEN_HEIGHT / sy)); paper.setTextureRect(sf::IntRect( sf::Vector2i(0, 0), sf::Vector2i(paper.getTexture().getSize().x, 0))); carrot.setPosition(CARROT_POS); carrot.setScale(sf::Vector2f(5, 5)); carrot.setTextPosition(CARROT_TEXT_POS); carrot.setTextCharacterSize(30); carrot.setTextFillColor(sf::Color::Black); } void generateTilePatternAndMusic(AudioEmitter &audio_emitter) { generateTilePattern(audio_emitter.generateMusic(), audio_emitter); } bool updateAudio(AudioEmitter &audioEmitter, bool generated) { if (32.f - fmod(audioEmitter.getTimeTempo(), 32.f) < audioEmitter.timeBeforeNewGeneration) { if (!generated) { generateTilePatternAndMusic(audioEmitter); generated = true; } } else { generated = false; } return generated; } int nb_melo_total; float tempo; void Game::run() { AudioEmitter audioEmitter = AudioEmitter(); nb_melo_total = audioEmitter.nbr_melo_total; tempo = audioEmitter.tempo; generateTilePatternAndMusic(audioEmitter); bool generated = false; mWindow.setFramerateLimit(60); while (mWindow.isOpen()) { render(); generated = updateAudio(audioEmitter, generated); processEvents(audioEmitter); audioEmitter.audioUpdate(); update(TimePerFrame); } } void Game::processEvents(AudioEmitter &audioEmitter) { while (const std::optional event = mWindow.pollEvent()) { if (event->is()) { mWindow.close(); break; } if (const auto *keyPressed = event->getIf()) { sf::Keyboard::Scancode key_scan_code = keyPressed->scancode; switch (key_scan_code) { case sf::Keyboard::Scancode::Left: update_scores( NoteTile::checkPress(audioEmitter.getTime(), NotePlaceEnum::Left)); break; case sf::Keyboard::Scancode::Up: update_scores(NoteTile::checkPress(audioEmitter.getTime(), NotePlaceEnum::Middle)); break; case sf::Keyboard::Scancode::Right: update_scores( NoteTile::checkPress(audioEmitter.getTime(), NotePlaceEnum::Right)); break; } } } } float totalTime = 0.0f; void Game::update(const sf::Time elapsedTime) { float maxTime = nb_melo_total * 8 * 60 / tempo; int paperAdvancement = paper.getTexture().getSize().y * totalTime / maxTime; paper.setTextureRect(sf::IntRect( sf::Vector2i(0, 0), sf::Vector2i(paper.getTexture().getSize().x, paperAdvancement))); totalTime += elapsedTime.asSeconds(); } void Game::render() { mWindow.clear(sf::Color::Yellow); mWindow.draw(backGround); mWindow.draw(paper); mWindow.draw(leftPressZone); mWindow.draw(middlePressZone); mWindow.draw(rightPressZone); carrot.draw(mWindow, TimePerFrame.asSeconds()); if (!NoteTile::update(TimePerFrame.asSeconds(), mWindow)) update_scores(false); if (NoteTile::isFinished()) { mWindow.draw(endScreen); } carrot.handleText(mWindow, TimePerFrame.asSeconds()); mWindow.draw(mStatisticsText); mWindow.draw(ScoreText); mWindow.draw(ScoreMultiplierText); mWindow.display(); } void Game::update_scores(bool good_action) { if (good_action) { score += score_multiplier; score_multiplier++; } else { score_multiplier = 1; } ScoreText.setString(std::format("{}pts", score)); ScoreMultiplierText.setString(std::format("{}x", score_multiplier)); if (score_multiplier < 5) { carrot.changeState(Angry); } else if (score_multiplier < 15) { carrot.changeState(Neutral); } else { carrot.changeState(Happy); } }