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