SFML 2.0 launcher problem

As i mentioned in another topic (http://www.cplusplus.com/forum/general/109954/) I am making a launcher for a game and it is much further along but when i click something that usually closes it, it just restarts. it does it 2 - 4 times and then works as normal. what is my issue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
char Menu()
{
    sf::Music theme_music;

    if(!theme_music.openFromFile("Data/Sounds/Launcher music.ogg"))
        return 'Q';

    sf::RenderWindow launcher;
    launcher.create(sf::VideoMode(866, 468),
    "Launcher", sf::Style::Titlebar);
    bool exit = false, play = false, play1 = false, mage = false, warrior = false;

    if(!arial.loadFromFile("Data/Fonts/arial.ttf"))
        return 'Q';

    sf::Text Play("Play", arial, 50), Quit("Quit", arial, 50), Select("Select Your Class", arial, 50);
    Select.setPosition(launcher.getSize().x/4, 0);
    Select.setColor(sf::Color::Blue);

    sf::Texture button;
    sf::Texture background;
    if (!button.loadFromFile("Data/Images/Button.png"))
        return 'Q';

    if (!background.loadFromFile("Data/Images/Epic Background.png"))
        return 'Q';

    theme_music.setLoop(true);
    theme_music.setVolume(25);
    theme_music.play();

    sf::Sprite button1, button2, wallpaper;
    button1.setTexture(button);
    button1.setColor(sf::Color::Green);
    button1.setPosition(sf::Vector2f(0, launcher.getSize().y/2 - button.getSize().y));

    Play.setPosition(button1.getPosition().x + 40, button1.getPosition().y);

    button2.setTexture(button);
    button2.setPosition(sf::Vector2f(launcher.getSize().x - button.getSize().x, launcher.getSize().y/2 - button.getSize().y));
    button2.setColor(sf::Color::Green);

    Quit.setPosition(button2.getPosition().x + 40, button1.getPosition().y);

    wallpaper.setTexture(background);

    while (launcher.isOpen())
    {
        sf::Event event;
        while(launcher.pollEvent(event))
        {
        }

            while (exit == true)
            {
                cout << "q";
                return 'q';
            }

            while (mage == true)
            {
                cout << "m";
                return 'm';
            }

            while (warrior == true)
            {
                cout << "w";
                return 'w';
            }

            while(sf::Mouse::isButtonPressed(sf::Mouse::Left) && sf::Mouse::getPosition(launcher).x <=
            button1.getPosition().x + button.getSize().x && sf::Mouse::getPosition(launcher).y <= button1.getPosition().y +
            button.getSize().y && sf::Mouse::getPosition(launcher).x >= button1.getPosition().x && play != true && exit != true)
            {
                play1 = true;
            }
            if (play1 == true)
            {
                play = true;
            }

            while(sf::Mouse::isButtonPressed(sf::Mouse::Left) && sf::Mouse::getPosition(launcher).x <=
            button2.getPosition().x + button.getSize().x && sf::Mouse::getPosition(launcher).y <= button2.getPosition().y +
            button.getSize().y && sf::Mouse::getPosition(launcher).x >= button2.getPosition().x && play != true && exit != true)
            {
                exit = true;
            }

            launcher.clear();
            launcher.draw(wallpaper);
            launcher.draw(button1);
            launcher.draw(Play);
            launcher.draw(button2);
            launcher.draw(Quit);
            if (play == true)
            {
                launcher.draw(Select);
            }
            launcher.display();


            if (play == true)
            {
                Play.setString("Mage");
                Quit.setString("Warrior");
                Quit.setPosition(button2.getPosition().x + 18, button1.getPosition().y);
            }

            while(sf::Mouse::isButtonPressed(sf::Mouse::Left) && sf::Mouse::getPosition(launcher).x <=
            button1.getPosition().x + button.getSize().x && sf::Mouse::getPosition(launcher).y <= button1.getPosition().y +
            button.getSize().y && sf::Mouse::getPosition(launcher).x >= button1.getPosition().x && play == true && exit != true)
            {
                mage = true;
            }

            while(sf::Mouse::isButtonPressed(sf::Mouse::Left) && sf::Mouse::getPosition(launcher).x <= button2.getPosition().x
            + button.getSize().x && sf::Mouse::getPosition(launcher).y <= button2.getPosition().y + button.getSize().y &&
            sf::Mouse::getPosition(launcher).x >= button2.getPosition().x && play == true && exit != true)
            {
                warrior = true;
            }
        }
    }




changelog:
Updated code
Last edited on
I'm not sure exactly what the problem with your code is. I found it too much of a pain to read. Here is what a more typical menu might look like, with the Button stuff encapsulated into a (minimal) class, because the graphic place holders I used were different sizes than yours.

Pardon the length.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include <string>
#include <stdexcept>

#include <SFML/Graphics.hpp>

const char* font_name = "arial.ttf";
const char* button_name = "button.png";
const char* background_name = "epicbackground.png";

class Button : public sf::Drawable
{
public:
    Button(const sf::String& text, sf::Font& font, std::size_t fontSize,  sf::Texture& texture)
        : _buttonBase(texture), _text(text,font, fontSize)
    {
        _positionText();
    }

    sf::Vector2f getPosition() const
    {
        return _buttonBase.getPosition();
    }

    sf::Vector2f getSize() const
    {
        return sf::Vector2f(_buttonBase.getLocalBounds().width, _buttonBase.getLocalBounds().height);
    }

    bool contains(const sf::Vector2f& pos)
    {
        return _buttonBase.getGlobalBounds().contains(pos);      
    }

    void setPosition(const sf::Vector2f& pos)
    {
        _buttonBase.setPosition(pos);
        _positionText();
    }

    void setText(const sf::String& text)
    {
        _text.setString(text);
        _positionText();
    }

    void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        target.draw(_buttonBase, states);
        target.draw(_text, states);
    }

private:

    // Positions text so that it is centered on the button.  If the text would be larger
    // than the button, scales the text to fit - could be done more gracefully with a combination
    // of character size adjustment/scaling 
    void _positionText()
    {
        const float minBuffer = 5.0f;

        const float buttonWidth = getSize().x;
        const float buttonHeight = getSize().y;

        float textWidth = _text.getLocalBounds().width;
        float textHeight = _text.getLocalBounds().height;

        if (textWidth > buttonWidth || textHeight > buttonHeight)
        {
            float widthScaleFactor = textWidth > buttonWidth ? (buttonWidth - minBuffer) / textWidth : 1.0f;
            float heightScaleFactor = textHeight > buttonHeight ? (buttonHeight - minBuffer) / textHeight : 1.0f;

            float scaleFactor = std::min(widthScaleFactor, heightScaleFactor);

            _text.scale(scaleFactor, scaleFactor);
            textWidth = _text.getLocalBounds().width;
            textHeight = _text.getLocalBounds().height;
        }

        float xOffset = (buttonWidth - textWidth) / 2.0f  - _text.getLocalBounds().left ;
        float yOffset = (buttonHeight - textHeight) / 2.0f - _text.getLocalBounds().top ;

        sf::Vector2f buttonPosition = getPosition();
        _text.setPosition(buttonPosition.x + xOffset, buttonPosition.y + yOffset);
    }

    sf::Sprite _buttonBase;
    sf::Text _text;
};

