206 lines
6.3 KiB
C++
206 lines
6.3 KiB
C++
#include "Game.hpp"
|
|
#include "AudioEmitter.hpp"
|
|
#include "GameData.hpp"
|
|
#include "NoteSprite.hpp"
|
|
#include "NoteTile.hpp"
|
|
#include "TilePattern.hpp"
|
|
#include <SFML/Graphics/Color.hpp>
|
|
#include <SFML/Graphics/Rect.hpp>
|
|
#include <SFML/Graphics/RectangleShape.hpp>
|
|
#include <SFML/Graphics/Sprite.hpp>
|
|
#include <SFML/Graphics/Texture.hpp>
|
|
#include <SFML/System/Vector2.hpp>
|
|
#include <SFML/Window/Keyboard.hpp>
|
|
#include <format>
|
|
#include <iostream>
|
|
#include <math.h>
|
|
#include <string>
|
|
|
|
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<sf::Event::Closed>()) {
|
|
mWindow.close();
|
|
break;
|
|
}
|
|
if (const auto *keyPressed = event->getIf<sf::Event::KeyPressed>()) {
|
|
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);
|
|
}
|
|
}
|