
Big Tuto SFML 2 / Action-RPG : Legends of Meruvia
Chapitre 15 : Monte le son !
Tutoriel présenté par : Jérémie F. Bellanger (Jay81)
Date d'écriture : 27 juin 2016
Date de révision : -
Prologue
Comme vous l'aurez remarqué, pour l'instant notre jeu n'a pas de son ! 
On va donc y remédier dès maintenant en rajoutant une jolie mélodie, composée par Skrool, que je remercie, ainsi que des effets sonores aussi appelés sounds Fx (ou effects). 
Allez, on est parti !
Fichiers musique et sound Fx
Bien entendu, pour jouer de la musique et des sons, il faut que les fichiers correspondants soient déjà inclus dans le dossier de notre projet. Si vous avez téléchargé l'archive, normalement vous devriez les trouver dans les dossier music et sounds de votre projet. Bien sûr, si vous en avez, vous pouvez aussi utiliser vos propres fichiers (sachant que ceux du tuto sont protégés par le droit d'auteur et restent utilisables uniquement dans le cadre de ce tuto - n'allez pas les vendre avec votre jeu
).
Attention : la SFML ne gère pas le format MP3 pour des problèmes de droits, utilisez donc le format ogg !
Il existe des sites web qui convertiront automatiquement et gratuitement vos mp3 en ogg. ![]()
Passons maintenant au code ! ![]()
Le code
On va commencer par créer une nouvelle classe Sounds. Vous devriez maintenant en avoir l'habitude. ![]()
Copiez-y le code suivant :
Fichier : sounds.h : Créer le fichier et y copier :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#ifndef SOUNDS_H
#define SOUNDS_H
#include <SFML/Audio.hpp>
#include <iostream>
class Sounds
{
public:
//Constructeur
Sounds();
//Fonctions
void PlayMusic(bool valeur);
void PlaySoundFx(int type);
private:
//Variables de la classe en accès privé
//Attention : il faut bien déclarer les SoundBuffer AVANT les Sound !
sf::SoundBuffer bumper;
sf::SoundBuffer destroy;
sf::SoundBuffer jump;
sf::SoundBuffer star;
sf::Sound soundFxBumper;
sf::Sound soundFxDestroy;
sf::Sound soundFxJump;
sf::Sound soundFxStar;
sf::Music music;
public:
//Une enum pour la gestion des sons.
enum { BUMPER, DESTROY, JUMP, STAR };
};
#endif
|
Comme vous pouvez le voir, c'est très basique. ![]()
Au niveau variables, on va créer autant de SoundBuffer que de Sound pour contenir nos effets sonores en .wav. Le fonctionnement de ces variables en SFML ressemble beaucoup à celui des Sprites et des Textures, et je vous renvoie à la doc pour plus de détails. ![]()
Une variable music contiendra notre fichier ogg, qui sera lu en streaming (et pas copié en mémoire).
Enfin, une enum nous permettra de retrouver facilement le son à jouer, plutôt que de les appeler 1, 2, 3, etc.
(N.B. : J'ai gardé l'enum de Rabidja, mais certains sons nous seront inutiles ici...
)
Attention : Rappelez-vous de bien déclarer vos sf::SoundBuffer AVANT les sf::Sound, sinon, vous aurez une erreur de violation mémoire en quittant car le programme détruira les variables en sens inverse, ce qui donnera un pointeur sur une variable qui n'existe plus ! ![]()
Passons maintenant au fichier sounds.cpp :
Fichier : sounds.cpp : Créer le fichier et y copier :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#include "sounds.h"
using namespace std;
using namespace sf;
//Constructeur
Sounds::Sounds()
{
//On charge les sound effects
if (!bumper.loadFromFile("sounds/bumper.wav"))
cout << "Erreur durant le chargement des sound Fx." << endl;
soundFxBumper.setBuffer(bumper);
if (!destroy.loadFromFile("sounds/destroy.wav"))
cout << "Erreur durant le chargement des sound Fx." << endl;
soundFxDestroy.setBuffer(destroy);
if (!jump.loadFromFile("sounds/jump.wav"))
cout << "Erreur durant le chargement des sound Fx." << endl;
soundFxJump.setBuffer(jump);
if (!star.loadFromFile("sounds/star.wav"))
cout << "Erreur durant le chargement des sound Fx." << endl;
soundFxStar.setBuffer(star);
//On joue la musique en boucle - celle-ci doit être au format ogg
//ATTENTION : FORMAT MP3 NON SUPPORTE !
if (!music.openFromFile("music/village1.ogg"))
cout << "Erreur durant le chargement de la musique." << endl;
}
//Fonctions
void Sounds::PlayMusic(bool valeur)
{
//On allume / éteint la musique en boucle suivant
//le booléen true ou false envoyé.
music.setLoop(true);
if (valeur)
music.play();
else
music.stop();
}
void Sounds::PlaySoundFx(int type)
{
//Suivant le type, on joue l'effet sonore
switch (type)
{
case BUMPER:
soundFxBumper.play();
break;
case DESTROY:
soundFxDestroy.play();
break;
case JUMP:
soundFxJump.play();
break;
case STAR:
soundFxStar.play();
break;
}
}
|
Bien, il va maintenant nous falloir intégrer nos sons dans nos classes pré-existantes. ![]()
Bien que ce ne soit pas particulièrement difficile, c'est assez fastidieux, car il y a de nombreuses petites choses à modifier.
Plutôt que de les voir les unes après les autres, j'ai donc choisi de vous redonner le code complet pour les headers, et le code complet des fonctions à modifier (plus faciles à copier/coller à la place de l'ancien code
) et de vous indiquer à côté les points du code qui ont été modifiés.
Fichier : monster.h : Remplacer le code précédent par :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#ifndef MONSTER_H
#define MONSTER_H
#include <SFML/Graphics.hpp>
#include <iostream>
class Map;
class Player;
class Sounds;
class Monster
{
public:
//Constructeur
Monster();
//Accesseurs
int getType(void) const;
int getLife(void) const;
int getLifeMax(void) const;
int getX(void) const;
int getY(void) const;
int getW(void) const;
int getH(void) const;
float getDirX(void) const;
float getDirY(void) const;
int getFrameNumber(void) const;
int getFrameTimer(void) const;
int getFrameMax(void) const;
int getEtat(void) const;
int getDirection(void) const;
int getSaveX(void) const;
int getSaveY(void) const;
int getTimerMort(void) const;
int getIATimer(void) const;
int getInvincibleTimer(void) const;
int getisHurt(void) const;
int getHurtDirection(void) const;
//Mutateurs
void setLife(int valeur);
void setX(int valeur);
void setY(int valeur);
void setW(int valeur);
void setH(int valeur);
void setDirX(float valeur);
void setDirY(float valeur);
void setTimerMort(int valeur);
void setInvincibleTimer(int valeur);
void setisHurt(int valeur);
void setHurtDirection(int valeur);
//Fonctions
void initialize(int Atype, int x1, int y1);
void draw(Map &map, sf::RenderWindow &window);
int update(int monsterNumber, Map &map, Player &player, Monster monster[], Sounds &sounds);
void mapCollision(Map &map, Player &player);
bool collideWithMonsters(Monster &monster);
void copy(Monster &monster);
bool collide(Player &player);
private:
//Variables de la classe en accès privé
// Points de vie/santé + chrono d'invicibilité
float life, lifeMax;
int invincibleTimer;
//Type de monstre
int type;
//Si le monstre est touché
int isHurt;
int hurtDirection;
// Coordonnées du sprite
int x, y;
// Largeur, hauteur du sprite
int h, w;
// Checkpoint pour le héros (actif ou non)
int checkpointActif;
// + coordonnées de respawn (réapparition)
int respawnX, respawnY;
// Variables utiles pour l'animation :
// Numéro de la frame (= image) en cours + timer
int frameNumber, frameTimer, frameMax;
// Nombre max de frames, état du sprite et direction
// dans laquelle il se déplace (gauche / droite)
int etat, direction;
//Timer pour l'IA
int IATimer;
// Variables utiles pour la gestion des collisions :
//Est-il sur le sol, chrono une fois mort
int timerMort;
//Vecteurs de déplacement temporaires avant détection
//des collisions avec la map
float dirX, dirY;
//Sauvegarde des coordonnées de départ
int saveX, saveY;
//Spritesheet
sf::Texture Texture[2];
sf::Sprite Sprite[2];
int numberOfMonstersSprites;
//LifeGauge
sf::Texture lifeGaugeTexture;
sf::Sprite lifeGauge;
sf::Texture energyTexture;
sf::Sprite energy;
/******************/
/* Constantes */
/******************/
/* Taille maxi de la map : 400 x 150 tiles */
const int MAX_MAP_X = 400;
const int MAX_MAP_Y = 150;
/* Taille d'une tile (32 x 32 pixels) */
const int TILE_SIZE = 32;
/* Constante pour l'animation */
const int TIME_BETWEEN_2_FRAMES_PLAYER = 4;
//Dimensions du monstre
const int MONSTER_WIDTH = 42;
const int MONSTER_HEIGTH = 42;
//Valeurs attribuées aux états/directions
const int IDLE = 0;
const int WALK = 1;
const int DEAD = 4;
const int DOWN = 0;
const int UP = 1;
const int RIGHT = 2;
const int LEFT = 3;
const int IATime = 50;
const int TIME_BETWEEN_2_SHOTS = 30;
const int MOONWALK_TIMER = 8;
// Taille de la fenêtre : 800x480 pixels
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 480;
};
#endif
|
Voici la liste des modifications opérées : ![]()
- on rajoute class Sounds; en haut du fichier.
- on rajoute Sounds &sounds en argument à la fonction update().
Fichier : monster.cpp : Rajouter l'include et remplacer la fonction update() :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#include "monster.h"
#include "player.h"
#include "map.h"
//Include à rajouter
#include "sounds.h"
//Code coupé...
int Monster::update(int monsterNumber, Map &map, Player &player, Monster monster[], Sounds &sounds)
{
//Même fonctionnement que pour le joueur
if (timerMort == 0)
{
//On diminue le timer d'invincibilité et de recul
if (invincibleTimer > 0)
invincibleTimer--;
if (isHurt > 0)
isHurt--;
dirX = 0;
dirY = 0;
//Test de collision dans un mur : si la variable x ou y reste la même, deux tours de boucle
//durant, le monstre est bloqué et on lui fait faire demi-tour.
if (x == saveX && isHurt == 0)
{
if (direction == LEFT)
{
direction = RIGHT;
//Sécurité : système d'éjection du monstre pour
//l'évacuer s'il reste coincé dans un obstacle
if (y == saveY && direction == UP)
y += 1;
else if (y == saveY && direction == DOWN)
y -= 1;
}
else if (direction == RIGHT)
{
direction = LEFT;
//Sécurité : système d'éjection du monstre pour
//l'évacuer s'il reste coincé dans un obstacle
if (y == saveY && direction == UP)
y += 1;
else if (y == saveY && direction == DOWN)
y -= 1;
}
}
else if (y == saveY)
{
if (direction == UP)
{
direction = DOWN;
//Sécurité : système d'éjection du monstre pour
//l'évacuer s'il reste coincé dans un obstacle
if (x == saveX && direction == LEFT)
x += 1;
else if (x == saveX && direction == RIGHT)
x -= 1;
}
else if (direction == DOWN)
{
direction = UP;
//Sécurité : système d'éjection du monstre pour
//l'évacuer s'il reste coincé dans un obstacle
if (x == saveX && direction == LEFT)
x += 1;
else if (x == saveX && direction == RIGHT)
x -= 1;
}
}
//Si le timer de l'IA descend en-dessous de 0, il est temps
//de changer de direction au hasard.
if (IATimer <= 0 && isHurt == 0)
{
direction = rand() % 4;
IATimer = IATime;
}
else
IATimer--;
//Déplacement du monstre selon la direction
//s'il est touché
if (isHurt > 0)
{
if (hurtDirection == LEFT)
dirX -= 10;
else if (hurtDirection == RIGHT)
dirX += 10;
else if (hurtDirection == UP)
dirY -= 10;
else if (hurtDirection == DOWN)
dirY += 10;
}
else
{
if (direction == LEFT)
dirX -= 1;
else if (direction == RIGHT)
dirX += 1;
else if (direction == UP)
dirY -= 1;
else if (direction == DOWN)
dirY += 1;
}
//On sauvegarde les coordonnées du monstre pour gérer le demi-tour
//avant que mapCollision() ne les modifie.
saveX = x;
saveY = y;
//On détecte les collisions avec la map comme pour le joueur
mapCollision(map, player);
}
//On détecte les collisions avec le joueur
//Si c'est égal à 1, on diminue ses PV
if (collide(player))
{
if (player.getLife() > 1)
{
//On blesse le joueur
player.playerHurts(sounds);
//Et on blesse le monstre s'il n'est pas invincible
if (invincibleTimer == 0)
{
life--;
if (life <= 0)
timerMort = 1;
invincibleTimer = TIME_BETWEEN_2_SHOTS;
}
//On le déclare touché, pour qu'il recule en arrière
isHurt = MOONWALK_TIMER;
//On détermine sa direction de recul, par rapport au placement
//de l'ennemi
//S'il vient d'en haut
if (player.getDirection() == DOWN)
hurtDirection = DOWN;
else if (player.getDirection() == UP)
hurtDirection = UP;
else if (player.getDirection() == RIGHT)
hurtDirection = RIGHT;
else if (player.getDirection() == LEFT)
hurtDirection = LEFT;
}
else
{
player.killPlayer(sounds);
}
}
//On détecte les collisions avec l'épée
//Si c'est le cas, on diminue ses PV
if (player.getCollisionWithSword(x, y, w, h))
{
//Et on blesse le monstre s'il n'est pas invincible
if (invincibleTimer == 0)
{
life--;
if (life <= 0)
timerMort = 1;
invincibleTimer = TIME_BETWEEN_2_SHOTS;
//On joue le sound Fx
sounds.PlaySoundFx(sounds.DESTROY);
}
//On le déclare touché, pour qu'il recule en arrière
isHurt = MOONWALK_TIMER;
//On détermine sa direction de recul, par rapport au placement
//de l'ennemi
//S'il vient d'en haut
if (player.getDirection() == DOWN)
hurtDirection = DOWN;
else if (player.getDirection() == UP)
hurtDirection = UP;
else if (player.getDirection() == RIGHT)
hurtDirection = RIGHT;
else if (player.getDirection() == LEFT)
hurtDirection = LEFT;
}
//On détecte les collisions avec les autres monstres
for (int i = 0; i < map.getNombreMonstres(); i++)
{
//On ne reteste pas le monstre avec lui-même, sinon
//gare à la cata !!
if (i != monsterNumber)
if (collideWithMonsters(monster[i]))
{
if (direction == UP)
{
direction = DOWN;
y = monster[i].getY() + monster[i].getH() + 1;
}
else if (direction == DOWN)
{
direction = UP;
y = monster[i].getY() - h - 1;
}
else if (direction == RIGHT)
{
direction = LEFT;
x = monster[i].getX() - w - 1;
}
else if (direction == LEFT)
{
direction = RIGHT;
x = monster[i].getX() + monster[i].getW() + 1;
}
}
}
//Si le monstre meurt, on active une tempo
if (timerMort > 0)
{
timerMort--;
/* Si le monstre meurt, on renvoie 2 pour le remplace simplement par le dernier
monstre du tableau dans le main puis on rétrécit le tableau d'une case
(on ne peut pas laisser de case vide), sinon on renvoie 0 */
if (timerMort == 0)
return 2;
else
return 0;
}
else
return 0;
}
|
Voici la liste des modifications opérées :
- on rajoute #include "sounds.h" en haut du fichier.
- on rajoute Sounds &sounds en argument à update()
- dans la fonction update() :
- on rajoute un appel à PlaySoundFx() dans : if (player.getCollisionWithSword(x, y, w, h)).
- on met à jour l'appel à killPlayer() et playerHurts() en leur passant sounds en argument.
Passons à la classe Player : ![]()
Fichier : player.h : Remplacer le code précédent par :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <iostream>
class Map;
class Input;
class Sounds;
class Player
{
public:
//Structures
struct POINT { int x, y; };
//Constructeur
Player();
//Accesseurs
int getX(void) const;
int getY(void) const;
int getW(void) const;
int getH(void) const;
float getDirX(void) const;
float getDirY(void) const;
int getOnGround(void) const;
int getLife(void) const;
int getGold(void) const;
int getDirection(void) const;
int getMagic(void) const;
int getNombreExplosions(void) const;
float getMP(void) const;
float getMPmax(void) const;
//Mutateurs
void setX(int valeur);
void setY(int valeur);
void setW(int valeur);
void setH(int valeur);
void setDirX(float valeur);
void setDirY(float valeur);
void setOnGround(bool valeur);
void setTimerMort(int valeur);
void setGold(int valeur);
void setCheckpoint(bool valeur);
void setMagic(int valeur);
void setNombreExplosions(int valeur);
//Fonctions
void initialize(Map &map);
void reinitialize(Map &map);
void draw(Map &map, sf::RenderWindow &window);
void update(Input &input, Map &map);
void centerScrolling(Map &map);
void mapCollision(Map &map);
void drawSword(Map &map, sf::RenderWindow &window);
void killPlayer(Sounds &sounds);
void playerHurts(Sounds &sounds);
bool getCollisionWithSword(int Ax, int Ay, int Aw, int Ah);
private:
//Variables de la classe en accès privé
// Points de vie/santé + chrono d'invicibilité
int life, invincibleTimer;
//Magie
float MP, regainTime;
int MPmax;
int gold;
// Coordonnées du sprite
int x, y;
// Largeur, hauteur du sprite
int h, w;
// Checkpoint pour le héros (actif ou non)
bool checkpointActif;
// + coordonnées de respawn (réapparition)
int respawnX, respawnY;
// Variables utiles pour l'animation :
// Numéro de la frame (= image) en cours + timer
int frameNumber, frameTimer, frameMax;
// Nombre max de frames, état du sprite et direction
// dans laquelle il se déplace (gauche / droite)
int etat, direction;
int isrunning;
int isAttacking;
// Variables utiles pour la gestion des collisions :
//Est-il sur le sol, chrono une fois mort
int timerMort;
//Vecteurs de déplacement temporaires avant détection
//des collisions avec la map
float dirX, dirY;
//Sauvegarde des coordonnées de départ
int saveX, saveY;
//Spritesheet du héros
sf::Texture heroTexture;
sf::Sprite hero;
sf::Texture swordTexture;
sf::Sprite sword;
//Gestion de l'épée
int swordX, swordY;
int swordTimer;
int swordRotation;
//Gestion de la magie (boules de feu)
int magicNumber;
//Nombre d'explosions à l'écran
int nombreExplosions;
//Numéro de la warp spéciale empruntée
int numberSPE;
/******************/
/* Constantes */
/******************/
/* Taille maxi de la map : 400 x 150 tiles */
const int MAX_MAP_X = 400;
const int MAX_MAP_Y = 150;
/* Taille d'une tile (32 x 32 pixels) */
const int TILE_SIZE = 32;
/* Constantes pour l'animation */
const int TIME_BETWEEN_2_FRAMES_PLAYER = 3;
const float TIME_BETWEEN_2_FRAMES_SWORD = 1;
/* Taille du sprite de notre héros (largeur = width et hauteur = heigth) */
const int PLAYER_WIDTH = 40;
const int PLAYER_HEIGTH = 48;
//Vitesse de déplacement en pixels du sprite
const int PLAYER_SPEED = 3;
//Valeurs attribuées aux états/directions
const int IDLE = 0;
const int WALK = 1;
const int DEAD = 4;
const int DOWN = 0;
const int UP = 1;
const int RIGHT = 2;
const int LEFT = 3;
// Taille de la fenêtre : 800x480 pixels
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 480;
//Constantes pour les limites de la caméra avant scrolling
const int LIMITE_X = 400;
const int LIMITE_Y = 220;
const int LIMITE_W = 100;
const int LIMITE_H = 80;
//Enum pour les boutons
const enum{ up, down, right, left, attack, run, enter, magie };
//Nombre max de levels
const int LEVEL_MAX = 2;
//Une enum pour la gestion du menu.
const enum { START, PAUSE };
//Nombre max de shurikens à l'écran
const int MAGIC_MAX = 6;
/*************************/
/* VALEURS DES TILES */
/************************/
const int MUR = 1;
const int SPE1 = 10;
const int SPE2 = 11;
const int SPE3 = 12;
const int SPE4 = 13;
const int SPE5 = 14;
const int SPE6 = 15;
const int SPE7 = 16;
const int SPE8 = 17;
const int SPE9 = 18;
const int SPE10 = 19;
};
#endif
|
Voici la liste des modifications opérées :
- On rajoute class Sounds; en haut du fichier.
- on rajoute Sounds &sounds en argument à killPlayer() et playerHurts().
Fichier : player.cpp : Rajouter l'include et remplacer les fonctions modifiées :
|
//Rabidja 3 - nouvelle version intégralement en SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#include "player.h"
#include "map.h"
#include "input.h"
//Include à rajouter
#include "sounds.h"
using namespace std;
using namespace sf;
//Code coupé...
void Player::killPlayer(Sounds &sounds)
{
//On met le timer à 1 pour tuer le joueur intantanément
timerMort = 1;
//On joue le sound Fx
sounds.PlaySoundFx(sounds.DESTROY);
}
void Player::playerHurts(Sounds &sounds)
{
//Si le timer d'invincibilité est à 0
//on perd un coeur
if (invincibleTimer == 0)
{
life--;
invincibleTimer = 80;
//On joue le sound Fx
sounds.PlaySoundFx(sounds.DESTROY);
}
}
|
Voici la liste des modifications opérées :
- on rajoute #include "sounds.h" en haut du fichier.
- on rajoute Sounds &sounds en argument à killPlayer() et playerHurts().
- dans killPlayer() : on rajoute un appel à PlaySoundFx().
- dans playerHurts() : on rajoute un appel à PlaySoundFx().
Fichier : main.h : Remplacer le code précédent par :
|
//Legends of Meruvia - C++ / SFML 2
//Copyright / Droits d'auteur : www.meruvia.fr - Jérémie F. Bellanger
#include <cstdlib>
#include <iostream>
#include <SFML/Graphics.hpp>
#include "input.h"
#include "map.h"
#include "player.h"
#include "monster.h"
#include "sounds.h"
using namespace std;
using namespace sf;
//Fonctions
void update(Input &input, Map &map, Player &player, Monster monster[], Sounds &sounds);
void draw(sf::RenderWindow &window, Map &map, Player &player, Monster monster[]);
// Taille de la fenêtre : 800x480 pixels
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 480;
//Nombre max de monstres à l'écran
const int MONSTRES_MAX = 50;
|
Et voilà, passons maintenant au main(). Ici, on rajoute simplement : #include "sounds.h" et on met à jour le prototype de update() en rajoutant Sounds &sounds. ![]()
Fichier : main.cpp : Remplacer les fonctions main() et update() :
|
int main(int argc, char *argv[])
{
// Création d'une fenêtre en SFML
RenderWindow window(VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32),
"Meruvia - Big Tuto A-RPG/SFML2 - Chapitre 15 - www.meruvia.fr");
//On active la synchro verticale
window.setVerticalSyncEnabled(true);
//Instanciation des classes
Input input;
Map map;
Player player;
Sounds sounds;
//On instancie autant de classes que de monstres gérables
Monster monster[MONSTRES_MAX];
//On lance la musique en boucle
sounds.PlayMusic(true);
//On commence au premier niveau
map.setLevel(1);
map.changeLevel();
//On initialise le player
player.initialize(map);
player.setGold(100);
// Boucle infinie, principale, du jeu
while (window.isOpen())
{
// Gestion des inputs
input.gestionInputs(window);
//Updates
update(input, map, player, monster, sounds);
// Dessin - draw
draw(window, map, player, monster);
window.display();
}
// On quitte
return 0;
}
//Fonction de mise à jour du jeu : gère la logique du jeu
void update(Input &input, Map &map, Player &player, Monster monster[], Sounds &sounds)
{
//On met à jour le player
player.update(input, map);
//On met à jour les monstres un par un
for (int i = 0; i < map.getNombreMonstres(); i++)
{
if (monster[i].update(i, map, player, monster, sounds) == 2)
{
//Si l'update du monstre renvoie 2, c'est qu'il doit mourir :
//on copie à sa place le dernier monstre avant de retirer un monstre
monster[i].copy(monster[map.getNombreMonstres() - 1]);
map.setNombreMonstres(map.getNombreMonstres() - 1);
}
}
}
|
Et enfin, voici la liste des modifications opérées dans le main() :
- on instancie la classe Sounds : Sounds sounds;
- puis on lance la musique en boucle : sounds.PlayMusic(true);
- on rajoute l'argument sounds à update().
Puis dans la fonction update() :
- on met à jour ses arguments en rajoutant Sounds sounds.
- on rajoute l'argument sounds à monster.update().
Voilà, on compile et on lance le programme !
Et ?! Y'a du son !!
Hourra !
A nous les combats d'épée endiablés sur une musique épique ! ![]()
Bon, allez, je vous laisse sur un petit screenshot qui vous en dit long sur la musique de folie (signée Skrool, je rappelle !
) qui passe en arrière-plan, et je vous dis à bientôt ! ![]()

@ bientôt pour le chapitre 16 ! ![]()
Jay

English
Français 