enum MenuReturn { Quit, Mage, Warrior };

MenuReturn Menu()
{
    // Prepare launcher window

    const unsigned launcherWidth = sf::VideoMode::getDesktopMode().width - 500;
    const unsigned launcherHeight = sf::VideoMode::getDesktopMode().height - 300;
    sf::RenderWindow launcher(sf::VideoMode(launcherWidth, launcherHeight), "Launcher", sf::Style::Titlebar);


    // load menu resources
    sf::Font arial;
    if (!arial.loadFromFile(font_name))
        throw std::runtime_error(std::string("Unable to load font from file \"") + font_name + '"');

    sf::Texture buttonTexture;
    if (!buttonTexture.loadFromFile(button_name))
        throw std::runtime_error(std::string("Unable to load texture from file \"") + button_name + '"');

    sf::Texture backgroundTexture;
    if (!backgroundTexture.loadFromFile(background_name))
        throw std::runtime_error(std::string("Unable to load texture from file \"") + background_name + '"');
    backgroundTexture.setSmooth(true);

    sf::Sprite wallpaper(backgroundTexture); //stretch to fit
    wallpaper.scale(launcherWidth / wallpaper.getGlobalBounds().width, launcherHeight / wallpaper.getGlobalBounds().height);

    Button leftButton("Play", arial, 50, buttonTexture);
    leftButton.setPosition(sf::Vector2f(0, launcherHeight / 2.0f - leftButton.getSize().y));

    Button rightButton("Quit", arial, 50, buttonTexture);
    rightButton.setPosition(sf::Vector2f(launcherWidth - rightButton.getSize().x, launcherHeight / 2.0f - rightButton.getSize().y));

    sf::Text selectText("Select Your Class", arial, 50);
    selectText.setPosition((launcherWidth / 2.0f) - (selectText.getLocalBounds().width / 2.0f), 0);
    selectText.setColor(sf::Color::Blue);

    // set up state:
    enum MenuState { PlayOrQuit, SelectClass };
    MenuState state = PlayOrQuit;

    while (launcher.isOpen())
    {
        sf::Event event;
        while (launcher.pollEvent(event))
        {
            if (event.type == sf::Event::MouseButtonReleased)
            {
                if (leftButton.contains(sf::Vector2f(event.mouseButton.x, event.mouseButton.y)))
                {
                    if (state == PlayOrQuit)
                    {
                        state = SelectClass;
                        leftButton.setText("Mage");
                        rightButton.setText("Warrior");
                    }
                    else
                    {
                        launcher.close();
                        return Mage;
                    }
                }

                if (rightButton.contains(sf::Vector2f(event.mouseButton.x, event.mouseButton.y)))
                {
                    if (state == PlayOrQuit)
                    {
                        launcher.close();
                        return Quit;
                    }
                    else
                    {
                        launcher.close();
                        return Warrior;
                    }
                }
            }
        }


        launcher.clear();
        launcher.draw(wallpaper);

        if (state == SelectClass)
            launcher.draw(selectText);

        launcher.draw(leftButton);
        launcher.draw(rightButton);
        launcher.display();
    }

    return Quit;
}

#include <iostream>
#include <cstdlib>

int main()
{
    try {
        MenuReturn retVal = Menu();
        // do something with retVal
    }

    catch (std::exception& ex)
    {
        std::cerr << ex.what() << '\n';
        return EXIT_FAILURE;
    }
}
Last edited on
Topic archived. No new replies allowed.