R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
WaitingRoomMenu.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** r-type
4** File description:
5** WaitingRoomMenu - Menu for waiting before game starts
6*/
7
9#include <cstring>
10#include <sstream>
11#include "../common/Logger/Logger.hpp"
12
13namespace Game {
15 : BaseMenu(uiFactory), _graphics(graphics) {}
16
17 void WaitingRoomMenu::SetOnStartGame(std::function<void()> onStartGame) {
18 _onStartGame = std::move(onStartGame);
19 }
20
21 void WaitingRoomMenu::SetOnBack(std::function<void()> onBack) {
22 _onBack = std::move(onBack);
23 }
24
25 void WaitingRoomMenu::UpdatePlayerList(const std::vector<PlayerInfo> &players) {
26 _players = players;
28 }
29
30 void WaitingRoomMenu::SetRoomInfo(const std::string &roomName, uint32_t currentPlayers,
31 uint32_t maxPlayers) {
32 _roomName = roomName;
33 _currentPlayers = currentPlayers;
34 _maxPlayers = maxPlayers;
35 }
36
37 void WaitingRoomMenu::SetIsHost(bool isHost) {
38 _isHost = isHost;
39 // Re-initialize menu to show/hide Start Game button based on host status
40 Initialize();
41 }
42
43 void WaitingRoomMenu::SetIsSpectator(bool isSpectator) {
44 _isSpectator = isSpectator;
45 }
46
48 if (!_menu) {
49 return;
50 }
51
52 _menu->Clear();
53
54 float screenWidth = static_cast<float>(_graphics.GetScreenWidth());
55 float screenHeight = static_cast<float>(_graphics.GetScreenHeight());
56
57 // Add "Start Game" button (host only, bottom right)
58 const float buttonWidth = 180.0f;
59 const float buttonHeight = 50.0f;
60 const float margin = 20.0f;
61
62 // Only add Start Game button if this player is the host
63 if (_isHost) {
64 auto startGamePtr = _uiFactory.CreateButton();
65 startGamePtr->SetSize(buttonWidth, buttonHeight);
66 // Center the button horizontally to avoid chat widget conflict
67 float centerX = (screenWidth - buttonWidth) / 2.0f;
68 startGamePtr->SetPosition(centerX, screenHeight - margin - buttonHeight);
69 startGamePtr->SetText("START GAME");
70 startGamePtr->SetBackgroundColor(0xFF4CAF50); // Green
71 startGamePtr->SetHoverColor(0xFF66BB6A);
72 startGamePtr->SetTextColor(0xFFFFFFFF);
73 startGamePtr->SetCallback(WrapWithClickSound([this]() { OnStartGameClicked(); }));
74
75 _startGameButton = std::move(startGamePtr);
76 _menu->AddButton(_startGameButton);
77 }
78
79 // Add "Back" button (bottom left)
80 auto backPtr = _uiFactory.CreateButton();
81 backPtr->SetSize(buttonWidth, buttonHeight);
82 backPtr->SetPosition(margin, screenHeight - margin - buttonHeight);
83 backPtr->SetText("BACK");
84 backPtr->SetBackgroundColor(0xFF424242); // Dark gray
85 backPtr->SetHoverColor(0xFF616161);
86 backPtr->SetTextColor(0xFFFFFFFF);
87 backPtr->SetCallback(WrapWithClickSound([this]() { OnBackClicked(); }));
88
89 _backButton = std::move(backPtr);
90 _menu->AddButton(_backButton);
91
93 }
94
96 if (!_menu || !_menu->IsVisible()) {
97 return;
98 }
100 }
101
103 if (!_menu || !_menu->IsVisible()) {
104 return;
105 }
106
107 int screenWidth = _graphics.GetScreenWidth();
108
109 // Draw title
110 const char *title = "Waiting for Game Start";
111 int titleFontSize = 36;
112 int titleWidth = static_cast<int>(strlen(title) * titleFontSize * 0.5f);
113 int titleX = (screenWidth - titleWidth) / 2;
114 _graphics.DrawText(title, titleX, 30, titleFontSize, 0xFFFFFFFF);
115
116 // Draw room info
117 std::string roomInfo = _roomName + " [" + std::to_string(_currentPlayers) + "/" +
118 std::to_string(_maxPlayers) + " players]";
119 int infoFontSize = 20;
120 int infoWidth = static_cast<int>(roomInfo.length() * infoFontSize * 0.5f);
121 int infoX = (screenWidth - infoWidth) / 2;
122 _graphics.DrawText(roomInfo.c_str(), infoX, 80, infoFontSize, 0xFFAAAAAA);
123
124 // Draw "Players:" label
125 _graphics.DrawText("Players:", 50, 130, 22, 0xFFFFFFFF);
126
127 // Draw player list
128 float playerY = 160.0f;
129 int playerFontSize = 18;
130 int playerBoxHeight = 40;
131 int playerBoxWidth = 400;
132
133 for (size_t i = 0; i < _players.size(); ++i) {
134 const auto &player = _players[i];
135
136 // Determine color: yellow for host, white for others
137 uint32_t backgroundColor =
138 player.isHost ? 0xFFFFD700 : 0xFF505050; // Gold for host, gray for others
139 uint32_t textColor =
140 player.isHost ? 0xFF000000 : 0xFFFFFFFF; // Black text on gold, white on gray
141
142 // Draw player box
143 _graphics.DrawRectFilled(50, static_cast<int>(playerY), playerBoxWidth, playerBoxHeight,
144 backgroundColor);
145 _graphics.DrawRect(50, static_cast<int>(playerY), playerBoxWidth, playerBoxHeight, 0xFF888888);
146
147 // Draw player name
148 std::string playerLabel = player.playerName;
149 if (player.isHost) {
150 playerLabel += " (HOST)";
151 }
152 if (player.isSpectator) {
153 playerLabel += " [SPECTATOR]";
154 }
155
156 _graphics.DrawText(playerLabel.c_str(), 60, static_cast<int>(playerY) + 10, playerFontSize,
157 textColor);
158
159 playerY += playerBoxHeight + 10;
160 }
161
163 }
164
166 if (!_menu) {
167 return;
168 }
169
170 // Don't clear entire menu, just rebuild player display
171 // (buttons are persistent)
172
173 // Players are drawn in Render() method as text, not as UI buttons
174 }
175
177 LOG_INFO("[WaitingRoomMenu] Start Game button clicked");
178 if (_onStartGame) {
179 _onStartGame();
180 }
181 }
182
184 LOG_INFO("[WaitingRoomMenu] Back button clicked");
185 if (_onBack) {
186 _onBack();
187 }
188 }
189
190} // namespace Game
#define LOG_INFO(...)
Definition Logger.hpp:181
Base class for all menu implementations.
Definition BaseMenu.hpp:26
virtual void Update()
Update menu state (should be called every frame).
Definition BaseMenu.cpp:16
std::shared_ptr< UI::IMenu > _menu
Definition BaseMenu.hpp:101
virtual void Render()
Render menu (should be called every frame).
Definition BaseMenu.cpp:22
std::function< void()> WrapWithClickSound(std::function< void()> callback)
Wrap a callback to play click sound before executing.
Definition BaseMenu.cpp:48
UI::IUIFactory & _uiFactory
Definition BaseMenu.hpp:100
std::shared_ptr< UI::IButton > _startGameButton
void Update() override
Update menu state (should be called every frame).
void SetOnStartGame(std::function< void()> onStartGame)
Set callback triggered when Start Game button is clicked (host only)
std::function< void()> _onStartGame
WaitingRoomMenu(UI::IUIFactory &uiFactory, Graphics::IGraphics &graphics)
Graphics::IGraphics & _graphics
void Render() override
Render menu (should be called every frame).
void SetRoomInfo(const std::string &roomName, uint32_t currentPlayers, uint32_t maxPlayers)
Set room name and player count info.
std::shared_ptr< UI::IButton > _backButton
void UpdatePlayerList(const std::vector< PlayerInfo > &players)
Update the player list.
void SetOnBack(std::function< void()> onBack)
Set callback triggered when Back button is clicked.
std::vector< PlayerInfo > _players
void SetIsSpectator(bool isSpectator)
Set whether current player is spectator (shows spectator banner)
std::function< void()> _onBack
void Initialize() override
Initialize menu (must be implemented by derived classes).
void SetIsHost(bool isHost)
Set whether current player is host (enables Start Game button)
Abstract interface for graphics rendering operations.
Definition IGraphics.hpp:32
virtual void DrawRectFilled(int x, int y, int width, int height, unsigned int color)=0
Draw a filled rectangle.
virtual void DrawText(int fontHandle, const char *text, int x, int y, int fontSize, unsigned int color)=0
Draw text using a loaded font.
virtual void DrawRect(int x, int y, int width, int height, unsigned int color)=0
Draw a rectangle outline.
virtual int GetScreenHeight() const =0
Get the screen height (same as window height)
virtual int GetScreenWidth() const =0
Get the screen width (same as window width)
Abstract factory interface for creating UI elements.
virtual std::unique_ptr< IButton > CreateButton()=0
Create a button instance.