I get what you mean. I tried putting the music in a switch condition as well. But that didn't change when the game state changed. Yours WAS a real answer, but that doesn't mean I don't want more information. ;D Here's my code.
This is outside the window.isOpen() loop:
sf::Music MenuMusic, PlayMusic;
if(!MenuMusic.openFromFile("images/menuscore.wav"))
return EXIT_FAILURE;
if(!PlayMusic.openFromFile("images/score.wav"))
return EXIT_FAILURE;
switch(CurrentState)
{
case MENU:
MenuMusic.play();
MenuMusic.setLoop(true);
break;
case PLAY:
PlayMusic.play();
PlayMusic.setLoop(true);
}
This is within the window loop, where (I think) music can't be played:
switch(CurrentState)
{
case MENU:
Menu MainMenu;
MainMenu.Show(window, menu, play, quit, CurrentState);
break;
case PLAY:
Play PlayGame;
PlayGame.Show(window, player, background, enemy, CurrentState);
break;
}
This is the minimal of it. The completeness of it is kinda messy. But this is sufficient, I think (I hope). How do I do it? Please tell me. Thanks.
I don't get you. Isn't the switch case inside the window loop where the game state changes? OK... Here's the complete and minimal code.
HEADERS.H:
#pragma once
#include<iostream>
#include<math.h>
#include<ctype.h>
#include<SFML/Audio.hpp>
#include<SFML/Graphics.hpp>
#include<SFML/Network.hpp>
#include<SFML/System.hpp>
#include<SFML/Window.hpp>
#include<list>
#include<string>
enum GameStates{MENU, INTRO, PLAY, GAMEOVER};
MENU.H:
#include "headers.h"
class Menu
{
public:
int Show(sf::RenderWindow &window, sf::Sprite &menu, sf::Sprite &play, sf::Sprite &quit, GameStates &CurrentState);
};
MENU.CPP:
#include "menu.h"
int Menu::Show(sf::RenderWindow &window, sf::Sprite &menu, sf::Sprite &play, sf::Sprite &quit, GameStates &CurrentState)
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::FloatRect BoundsOfPlay = play.getGlobalBounds();
sf::FloatRect BoundsOfExit = quit.getGlobalBounds();
float mouseX = (float)sf::Mouse::getPosition(window).x;
float mouseY = (float)sf::Mouse::getPosition(window).y;
if(BoundsOfPlay.contains(mouseX,mouseY))
CurrentState = PLAY;
if(BoundsOfExit.contains(mouseX, mouseY))
window.close();
}
window.draw(menu);
window.draw(play);
window.draw(quit);
return EXIT_SUCCESS;
}
PLAY.H:
#include "headers.h"
class Play
{
public:
int Show(sf::RenderWindow &window, sf::Sprite &menu, sf::Sprite &background, sf::Sprite &player, GameStates &CurrentState);
};
PLAY.CPP:
#include "play.h"
int Play::Show(sf::RenderWindow &window, sf::Sprite &menu, sf::Sprite &background, sf::Sprite &player, GameStates &CurrentState)
{
window.draw(background);
window.draw(player);
return EXIT_SUCCESS;
}
MAIN.CPP:
#include "menu.h"
#include "player.h"
int main()
{
// Initializing a Game State
GameStates CurrentState;
// Setting the Current Game State
CurrentState = MENU;
// Creating a Window
sf::VideoMode resolution;
sf::RenderWindow window(resolution.getDesktopMode(), "Game");
// Initializing Textures
sf::Texture playertex, backgroundtex, enemytex, menutex, playtex, quittex;
// Initializing Sprites
sf::Sprite player, background, menu, play, quit;
// Loading Menu Background Texture
if(!menutex.loadFromFile("images/menu.png"))
return EXIT_FAILURE;
// Setting Menu Background Texture to Menu Background Sprite
menu.setTexture(menutex);
menutex.setSmooth(true);
// Getting Bounding Box of the Menu Background Sprite
sf::FloatRect menubounds = menu.getGlobalBounds();
// Initializing Menu Background Orientation
menu.setOrigin(menubounds.width/2, menubounds.height/2);
menu.setScale(resolution.getDesktopMode().width/menubounds.width, resolution.getDesktopMode().width/menubounds.width);
menu.setPosition((float)resolution.getDesktopMode().width/2, (float)resolution.getDesktopMode().height/2);
// Loading Play Button Texture
if(!playtex.loadFromFile("images/play.png"))
return EXIT_FAILURE;
// Setting Play Button Texture to Play Button Sprite
play.setTexture(playtex);
// Getting Bounding Box of the Play Button Sprite
sf::FloatRect playbounds = play.getGlobalBounds();
// Initializing Play Button Orientation
play.setOrigin(playbounds.width/2, playbounds.height/2);
play.setPosition(resolution.getDesktopMode().width/2 - playbounds.width, resolution.getDesktopMode().height/2 + playbounds.height*2);
// Loading Exit Button Texture
if(!quittex.loadFromFile("images/quit.png"))
return EXIT_FAILURE;
// Setting Exit Button Texture to Exit Button Sprite
quit.setTexture(quittex);
// Getting Bounding Box of the Exit Button Sprite
sf::FloatRect exitbounds = quit.getGlobalBounds();
// Initializing Exit Button Orientation
quit.setOrigin(exitbounds.width/2, exitbounds.height/2);
quit.setPosition(resolution.getDesktopMode().width/2 + exitbounds.width, resolution.getDesktopMode().height/2 + exitbounds.height*2);
// Loading Player Texture
if(!playertex.loadFromFile("images/ship.png"))
return EXIT_FAILURE;
// Setting Player Texture to Player Sprite
player.setTexture(playertex);
// Getting Bounding Box of the Player Sprite
sf::FloatRect playerbounds = player.getGlobalBounds();
// Initializing Player Orientation
player.setOrigin(playerbounds.width/2, playerbounds.height/2);
player.setPosition((float)resolution.getDesktopMode().width/2, (float)(resolution.getDesktopMode().height - playerbounds.height/2));
// Loading Play Background Texture
if(!backgroundtex.loadFromFile("images/space.jpg"))
return EXIT_FAILURE;
// Setting Play Background Texture to Play Background Sprite
background.setTexture(backgroundtex);
// Getting Bounding Box of the Play Background Sprite
sf::FloatRect border = background.getGlobalBounds();
// Initializing Play Background Orientation
background.setOrigin(border.width/2, border.height/2);
background.setScale(resolution.getDesktopMode().width/border.width, resolution.getDesktopMode().height/border.height);
background.setPosition((float)resolution.getDesktopMode().width/2, (float)resolution.getDesktopMode().height/2);
sf::Music MenuMusic, PlayMusic;
if(!MenuMusic.openFromFile("images/menuscore.wav"))
return EXIT_FAILURE;
if(!PlayMusic.openFromFile("images/score.wav"))
return EXIT_FAILURE;
switch(CurrentState)
{
case MENU:
MenuMusic.play();
MenuMusic.setLoop(true);
break;
case PLAY:
PlayMusic.play();
PlayMusic.setLoop(true);
}
while(window.isOpen())
{
float timer = clock.restart().asSeconds();
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.key.code == sf::Keyboard::Escape)
window.close();
}
window.clear();
switch(CurrentState)
{
case MENU:
Menu MainMenu;
MainMenu.Show(window, menu, play, quit, CurrentState);
break;
case PLAY:
Play PlayGame;
PlayGame.Show(window, background, player, CurrentState);
break;
}
window.display();
}
return 0;
}
I apologize if the code is too long. And I know it is. But to just copy/paste it and test it right away, this is what I could give you. Again, apologies. Now, where might the problem be? Please tell me. Thank you.
OK... I have absolutely no idea what to reply to that. If the tone of this statement conveys rudeness, my apologies, but it is not. It's confusion. One person says minimal and complete is copy-paste-execute code. Another person says minimal should only be the problematic part. If that is the case, then my second post was minimal. Anyways, anything I say at this point may offend people, which I think already happened. So... Minimal.
#include<iostream>
#include<SFML/Audio.hpp>
#include<SFML/Graphics.hpp>
#include<SFML/Network.hpp>
#include<SFML/System.hpp>
#include<SFML/Window.hpp>
int main()
{
// Initializing a Game State
GameStates CurrentState;
// Setting the Current Game State
CurrentState = MENU;
// Creating a Window
sf::VideoMode resolution;
sf::RenderWindow window(resolution.getDesktopMode(), "Game", sf::Style::Fullscreen);
sf::Music MenuMusic, PlayMusic;
if(!MenuMusic.openFromFile("images/menuscore.wav"))
return EXIT_FAILURE;
if(!PlayMusic.openFromFile("images/score.wav"))
return EXIT_FAILURE;
switch(CurrentState)
{
case MENU:
MenuMusic.play();
MenuMusic.setLoop(true);
break;
case PLAY:
PlayMusic.play();
PlayMusic.setLoop(true);
}
while(window.isOpen())
{
window.clear();
switch(CurrentState)
{
case MENU:
Menu MainMenu;
MainMenu.Show(window, menu, play, quit, CurrentState);
break;
case PLAY:
Play PlayGame;
PlayGame.Show(window, background, player, CurrentState);
break;
}
window.display();
}
return 0;
}
Once again... If any of that seemed impolite, my apologies. No offence intended. Confusion intended.
OK... I kinda got it figured out... Not quite... But still... Here's what I got so far.
sf::Music MenuMusic, PlayMusic;
if(!MenuMusic.openFromFile("images/menuscore.wav"))
return EXIT_FAILURE;
if(!PlayMusic.openFromFile("images/score.wav"))
return EXIT_FAILURE;
MenuMusic.play();
MenuMusic.setLoop(true);
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
if(event.key.code == sf::Keyboard::Escape)
window.close();
if(event.type == sf::Event::MouseButtonPressed)
{
if(CurrentState == PLAY)
{
MenuMusic.stop();
PlayMusic.play();
PlayMusic.setLoop(true);
}
}
}
}
This works! Thankfully! But... The event for changing from MENU state to PLAY state is caused by a mouse click, so it works. But the change from PLAY to GAME OVER occurs due to collision between player and enemy sprites. sf::Event::MouseButtonPressed is a pre-defined event, so that worked. Can I define my own events for other state changes? Also... One mouse click goes to PLAY state. And after going to PLAY state, if I click mouse button again, it is distorting the music. Why is that? Please help.
Incidentally, based on the code snippets I saw before--and assuming you want your actual game to have similar code organization after you put some real content into it--it occurred to me a class like this might be handy.
class GameState {
Menu MainMenu;
Play PlayGame;
typedef enum {MENU, PLAY} state_type;
state_type state;
std::map<state_type, sf::Music> musics;
public:
GameState() {
//load all the musics, do whatever you need to do to setup the Menu and Play objects properly
state = MENU;
musics[MENU].play();
}
draw_me() {
switch(state) {
case MENU:
MainMenu.Show(window, menu, play, quit, CurrentState);
break;
case PLAY:
PlayGame.Show(window, background, player, CurrentState);
break;
}
}
switch_state(state_type new_state) {
switch(new_state) {
case MENU:
musics[state].stop();
state = MENU;
break;
case PLAY:
musics[state].stop();
state = PLAY;
break;
}
}
};
Just spent a minute scribbling this down, no testing or anything, so no guarantees.