init
This commit is contained in:
commit
f698a38c7e
585 changed files with 118338 additions and 0 deletions
46
SimpleGame/src/CMakeLists.txt
Normal file
46
SimpleGame/src/CMakeLists.txt
Normal file
|
@ -0,0 +1,46 @@
|
|||
cmake_minimum_required(VERSION 3.26)
|
||||
project(simpleGame)
|
||||
|
||||
if(WIN32)
|
||||
message(STATUS "Platform: Windows")
|
||||
set(FMOD_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../fmodwindow")
|
||||
set(CPU_THING "x64")
|
||||
set(FMOD_LIB_NAME "fmod_vc")
|
||||
set(FMOD_DLL_NAME "fmod.dll")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
message(STATUS "Platform: Linux")
|
||||
set(FMOD_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../fmodstudioapi20307linux")
|
||||
set(CPU_THING "x86_64")
|
||||
set(FMOD_LIB_NAME "fmod")
|
||||
set(FMOD_DLL_NAME "libfmod.so")
|
||||
else()
|
||||
message(FATAL_ERROR "Platform not supported, please update the CMake script.")
|
||||
endif()
|
||||
|
||||
add_executable(simpleGame
|
||||
Source/Game.cpp Include/Game.hpp Source/Main.cpp
|
||||
Source/RoundTarget.cpp Include/RoundTarget.hpp
|
||||
Source/AudioEmitter.cpp Include/AudioEmitter.hpp
|
||||
)
|
||||
|
||||
target_include_directories(simpleGame PRIVATE
|
||||
"Include"
|
||||
"${FMOD_PATH}/api/core/inc"
|
||||
)
|
||||
|
||||
target_link_directories(simpleGame PRIVATE
|
||||
"${FMOD_PATH}/api/core/lib/${CPU_THING}"
|
||||
)
|
||||
|
||||
target_link_libraries(simpleGame PUBLIC
|
||||
sfml-graphics
|
||||
${FMOD_LIB_NAME}
|
||||
)
|
||||
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/../media" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_custom_command(TARGET simpleGame POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${FMOD_PATH}/api/core/lib/${CPU_THING}/${FMOD_DLL_NAME}"
|
||||
"$<TARGET_FILE_DIR:simpleGame>"
|
||||
)
|
34
SimpleGame/src/Include/AudioEmitter.hpp
Normal file
34
SimpleGame/src/Include/AudioEmitter.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <fmod.hpp>
|
||||
#include <fmod_errors.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class AudioEmitter {
|
||||
private:
|
||||
std::unique_ptr<FMOD::System> system;
|
||||
FMOD::Channel* timer{ nullptr };
|
||||
std::vector <std::unique_ptr<FMOD::Sound>> chords;
|
||||
std::vector<std::unique_ptr<FMOD::Sound>> drums;
|
||||
std::vector<std::unique_ptr<FMOD::Sound>> notes;
|
||||
int tempo{ 170 };
|
||||
std::vector<std::vector<float>> markov_matrix_chords;
|
||||
std::vector<std::vector<float>> markov_matrix_melody;
|
||||
int nbr_melo_max{ 4 };
|
||||
int current_beat{ 0 };
|
||||
std::vector<std::vector<float>> rythmes;
|
||||
int index_note;
|
||||
std::vector<int> chordProgression;
|
||||
std::vector<FMOD::Channel*> activeChannels;
|
||||
public:
|
||||
AudioEmitter();
|
||||
void generateMusic();
|
||||
void audioUpdate();
|
||||
void audioEnd();
|
||||
int firstChord();
|
||||
int nextChord(int currentChord);
|
||||
int firstNote();
|
||||
int nextNote(int currentNote);
|
||||
int noteSecondaire(int note);
|
||||
float getTime();
|
||||
float timeBeforeNewGeneration{ 0.2f };
|
||||
};
|
34
SimpleGame/src/Include/Game.hpp
Normal file
34
SimpleGame/src/Include/Game.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef BOOK_GAME_HPP
|
||||
#define BOOK_GAME_HPP
|
||||
|
||||
#include "RoundTarget.hpp"
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "AudioEmitter.hpp"
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game();
|
||||
Game(const Game &) = delete;
|
||||
Game &operator=(const Game &) = delete;
|
||||
void run();
|
||||
|
||||
private:
|
||||
void processEvents(AudioEmitter& audioEmitter);
|
||||
void update(sf::Time elapsedTime);
|
||||
void render();
|
||||
|
||||
void updateStatistics(AudioEmitter& audioEmitter);
|
||||
|
||||
static const sf::Time TimePerFrame;
|
||||
|
||||
sf::RenderWindow mWindow{sf::VideoMode({640, 480}), "SFML Application"};
|
||||
sf::Texture mTexture;
|
||||
RoundTarget mTarget{35.f, sf::Color::Red, 320.f, 300.f};
|
||||
sf::Font mFont;
|
||||
sf::Text mStatisticsText{mFont};
|
||||
sf::Time mStatisticsUpdateTime;
|
||||
|
||||
std::size_t mStatisticsNumFrames{0};
|
||||
};
|
||||
|
||||
#endif // BOOK_GAME_HPP
|
22
SimpleGame/src/Include/RoundTarget.hpp
Normal file
22
SimpleGame/src/Include/RoundTarget.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef SIMPLE_GAME_ROUND_TARGET_H
|
||||
#define SIMPLE_GAME_ROUND_TARGET_H
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
class RoundTarget {
|
||||
public:
|
||||
RoundTarget(float radius, sf::Color color, float x, float y);
|
||||
void drawCurrent(sf::RenderWindow &window) const;
|
||||
void handlePlayerInput(const sf::Keyboard::Key &key, const bool &isPressed);
|
||||
void update(const sf::Time &elapsedTime);
|
||||
|
||||
private:
|
||||
static constexpr float TargetSpeed{100.f};
|
||||
bool mIsMovingUp{false};
|
||||
bool mIsMovingDown{false};
|
||||
bool mIsMovingRight{false};
|
||||
bool mIsMovingLeft{false};
|
||||
sf::CircleShape mShape;
|
||||
};
|
||||
|
||||
#endif // SIMPLE_GAME_ROUND_TARGET_H
|
316
SimpleGame/src/Source/AudioEmitter.cpp
Normal file
316
SimpleGame/src/Source/AudioEmitter.cpp
Normal file
|
@ -0,0 +1,316 @@
|
|||
#include "AudioEmitter.hpp"
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
|
||||
void ERRCHECK(FMOD_RESULT result) {
|
||||
if (result != FMOD_OK) {
|
||||
std::cout << "FMOD error: " << FMOD_ErrorString(result) << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
auto fmodSoundDeleter = [](FMOD::Sound* sound) {
|
||||
if (sound) {
|
||||
sound->release();
|
||||
}
|
||||
};
|
||||
|
||||
AudioEmitter::AudioEmitter() {
|
||||
FMOD::System* rawSystem = nullptr;
|
||||
ERRCHECK(FMOD::System_Create(&rawSystem));
|
||||
|
||||
system.reset(rawSystem);
|
||||
ERRCHECK(system->init(512, FMOD_INIT_NORMAL, nullptr));
|
||||
|
||||
|
||||
std::vector<FMOD::Sound*> rawChords(7);
|
||||
ERRCHECK(system->createSound("media/accords/do.wav", FMOD_LOOP_OFF, nullptr, &rawChords[0]));
|
||||
ERRCHECK(system->createSound("media/accords/re.wav", FMOD_LOOP_OFF, nullptr, &rawChords[1]));
|
||||
ERRCHECK(system->createSound("media/accords/mi.wav", FMOD_LOOP_OFF, nullptr, &rawChords[2]));
|
||||
ERRCHECK(system->createSound("media/accords/fa.wav", FMOD_LOOP_OFF, nullptr, &rawChords[3]));
|
||||
ERRCHECK(system->createSound("media/accords/sol.wav", FMOD_LOOP_OFF, nullptr, &rawChords[4]));
|
||||
ERRCHECK(system->createSound("media/accords/la.wav", FMOD_LOOP_OFF, nullptr, &rawChords[5]));
|
||||
ERRCHECK(system->createSound("media/accords/si.wav", FMOD_LOOP_OFF, nullptr, &rawChords[6]));
|
||||
for (int i = 0; i < 7; i += 1) {
|
||||
chords.push_back(std::unique_ptr<FMOD::Sound>(rawChords[i]));
|
||||
}
|
||||
|
||||
int nbr_drums = 3;
|
||||
std::vector<FMOD::Sound*> rawDrums(nbr_drums);
|
||||
ERRCHECK(system->createSound("media/percussions/drums1.wav", FMOD_LOOP_OFF, nullptr, &rawDrums[0]));
|
||||
ERRCHECK(system->createSound("media/percussions/drums2.wav", FMOD_LOOP_OFF, nullptr, &rawDrums[1]));
|
||||
ERRCHECK(system->createSound("media/percussions/drums3.wav", FMOD_LOOP_OFF, nullptr, &rawDrums[2]));
|
||||
for (int i = 0; i < nbr_drums; i += 1) {
|
||||
drums.push_back(std::unique_ptr<FMOD::Sound>(rawDrums[i]));
|
||||
}
|
||||
|
||||
std::vector<FMOD::Sound*> rawNotes(15);
|
||||
ERRCHECK(system->createSound("media/notes/A1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[0]));
|
||||
ERRCHECK(system->createSound("media/notes/B1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[1]));
|
||||
ERRCHECK(system->createSound("media/notes/C1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[2]));
|
||||
ERRCHECK(system->createSound("media/notes/D1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[3]));
|
||||
ERRCHECK(system->createSound("media/notes/E1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[4]));
|
||||
ERRCHECK(system->createSound("media/notes/F1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[5]));
|
||||
ERRCHECK(system->createSound("media/notes/G1.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[6]));
|
||||
ERRCHECK(system->createSound("media/notes/A2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[7]));
|
||||
ERRCHECK(system->createSound("media/notes/B2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[8]));
|
||||
ERRCHECK(system->createSound("media/notes/C2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[9]));
|
||||
ERRCHECK(system->createSound("media/notes/D2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[10]));
|
||||
ERRCHECK(system->createSound("media/notes/E2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[11]));
|
||||
ERRCHECK(system->createSound("media/notes/F2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[12]));
|
||||
ERRCHECK(system->createSound("media/notes/G2.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[13]));
|
||||
ERRCHECK(system->createSound("media/notes/A3.wav", FMOD_LOOP_OFF, nullptr, &rawNotes[14]));
|
||||
for (int i = 0; i < 15; i += 1) {
|
||||
notes.push_back(std::unique_ptr<FMOD::Sound>(rawNotes[i]));
|
||||
}
|
||||
|
||||
|
||||
index_note = firstNote();
|
||||
|
||||
rythmes = {
|
||||
{0,2,4,6},
|
||||
{0,1,2,3,4,5,6,7},
|
||||
{0,0.5,1,1.5,2,3,4,5,6,7},
|
||||
{0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5},
|
||||
{0,0.5,1,2,2.5,3,4,4.5,5,6,6.5,7},
|
||||
{0.5,1,1.5,2,3.5,4,4.5,5,6.5,7,7.5},
|
||||
{0,1,2.5,3,4,5,5.5,6.5,7,7.5},
|
||||
{0,0.75,1.5,2.5,3,3.5,5,5.5},
|
||||
{0,0.5,1,1.5,2,3,4,4.5,5,6,6.5,7,7.5},
|
||||
{0,0.5,1,1.5,2.5,3.5,4,5,6,7},
|
||||
{0,1.5,3,4,5.5,7},
|
||||
{0,0.5,1.5,2,3,4,4.5,5.5,6,7},
|
||||
{0.5,1,1.5,2,2.75,3.5,4.5,5,5.5,6,6.5,7,7.5},
|
||||
{0,0.75,1.5,2,2.75,3.5,4,4.5,5,5.5,6,7,7.5},
|
||||
{0,0.5,1.5,2,3,3.5,4.5,5,6,6.5,7.5},
|
||||
{0,1,2,2.75,3.5,4.5,5,5.5,6,6.75,7.5},
|
||||
{0.5,1,1.5,2,2.5,3.5,4.5,5,5.5,6,6.5,7},
|
||||
{0,1,1.5,2,2.5,3,3.5,4,5.5,7},
|
||||
{0,1.5,2.5,3,4,5.5,6.5,7},
|
||||
{0,1.5,3,3.5,4,5.5,7},
|
||||
{0,0.5,1.5,2,2.5,3.5,4,4.5,5,5.5},
|
||||
{0,0.5,1,2,2.5,3,4,4.5,5,6,6.5,7},
|
||||
{0,1.5,3,4.5,6,7},
|
||||
{0,0.5,1,1.5,2.5,3,3.5,4,4.5,5,5.5,6.5,7,7.5},
|
||||
{1,2,3.5,4},
|
||||
{0,1.5,3,4,5.5,7},
|
||||
{0,2,2.5,3,3.5,4.5,5.5,6.5,7},
|
||||
{0.5,1,1.5,2,3.5,4,4.5,5,5.5,6,6.5,7},
|
||||
{0,0.5,1,1.5,3,4,4.5,5,5.5,7},
|
||||
};
|
||||
|
||||
markov_matrix_chords = {
|
||||
{0, 0.10, 0.00, 0.40, 0.35, 0.15, 0.00},
|
||||
// Depuis ii (1)
|
||||
{0.10, 0, 0.00, 0.25, 0.65, 0.00, 0.00},
|
||||
// Depuis iii (2)
|
||||
{0.00, 0.00, 0, 0.25, 0.15, 0.50, 0.10},
|
||||
// Depuis IV (3)
|
||||
{0.45, 0.15, 0.00, 0, 0.25, 0.15, 0.00},
|
||||
// Depuis V (4)
|
||||
{0.70, 0.00, 0.00, 0.10, 0, 0.20, 0.00},
|
||||
// Depuis vi (5)
|
||||
{0.15, 0.15, 0.00, 0.45, 0.25, 0, 0.00},
|
||||
// Depuis vii° (6)
|
||||
{0.80, 0.00, 0.00, 0.00, 0.20, 0.00, 0.00}
|
||||
};
|
||||
|
||||
markov_matrix_melody = {
|
||||
// A1 (0)
|
||||
{0.05, 0.30, 0.25, 0.15, 0.10, 0.05, 0.03, 0.02, 0.02, 0.01, 0.01, 0.00, 0.00, 0.00, 0.00},
|
||||
// B1 (1)
|
||||
{0.20, 0.05, 0.30, 0.20, 0.10, 0.05, 0.03, 0.02, 0.02, 0.01, 0.01, 0.00, 0.00, 0.00, 0.00},
|
||||
// C2 (2)
|
||||
{0.10, 0.20, 0.05, 0.30, 0.15, 0.10, 0.05, 0.02, 0.02, 0.01, 0.00, 0.00, 0.00, 0.00, 0.00},
|
||||
// D2 (3)
|
||||
{0.05, 0.15, 0.20, 0.05, 0.30, 0.15, 0.05, 0.03, 0.02, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
|
||||
// E2 (4)
|
||||
{0.03, 0.07, 0.15, 0.20, 0.05, 0.25, 0.15, 0.07, 0.03, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
|
||||
// F2 (5)
|
||||
{0.02, 0.05, 0.10, 0.15, 0.20, 0.05, 0.25, 0.15, 0.05, 0.02, 0.01, 0.00, 0.00, 0.00, 0.00},
|
||||
// G2 (6)
|
||||
{0.01, 0.03, 0.07, 0.10, 0.15, 0.20, 0.05, 0.25, 0.10, 0.03, 0.01, 0.00, 0.00, 0.00, 0.00},
|
||||
// A2 (7) - Centre tonal
|
||||
{0.00, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.05, 0.15, 0.05, 0.02, 0.01, 0.00, 0.00, 0.00},
|
||||
// B2 (8)
|
||||
{0.00, 0.00, 0.01, 0.03, 0.07, 0.15, 0.20, 0.25, 0.05, 0.20, 0.10, 0.05, 0.03, 0.01, 0.00},
|
||||
// C3 (9)
|
||||
{0.00, 0.00, 0.00, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.05, 0.20, 0.15, 0.07, 0.03, 0.01},
|
||||
// D3 (10)
|
||||
{0.00, 0.00, 0.00, 0.00, 0.03, 0.07, 0.10, 0.15, 0.20, 0.25, 0.05, 0.25, 0.15, 0.07, 0.03},
|
||||
// E3 (11)
|
||||
{0.00, 0.00, 0.00, 0.00, 0.00, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.05, 0.20, 0.15, 0.08},
|
||||
// F3 (12)
|
||||
{0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.03, 0.07, 0.10, 0.15, 0.20, 0.25, 0.05, 0.25, 0.15},
|
||||
// G3 (13)
|
||||
{0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.05, 0.28},
|
||||
// A3 (14)
|
||||
{0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.03, 0.07, 0.10, 0.15, 0.20, 0.25, 0.05}
|
||||
};
|
||||
|
||||
chordProgression.resize(4);
|
||||
|
||||
int chord = firstChord();
|
||||
chordProgression[0] = chord;
|
||||
for (int i = 1; i < 4; i += 1) {
|
||||
chord = nextChord(chord);
|
||||
chordProgression[i] = chord;
|
||||
}
|
||||
|
||||
FMOD::Sound* metronome_Sound;
|
||||
ERRCHECK(system->createSound("media/notes/A1.wav", FMOD_DEFAULT, nullptr, &metronome_Sound));
|
||||
ERRCHECK(system->playSound(metronome_Sound, nullptr, true, &timer));
|
||||
ERRCHECK(timer->setVolume(0));
|
||||
ERRCHECK(timer->setPaused(false));
|
||||
}
|
||||
|
||||
int AudioEmitter::firstChord() {
|
||||
std::vector<int> possibleChords = { 1,5,6 };
|
||||
return possibleChords[rand() % possibleChords.size()] - 1;
|
||||
}
|
||||
|
||||
int AudioEmitter::firstNote() {
|
||||
std::vector<int> possibleNotes = { 4,5,6,7,8,9,10,11 };
|
||||
return possibleNotes[rand() % possibleNotes.size()];
|
||||
}
|
||||
|
||||
int sampleIndex(const std::vector<float>& probabilities) {
|
||||
// Créer un générateur aléatoire
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
|
||||
// Créer une distribution discrète avec les probabilités données
|
||||
std::discrete_distribution<> dist(probabilities.begin(), probabilities.end());
|
||||
|
||||
// Tirer un échantillon
|
||||
return dist(gen);
|
||||
}
|
||||
|
||||
int randomWeightedChoice(const std::vector<int>& values, const std::vector<double>& weights) {
|
||||
if (values.size() != weights.size() || values.empty()) {
|
||||
throw std::invalid_argument("Les tableaux doivent être de même taille et non vides.");
|
||||
}
|
||||
|
||||
// Calcul de la somme totale des poids
|
||||
double totalWeight = std::accumulate(weights.begin(), weights.end(), 0.0);
|
||||
if (totalWeight <= 0) {
|
||||
throw std::invalid_argument("La somme des poids doit être positive.");
|
||||
}
|
||||
|
||||
// Générateur aléatoire
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<> dis(0.0, totalWeight);
|
||||
|
||||
double r = dis(gen);
|
||||
double cumulative = 0.0;
|
||||
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
cumulative += weights[i];
|
||||
if (r < cumulative) {
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback - devrait normalement ne jamais être atteint
|
||||
return values.back();
|
||||
}
|
||||
|
||||
int AudioEmitter::nextChord(int currentChord) {
|
||||
return sampleIndex(markov_matrix_chords[currentChord]);
|
||||
}
|
||||
|
||||
int AudioEmitter::nextNote(int currentNote) {
|
||||
return sampleIndex(markov_matrix_melody[currentNote]);
|
||||
}
|
||||
|
||||
int AudioEmitter::noteSecondaire(int note) {
|
||||
std::vector<int> notesPossibles = { note - 4,note - 3,note + 3,note + 4,note + 5 };
|
||||
std::vector<double> proba = { 0.05,0.10,0.60,0.05,0.2 };
|
||||
for (int i = 0; i < proba.size(); i += 1) {
|
||||
if ((notesPossibles[i] < 0) || (notesPossibles[i] >= notes.size())) {
|
||||
proba[i] = 0;
|
||||
}
|
||||
}
|
||||
return randomWeightedChoice(notesPossibles, proba);
|
||||
}
|
||||
|
||||
void AudioEmitter::generateMusic() {
|
||||
float beatDuration = tempo / 60.f;
|
||||
unsigned int sampleRate = 48000;
|
||||
int maxsize = 400;
|
||||
if (activeChannels.size() > maxsize) {
|
||||
for (int i = 0; i < maxsize / 2; i += 1) {
|
||||
if (activeChannels[i]) {
|
||||
activeChannels[i]->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
chordProgression[0] = nextChord(chordProgression[3]);
|
||||
for (int i = 1; i < 4; i += 1) {
|
||||
chordProgression[i] = nextChord(chordProgression[i-1]);
|
||||
}
|
||||
int index_drums = rand() % 3;
|
||||
int second_melody = 1; //Pas de seconde mélodie
|
||||
for (int i = current_beat; i < current_beat + nbr_melo_max; i += 1) {
|
||||
//Chords
|
||||
FMOD::Channel* channelChords = nullptr;
|
||||
int index_chord = chordProgression[i % 4];
|
||||
ERRCHECK(system->playSound(chords[index_chord].get(), nullptr, true, &channelChords));
|
||||
|
||||
unsigned long long delay = (unsigned long long)(i * beatDuration * sampleRate);
|
||||
ERRCHECK(channelChords->setDelay(delay, 0, true));
|
||||
ERRCHECK(channelChords->setPaused(false));
|
||||
|
||||
activeChannels.push_back(channelChords);
|
||||
//Drums
|
||||
FMOD::Channel* channelDrums = nullptr;
|
||||
ERRCHECK(system->playSound(drums[index_drums].get(), nullptr, true, &channelDrums));
|
||||
ERRCHECK(channelDrums->setDelay(delay, 0, true));
|
||||
ERRCHECK(channelDrums->setPaused(false));
|
||||
|
||||
activeChannels.push_back(channelDrums);
|
||||
//Mélodie
|
||||
std::vector<float> rythme_melodie = rythmes[rand() % rythmes.size()];
|
||||
for (float time : rythme_melodie) {
|
||||
FMOD::Channel* channelNote = nullptr;
|
||||
ERRCHECK(system->playSound(notes[index_note].get(), nullptr, true, &channelNote));
|
||||
unsigned long long delayNote = (unsigned long long)((i + time / 8.f) * beatDuration * sampleRate);
|
||||
ERRCHECK(channelNote->setDelay(delayNote, 0, true));
|
||||
ERRCHECK(channelNote->setPaused(false));
|
||||
if (second_melody == 0) {
|
||||
FMOD::Channel* channelNoteSec = nullptr;
|
||||
ERRCHECK(system->playSound(notes[noteSecondaire(index_note)].get(), nullptr, true, &channelNoteSec));
|
||||
unsigned long long delayNote = (unsigned long long)((i + time / 8.f) * beatDuration * sampleRate);
|
||||
ERRCHECK(channelNoteSec->setDelay(delayNote, 0, true));
|
||||
ERRCHECK(channelNoteSec->setPaused(false));
|
||||
activeChannels.push_back(channelNoteSec);
|
||||
}
|
||||
index_note = nextNote(index_note);
|
||||
activeChannels.push_back(channelNote);
|
||||
}
|
||||
}
|
||||
current_beat += nbr_melo_max;
|
||||
}
|
||||
|
||||
void AudioEmitter::audioUpdate() {
|
||||
system->update();
|
||||
}
|
||||
|
||||
void AudioEmitter::audioEnd() {
|
||||
for (FMOD::Channel* c : activeChannels) {
|
||||
delete c;
|
||||
}
|
||||
timer->stop();
|
||||
system->close();
|
||||
system->release();
|
||||
}
|
||||
|
||||
float AudioEmitter::getTime() {
|
||||
float beatDuration = tempo / 60.f / 8.f;
|
||||
unsigned long long dspClock = 0;
|
||||
ERRCHECK(timer->getDSPClock(&dspClock, nullptr));
|
||||
return dspClock / 48000.f / beatDuration;
|
||||
}
|
77
SimpleGame/src/Source/Game.cpp
Normal file
77
SimpleGame/src/Source/Game.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "Game.hpp"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
|
||||
const sf::Time Game::TimePerFrame = sf::seconds(1.f / 60.f);
|
||||
|
||||
Game::Game() {
|
||||
assert(mFont.openFromFile("media/Sansation.ttf"));
|
||||
// We do not need to do mStatisticsText.setFont(mFont); as mStatisticsText is
|
||||
// initialized with a reference to mFont
|
||||
mStatisticsText.setPosition({5.f, 5.f});
|
||||
mStatisticsText.setCharacterSize(10);
|
||||
}
|
||||
|
||||
void Game::run() {
|
||||
sf::Clock clock;
|
||||
sf::Time timeSinceLastUpdate = sf::Time::Zero;
|
||||
AudioEmitter audioEmitter = AudioEmitter();
|
||||
audioEmitter.generateMusic();
|
||||
bool generated = false;
|
||||
mWindow.setVerticalSyncEnabled(true);
|
||||
while (mWindow.isOpen()) {
|
||||
sf::Time elapsedTime = clock.restart();
|
||||
timeSinceLastUpdate += elapsedTime;
|
||||
while (timeSinceLastUpdate > TimePerFrame) {
|
||||
if (32.f - fmod(audioEmitter.getTime(), 32.f) < audioEmitter.timeBeforeNewGeneration) {
|
||||
if (!generated) {
|
||||
audioEmitter.generateMusic();
|
||||
generated = true;
|
||||
}
|
||||
} else {
|
||||
generated = false;
|
||||
}
|
||||
timeSinceLastUpdate -= TimePerFrame;
|
||||
|
||||
processEvents(audioEmitter);
|
||||
audioEmitter.audioUpdate();
|
||||
update(TimePerFrame);
|
||||
}
|
||||
|
||||
updateStatistics(audioEmitter);
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
void Game::processEvents(AudioEmitter& audioEmitter) {
|
||||
while (const std::optional event = mWindow.pollEvent()) {
|
||||
if (const auto *keyPressed = event->getIf<sf::Event::KeyPressed>()) {
|
||||
mTarget.handlePlayerInput(keyPressed->code, true);
|
||||
} else if (const auto *keyReleased =
|
||||
event->getIf<sf::Event::KeyReleased>()) {
|
||||
mTarget.handlePlayerInput(keyReleased->code, false);
|
||||
} else if (event->is<sf::Event::Closed>()) {
|
||||
audioEmitter.audioEnd();
|
||||
mWindow.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::update(const sf::Time elapsedTime) { mTarget.update(elapsedTime); }
|
||||
|
||||
void Game::render() {
|
||||
mWindow.clear();
|
||||
mTarget.drawCurrent(mWindow);
|
||||
mWindow.draw(mStatisticsText);
|
||||
mWindow.display();
|
||||
}
|
||||
|
||||
void Game::updateStatistics(AudioEmitter& audioEmitter) {
|
||||
mStatisticsText.setString(std::format(
|
||||
"Mesure = {}\nBeat = {} us", ceil(audioEmitter.getTime()/8.f),
|
||||
ceil(fmod(audioEmitter.getTime(),8.f))));
|
||||
|
||||
mStatisticsUpdateTime -= sf::seconds(1.0f);
|
||||
mStatisticsNumFrames = 0;
|
||||
}
|
6
SimpleGame/src/Source/Main.cpp
Normal file
6
SimpleGame/src/Source/Main.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "Game.hpp"
|
||||
|
||||
int main() {
|
||||
Game game;
|
||||
game.run();
|
||||
}
|
39
SimpleGame/src/Source/RoundTarget.cpp
Normal file
39
SimpleGame/src/Source/RoundTarget.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "RoundTarget.hpp"
|
||||
|
||||
RoundTarget::RoundTarget(const float radius, const sf::Color color, float x,
|
||||
float y) {
|
||||
mShape.setRadius(radius);
|
||||
mShape.setFillColor(color);
|
||||
mShape.setPosition({x, y});
|
||||
}
|
||||
|
||||
void RoundTarget::drawCurrent(sf::RenderWindow &window) const {
|
||||
window.draw(mShape);
|
||||
}
|
||||
|
||||
void RoundTarget::handlePlayerInput(const sf::Keyboard::Key &key,
|
||||
const bool &isPressed) {
|
||||
using enum sf::Keyboard::Key;
|
||||
if (key == Z)
|
||||
mIsMovingUp = isPressed;
|
||||
else if (key == S)
|
||||
mIsMovingDown = isPressed;
|
||||
else if (key == Q)
|
||||
mIsMovingLeft = isPressed;
|
||||
else if (key == D)
|
||||
mIsMovingRight = isPressed;
|
||||
}
|
||||
|
||||
void RoundTarget::update(const sf::Time &elapsedTime) {
|
||||
sf::Vector2f movement{0.f, 0.f};
|
||||
if (mIsMovingUp)
|
||||
movement.y -= TargetSpeed;
|
||||
if (mIsMovingDown)
|
||||
movement.y += TargetSpeed;
|
||||
if (mIsMovingLeft)
|
||||
movement.x -= TargetSpeed;
|
||||
if (mIsMovingRight)
|
||||
movement.x += TargetSpeed;
|
||||
|
||||
mShape.move(movement * elapsedTime.asSeconds());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue