Jump to content
  • Advertisement
Sign in to follow this  
louie999

[SFML] Menu system not working properly

This topic is 990 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I was trying to make a menu system for the game I'm making, it was almost good, until I discovered this annoying problem.

#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <functional>
#include <SFML/Graphics.hpp>
#include "menuhandler.hpp"

const int _WIDTH_ = 800;
const int _HEIGHT_ = 600;

int main()
{
    sf::RenderWindow Main_Window(sf::VideoMode(_WIDTH_, _HEIGHT_), "Total War");
    Gui::FontLoader fontLoader;
    fontLoader.loadFont("FREESCPT.TTF");

    Gui::GameState mainMenu("MainMenu");
    Gui::Button* bPlay = Gui::Button::New(mainMenu, 15.f, 100.f, 50, 20, "Play", fontLoader.font, 30);
    Gui::Button* bQuit = Gui::Button::New(mainMenu, 15.f, 200.f, 50, 20, "Quit", fontLoader.font, 30);

    while (Main_Window.isOpen())
    {
        sf::Event event;
        while (Main_Window.pollEvent(event))
        {
            switch (event.type)
            {
                case sf::Event::Closed:
                    Main_Window.close();
                    break;
                default:
                    break;
            }
        }
        Gui::Event evn;
        while (Gui::Base::checkEvent(Main_Window, evn))
        {
            if (evn.type == Gui::Event::EVENT::MOUSE_ENTER)
            {
                if (evn.object == bPlay)
                {
                    std::cout << "Mouse is in play button!";
                }
                if (evn.object == bQuit)
                {
                    std::cout << "Mouse is in quit button!";
                }
            }
        }
        Main_Window.clear(sf::Color(0, 200, 200, 150));
        Gui::Base::drawGUI(Main_Window);
        Main_Window.display();
    }
}

It properly displays those buttons(bPlay and bQuit) it also displays the message when the mouse is on bPlay button but it doesn't display the message when it's on the bQuit button, it only seems to pay attention to the first button created(in this case it's bPlay). I have no idea what caused this problem o.O here's the rest of my code:(menuhandler.hpp and menuhandler.cpp)

#pragma once
#include "gamestate.hpp"

namespace Gui
{
    class FontLoader
    {
        public:
            sf::Font font;

            FontLoader();
            bool loadFont(sf::String filepath);
    };

    class Base;
    class Button;

    class Event
    {
        public:
            Base* object;
            enum EVENT {NO_EVENT, MOUSE_ENTER, MOUSE_CLICKED};
            EVENT type = NO_EVENT;
            Event();
            bool operator==(Gui::Button& button);
    };

    class Base
    {
        public:
            static std::vector<std::unique_ptr<Base>> container;
            float PosX;
            float PosY;
            float Width;
            float Height;
            sf::String Text;
            sf::Font Font;
            unsigned int TextSize;
            Gui::GameState State;
            sf::IntRect MouseArea;
            sf::Text TextDisplay;
            sf::Sprite SprDisplay;
            bool show = true;

            Base();
            bool isMouseIn(sf::RenderWindow &win);
            bool isClicked(sf::RenderWindow &win);
            static bool checkEvent(sf::RenderWindow& win, Event& event);
            static void drawGUI(sf::RenderWindow& win);
            void setPos(float newX, float newY);
            void setWidth(float newWidth);
            void setHeight(float newHeight);
            void setShow(bool b);
    };

    class Button : public Base
    {
        public:
            Button(Gui::GameState& gameState, float x, float y, float width, float height, sf::String text, sf::Font& font, unsigned int textSize);
            static Button* New(Gui::GameState& gameState, float x, float y, float width, float height, sf::String text, sf::Font& font, unsigned int textSize);
    };
}

#include <SFML/Graphics.hpp>
#include <stdarg.h>
#include <vector>
#include <memory>
#include <functional>
#include <iostream>
#include "menuhandler.hpp"

bool Gui::Event::operator==(Gui::Button& button)
{
    if (*this == button)
    {
        return true;
    }
    return false;
}

Gui::FontLoader::FontLoader() {}

bool Gui::FontLoader::loadFont(sf::String filepath)
{
    if (!font.loadFromFile("Art/Fonts/" + filepath))
    {
        return false;
    }
    else
        return true;
}

std::vector<std::unique_ptr<Gui::Base>> Gui::Base::container;

Gui::Event::Event() {}

Gui::Base::Base() {}

bool Gui::Base::isMouseIn(sf::RenderWindow &win)
{
    sf::Vector2i mCoords = sf::Mouse::getPosition(win);
    auto w = this->PosX + this->Width;
    auto h = this->PosY + this->Height;

    if (mCoords.x >= this->PosX and mCoords.y >= this->PosY and mCoords.x <= w and mCoords.y <= h)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool Gui::Base::isClicked(sf::RenderWindow &win)
{
    if (this->isMouseIn(win) and sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        return true;
    }
    return false;
}

bool Gui::Base::checkEvent(sf::RenderWindow &win, Event &event)
{
    for (auto &gui: container)
    {
        event.object = nullptr;
        event.type = Gui::Event::EVENT::NO_EVENT;
        if (gui->isMouseIn(win))
        {
            event.object = gui.get();
            event.type = Gui::Event::MOUSE_ENTER;
            return true;
        }
        if (gui->isClicked(win))
        {
            event.object = gui.get();
            event.type = Gui::Event::MOUSE_CLICKED;
            return true;
        }
        return false;
    }
    return false;
}

void Gui::Base::drawGUI(sf::RenderWindow& win)
{
    for (auto &gui: container)
    {
        if (gui->show)
            win.draw(gui->TextDisplay);
    }
}

void Gui::Base::setShow(bool b)
{
    this->show = b;
}

Gui::Button::Button(Gui::GameState& gameState, float x, float y, float width, float height, sf::String text, sf::Font& font, unsigned int textSize)
{
    State = gameState;
    PosX = x;
    PosY = y;
    Width = width;
    Height = height;
    Text = text;
    Font = font;
    TextSize = textSize;
    TextDisplay.setString(Text);
    TextDisplay.setFont(Font);
    TextDisplay.setCharacterSize(TextSize);
    TextDisplay.setPosition(PosX, PosY);
}

Gui::Button* Gui::Button::New(Gui::GameState& gameState, float x, float y, float width, float height, sf::String text, sf::Font& font, unsigned int textSize)
{
    auto *newObj = new Gui::Button(gameState, x, y, width, height, text, font, textSize);
    Gui::Base::container.push_back(std::unique_ptr<Gui::Button>(newObj));
    std::cout << "Created object with address of: " << newObj << std::endl;
    return newObj;
}

Thanks in advance :S

Share this post


Link to post
Share on other sites
Advertisement
Make sure to flush the cout stream object to make sure that you can see what has been written.
 
std::cout << "Mouse is in quit button!" << std::flush;

If you use std::endl you don't need to use std::flush because it will flush automatically.

I think the real problem is that you return at the end of the loop in checkEvent. Edited by Wooh

Share this post


Link to post
Share on other sites

Make sure to flush the cout stream object to make sure that you can see what has been written.
 

std::cout << "Mouse is in quit button!" << std::flush;
If you use std::endl you don't need to use std::flush because it will flush automatically.

I think the real problem is that you return at the end of the loop in checkEvent.

 

Thanks dude :D, I removed that "return false" inside the loop and it works properly :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!