r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
gameSolo.cpp
Go to the documentation of this file.
2#include "ECS/Component.hpp"
4#include "Utils/Common.hpp"
7
8gme::GameSolo::GameSolo(const eng::id assignedId, const std::shared_ptr<eng::IRenderer> &renderer,
9 const std::shared_ptr<eng::IAudio> &audio, const int skinIndex, bool &showDebug)
10 : AScene(assignedId), m_renderer(renderer), m_audio(audio), m_skinIndex(skinIndex), m_showDebug(showDebug)
11{
12 auto &registry = AScene::getRegistry();
13
14 registry.onComponentAdded(
15 [this, &renderer, &audio, &registry](const ecs::Entity e, const std::type_info &type)
16 {
17 const auto *audioComp = registry.getComponent<ecs::Audio>(e);
18 const auto *colorComp = registry.getComponent<ecs::Color>(e);
19 const auto *fontComp = registry.getComponent<ecs::Font>(e);
20 const auto *rectComp = registry.getComponent<ecs::Rect>(e);
21 const auto *scaleComp = registry.getComponent<ecs::Scale>(e);
22 const auto *textComp = registry.getComponent<ecs::Text>(e);
23 const auto *textureComp = registry.getComponent<ecs::Texture>(e);
24 const auto *transform = registry.getComponent<ecs::Transform>(e);
25 const auto *hitBox = registry.getComponent<ecs::Hitbox>(e);
26
27 if (hitBox && transform)
28 {
29 renderer->createCircleShape({.name = "hitbox_" + std::to_string(e),
30 .radius = hitBox->radius,
31 .color = {.r = 255, .g = 0, .b = 0, .a = 100},
32 .x = transform->x + hitBox->offsetX,
33 .y = transform->y + hitBox->offsetY,
34 .outline_thickness = 1.0f,
35 .outline_color = {.r = 255, .g = 0, .b = 0, .a = 200}});
36 }
37 if (type == typeid(ecs::Text))
38 {
39 if (textComp && transform && fontComp)
40 {
41 // Only create font if not already loaded (cache)
42 if (this->m_loadedFonts.find(fontComp->id) == this->m_loadedFonts.end())
43 {
44 renderer->createFont(fontComp->id, fontComp->path);
45 this->m_loadedFonts.insert(fontComp->id);
46 }
47 renderer->createText(
48 {.font_name = fontComp->id,
49 .color = {.r = colorComp->r, .g = colorComp->g, .b = colorComp->b, .a = colorComp->a},
50 .content = textComp->content,
51 .size = textComp->font_size,
52 .x = transform->x,
53 .y = transform->y,
54 .name = textComp->id});
55 }
56 }
57 else if (type == typeid(ecs::Texture))
58 {
59 const float scale_x = scaleComp ? scaleComp->x : 1.F;
60 const float scale_y = scaleComp ? scaleComp->y : 1.F;
61
62 // Only create texture if not already loaded (cache)
63 if (this->m_loadedTextures.find(textureComp->id) == this->m_loadedTextures.end())
64 {
65 renderer->createTexture(textureComp->id, textureComp->path);
66 this->m_loadedTextures.insert(textureComp->id);
67 }
68
69 if (transform && textureComp)
70 {
71 if (rectComp)
72 {
73 renderer->createSprite(textureComp->id + std::to_string(e), textureComp->id, transform->x,
74 transform->y, scale_x, scale_y, static_cast<int>(rectComp->pos_x),
75 static_cast<int>(rectComp->pos_y), rectComp->size_x, rectComp->size_y);
76 }
77 else
78 {
79 renderer->createSprite(textureComp->id + std::to_string(e), textureComp->id, transform->x,
80 transform->y);
81 }
82 }
83 }
84 else if (type == typeid(ecs::Audio))
85 {
86 if (audioComp)
87 {
88 audio->createAudio(audioComp->path, audioComp->volume, audioComp->loop,
89 audioComp->id + std::to_string(e));
90 }
91 }
92 });
93
94 registry.createEntity().with<ecs::Score>("score", 0).build();
95
96 m_playerEntity = createPlayer(registry);
97 m_stageManager = std::make_unique<StageManager>();
98
99 // Preload all common textures to avoid lag spikes during gameplay
101
102 const auto beginSoundEntity = registry.createEntity()
103 .with<ecs::Audio>("game_begin", utl::Path::Audio::AUDIO_BEGIN, 10.0F, true, true)
104 .build();
105}
106
108{
109 // Preload all textures that will be used during gameplay
110 // This prevents lag when entities are first created
111
112 std::vector<std::pair<std::string, std::string>> texturesToLoad = {
118
119 for (const auto &[id, path] : texturesToLoad)
120 {
121 if (m_loadedTextures.find(id) == m_loadedTextures.end())
122 {
123 m_renderer->createTexture(id, path);
124 m_loadedTextures.insert(id);
125 }
126 }
127}
128
130{
131 auto *playerTransform = registry.getComponent<ecs::Transform>(m_playerEntity);
132 auto *playerVelocity = registry.getComponent<ecs::Velocity>(m_playerEntity);
133
134 if ((playerTransform == nullptr) || (playerVelocity == nullptr))
135 {
136 return;
137 }
138
139 constexpr float diagonal_speed =
141
142 playerVelocity->x = 0.0f;
143 playerVelocity->y = 0.0f;
144
145 const bool up = m_keysPressed[eng::Key::Up];
146 const bool down = m_keysPressed[eng::Key::Down];
147 const bool left = m_keysPressed[eng::Key::Left];
148 if (const bool right = m_keysPressed[eng::Key::Right]; up && right)
149 {
150 playerVelocity->x = diagonal_speed;
151 playerVelocity->y = -diagonal_speed;
152 }
153 else if (up && left)
154 {
155 playerVelocity->x = -diagonal_speed;
156 playerVelocity->y = -diagonal_speed;
157 }
158 else if (down && right)
159 {
160 playerVelocity->x = diagonal_speed;
161 playerVelocity->y = diagonal_speed;
162 }
163 else if (down && left)
164 {
165 playerVelocity->x = -diagonal_speed;
166 playerVelocity->y = diagonal_speed;
167 }
168 else
169 {
170 if (up)
171 playerVelocity->y = -utl::GameConfig::Player::SPEED;
172 if (down)
173 playerVelocity->y = utl::GameConfig::Player::SPEED;
174 if (left)
175 playerVelocity->x = -utl::GameConfig::Player::SPEED;
176 if (right)
177 playerVelocity->x = utl::GameConfig::Player::SPEED;
178 }
179
180 playerTransform->x += playerVelocity->x * dt;
181 playerTransform->y += playerVelocity->y * dt;
182 playerTransform->x = std::max(playerTransform->x, 0.F);
183 playerTransform->y = std::max(playerTransform->y, 0.F);
184
185 auto [width, height] = m_renderer->getWindowSize();
186 const float maxX =
188 const float maxY =
190
191 playerTransform->x = std::min(playerTransform->x, maxX);
192 playerTransform->y = std::min(playerTransform->y, maxY);
193}
194
195void gme::GameSolo::update(const float dt, const eng::WindowSize &size)
196{
197 auto &reg = getRegistry();
198 handlePlayerInputs(reg, dt);
199 m_stageManager->update(reg, dt, size);
200}
201
203{
204 switch (event.type)
205 {
207 if (event.key == eng::Key::Down)
208 {
209 m_keysPressed[eng::Key::Down] = true;
210 }
211 if (event.key == eng::Key::Up)
212 {
213 m_keysPressed[eng::Key::Up] = true;
214 }
215 if (event.key == eng::Key::Left)
216 {
217 m_keysPressed[eng::Key::Left] = true;
218 }
219 if (event.key == eng::Key::Right)
220 {
221 m_keysPressed[eng::Key::Right] = true;
222 }
223 break;
224
226 if (event.key == eng::Key::Down)
227 {
228 m_keysPressed[eng::Key::Down] = false;
229 }
230 if (event.key == eng::Key::Up)
231 {
232 m_keysPressed[eng::Key::Up] = false;
233 }
234 if (event.key == eng::Key::Left)
235 {
236 m_keysPressed[eng::Key::Left] = false;
237 }
238 if (event.key == eng::Key::Right)
239 {
240 m_keysPressed[eng::Key::Right] = false;
241 }
242 break;
243
244 default:
245 break;
246 }
247}
248
250{
251 auto &registry = getRegistry();
252
253 if (auto *playerRect = registry.getComponent<ecs::Rect>(m_playerEntity); playerRect != nullptr)
254 {
255 const float skinPosY = m_skinIndex * utl::GameConfig::Player::SPRITE_HEIGHT;
256 playerRect->pos_y = skinPosY;
257 }
258}
259
261{
262 auto [offsetX, offsetY] = utl::calculateHitboxOffsets(
264
265 return registry.createEntity()
266 .with<ecs::Transform>("player_transform", 200.0F, 100.0F, 0.F)
267 .with<ecs::Velocity>("player_velocity", 0.F, 0.F)
268 .with<ecs::Rect>("player_rect", 0.F, 0.F, static_cast<int>(utl::GameConfig::Player::SPRITE_WIDTH),
270 .with<ecs::Scale>("player_scale", utl::GameConfig::Player::SCALE, utl::GameConfig::Player::SCALE)
271 .with<ecs::Texture>("player_texture", utl::Path::Texture::TEXTURE_PLAYER)
272 .with<ecs::Player>("player", true)
273 .with<ecs::BeamCharge>("beam_charge", 0.0f, utl::GameConfig::Beam::MAX_CHARGE)
274 .with<ecs::Hitbox>("player_hitbox", utl::GameConfig::Hitbox::PLAYER_RADIUS, offsetX, offsetY)
275 .build();
276}
This file contains the component definitions.
Configuration constants for the multiplayer game.
This file contains the solo Game scene.
Utility functions for hitbox calculations.
This file contains the Audio interface.
EntityBuilder & with(Args &&...args)
Definition Registry.hpp:40
Class for managing entities and their components.
Definition Registry.hpp:25
EntityBuilder createEntity()
Definition Registry.hpp:53
T * getComponent(Entity e)
Definition Registry.hpp:71
void event(const eng::Event &event) override
Definition gameSolo.cpp:202
void update(float dt, const eng::WindowSize &size) override
Definition gameSolo.cpp:195
std::unique_ptr< StageManager > m_stageManager
Definition GameSolo.hpp:55
void handlePlayerInputs(ecs::Registry &registry, float dt)
Definition gameSolo.cpp:129
void updatePlayerSkin()
Definition gameSolo.cpp:249
std::unordered_set< std::string > m_loadedTextures
Definition GameSolo.hpp:58
static ecs::Entity createPlayer(ecs::Registry &registry)
Definition gameSolo.cpp:260
void preloadCommonTextures()
Definition gameSolo.cpp:107
ecs::Entity m_playerEntity
Definition GameSolo.hpp:50
GameSolo(eng::id assignedId, const std::shared_ptr< eng::IRenderer > &renderer, const std::shared_ptr< eng::IAudio > &audio, int skinIndex, bool &showDebug)
Definition gameSolo.cpp:8
std::unordered_set< std::string > m_loadedFonts
Definition GameSolo.hpp:59
This file contains common definitions and constants.
std::uint32_t Entity
Definition Entity.hpp:13
unsigned int id
Definition IScene.hpp:20
constexpr float MAX_CHARGE
constexpr float PLAYER_RADIUS
constexpr float SCALE
constexpr float DIAGONAL_SPEED_MULTIPLIER
constexpr float SPEED
constexpr float SPRITE_HEIGHT
constexpr float SPRITE_WIDTH
constexpr auto AUDIO_BEGIN
Definition Common.hpp:91
constexpr auto TEXTURE_STAGE1_FLOOR
Definition Common.hpp:124
constexpr auto TEXTURE_SHOOT
Definition Common.hpp:115
constexpr auto TEXTURE_STAGE1_CEILING
Definition Common.hpp:125
constexpr auto TEXTURE_PLAYER
Definition Common.hpp:114
constexpr auto TEXTURE_SHOOT_CHARGED
Definition Common.hpp:116
std::pair< float, float > calculateHitboxOffsets(const float spriteWidth, const float spriteHeight, const float scale)
Calculate hitbox offsets to center the hitbox on the sprite.
std::string id
Definition Component.hpp:15
EventType type