RType
GameScene.cpp
Go to the documentation of this file.
1 /*
2 ** EPITECH PROJECT, 2023
3 ** RType
4 ** File description:
5 ** GameScene.cpp
6 */
7 
8 #include "GameScene.hpp"
9 #include "ClientCore.hpp"
10 #include <utility>
11 #include <iostream>
12 #include <sstream>
13 #include <string>
14 
15 /**
16  * @brief Construct a new Game Scene:: Game Scene object
17  *
18  * @param clientCore
19  * @param socket
20  */
21 GameScene::GameScene(ClientCore *clientCore, std::shared_ptr<ClientSocket> socket) :
22  AScene(clientCore),
24 {
27 }
28 
29 /**
30  * @brief init_scene, init the scene
31  */
33 {
34  std::shared_ptr<TextComponent> text_ping = std::make_shared<TextComponent>(_clientCore, _socket);
35  std::shared_ptr<TextComponent> text_score = std::make_shared<TextComponent>(_clientCore, _socket);
36  // std::shared_ptr<SpriteComponent> sprite = std::make_shared<SpriteComponent>(_clientCore, _socket);
37  std::shared_ptr<MusicComponent> music = std::make_shared<MusicComponent>(_clientCore, _socket);
38  std::shared_ptr<SoundComponent> sound_new_player = std::make_shared<SoundComponent>(_clientCore, _socket);
39  std::shared_ptr<SoundComponent> sound_player_left = std::make_shared<SoundComponent>(_clientCore, _socket);
40  std::shared_ptr<TextComponent> text_event = std::make_shared<TextComponent>(_clientCore, _socket);
41 
42  music->setSound("../src/client/assets/musics/thisgirl.ogg");
43  music->setVolume(10);
44 
45  text_ping->setAttribute("text ping");
46  text_ping->setText("");
47  text_ping->setPosition(sf::Vector2f(0, 550));
48  text_score->setAttribute("text score");
49  text_score->setText("Score: 0");
50  text_score->setPosition(sf::Vector2f(650, 550));
51 
52  text_event->setAttribute("text event");
53  text_event->setText("");
54  text_event->setPosition(sf::Vector2f(425, 0));
55 
56  // sprite->setAttribute("Player");
57 
58  sound_new_player->setAttribute("new player");
59 
60  sound_player_left->setAttribute("player left");
61 
62 
63  // addComponent(sprite);
64  addComponent(music);
65 
66  addComponent(text_ping);
67  addComponent(text_score);
68  addComponent(sound_new_player);
69  addComponent(sound_player_left);
70  addComponent(text_event);
71 }
72 
73 /**
74  * @brief receiveData, receive data from the server
75  */
77 {
78  std::tuple<std::unique_ptr<Packet>, int> packet = _socket->receive();
79  std::unique_ptr<Packet> p = std::move(std::get<0>(packet));
80  while (p != nullptr) {
81  if (p->code == ELEMENT) {
82  auto *drawable = static_cast<DrawablePacket *>(p->data);
83  for (auto &component : _components) {
84  if (component->getType() == ComponentType::SPRITE) {
85  char *attributechar = static_cast<char *>(malloc(16));
86  std::memset(attributechar, 0, 16);
87  std::memcpy(attributechar, &drawable->attribute, 8);
88  std::memcpy(attributechar + 8, &drawable->attribute2, 8);
89  std::string attributeString(attributechar);
90  std::string componentAttribute = component->getAttribute();
91  if (component->getAttribute() == attributeString) {
92  // std::cout << "element: " << drawable->rectLeft << " " << drawable->rectTop << " "
93  // << drawable->rectWidth << " " << drawable->rectHeight << std::endl;
94  // sprite->setTexture(getTextureByType(element->type));
95  auto *sprite = dynamic_cast<SpriteComponent *>(component.get());
96  sprite->setPosition({drawable->x, drawable->y});
97  sprite->setSize({drawable->sizeHorizontal, drawable->sizeVertical});
98  sprite->setRect(
99  {drawable->rectLeft, drawable->rectTop, drawable->rectWidth, drawable->rectHeight});
100  }
101  if (component->getAttribute() == "sprite enemy") {
102  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::ENEMY));
103  }
104  if (component->getAttribute() == "sprite bullet") {
105  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BULLET));
106  }
107  if (component->getAttribute() == "sprite floor bg") {
108  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::FLOOR_BACKGROUND));
109  }
110  if (component->getAttribute() == "sprite roof bg") {
111  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::ROOF_BACKGROUND));
112  }
113  if (component->getAttribute() == "sprite bg1") {
114  dynamic_cast<SpriteComponent *>(component.get())
115  ->setTexture(getTextureByType(Type::BACKGROUND1));
116  }
117  if (component->getAttribute() == "sprite bg2") {
118  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BACKGROUND2));
119  }
120  if (component->getAttribute() == "sprite bg3") {
121  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BACKGROUND3));
122  }
123  if (component->getAttribute() == "sprite bg4") {
124  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BACKGROUND4));
125  }
126  if (component->getAttribute() == "sprite boss") {
127  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BOSS));
128  }
129  if (component->getAttribute() == "boss attack") {
130  dynamic_cast<SpriteComponent *>(component.get())->setTexture(getTextureByType(Type::BOSS_BULLET));
131  }
132  }
133  }
134  }
135  if (p->code == HEARTBEAT) {
136  timeval timerecv{};
137  timeval now{};
138  gettimeofday(&now, nullptr);
139  timerecv = *static_cast<timeval *>(p->data);
140  timersub(&now, &timerecv, &_pingTime);
141 
142  for (auto &component : _components) {
143  if (component->getType() == ComponentType::TEXT) {
144  if (component->getAttribute() == "text ping") {
145  dynamic_cast<TextComponent *>(component.get())
146  ->setText("Ping: " + std::to_string(_pingTime.tv_sec * 1000 + _pingTime.tv_usec / 1000) +
147  ", " + std::to_string(_pingTime.tv_usec % 1000) + "ms");
148  }
149  }
150  }
151  }
152 
153  if (p->code == MESSAGE) {
154  std::string attribute = static_cast<char *>(p->data);
155  if (attribute.find("Score") != std::string::npos) {
156  for (auto &component : _components) {
157  if (component->getType() == ComponentType::TEXT) {
158  if (component->getAttribute() == "text score") {
159  std::istringstream iss(attribute);
160  std::string prefix;
161  int score;
162 
163  // Lire la partie "Score: " de la chaîne
164  iss >> prefix;
165 
166  // Si le préfixe est "Score:", lire le nombre
167  if (prefix == "Score:") {
168  iss >> score;
169  }
170  std::cout << "Score: " << std::to_string(score) << std::endl;
171  dynamic_cast<TextComponent *>(component.get())
172  ->setText("Score: " + std::to_string(score));
173  }
174  }
175  }
176  }
177  }
178 
179  if (p->code == NEW_COMPONENT) {
180  auto *newComponent = static_cast<NewComponent *>(p->data);
181  newComponent->type = static_cast<ComponentTypeSocket>(ComponentType::SPRITE);
182  char *attributechar = static_cast<char *>(malloc(16));
183  std::memset(attributechar, 0, 16);
184  std::memcpy(attributechar, &newComponent->attribute, 16);
185  // std::memcpy(attributechar + 8, &newComponent->attribute2, 8);
186  //std::cout << "attribute: " << reinterpret_cast<char *>(&newComponent->attribute) << std::endl;
187  //std::cout << "attribute2: " << reinterpret_cast<char *>(&newComponent->attribute2) << std::endl;
188  std::string attributeString(attributechar);
189  attributeString = attributeString.substr(0, attributeString.find('\001'));
190  //std::cout << "newComponent: " << attributeString << " " << newComponent->x << " " << newComponent->y
191  //<< " id: " << newComponent->id << std::endl;
192  for (auto &component : _components) {
193  if (component->getType() == ComponentType::SPRITE) {
194  if (component->getAttribute() == reinterpret_cast<char *>(&newComponent->attribute)) {
195  _components.erase(std::remove(_components.begin(), _components.end(), component),
196  _components.end());
197  break;
198  }
199  }
200  }
201 
202  if (newComponent->type == ComponentType::SPRITE) {
203  auto sprite = std::make_shared<SpriteComponent>(_clientCore, _socket);
204  sprite->setAttribute(attributeString);
205  //std::cout << "new component: " << newComponent->id << std::endl;
206  sprite->setTexture(getTextureByType((Type)newComponent->id));
207  sprite->setPosition({newComponent->x, newComponent->y});
208  sprite->setSize({newComponent->sizeHorizontal, newComponent->sizeVertical});
209  sprite->setRect(
210  {newComponent->rectLeft, newComponent->rectTop, newComponent->rectWidth, newComponent->rectHeight});
211  addComponent(sprite);
212  }
213  if (newComponent->type == ComponentType::TEXT) {
214  auto text = std::make_shared<TextComponent>(_clientCore, _socket);
215  addComponent(text);
216  }
217  if (newComponent->type == ComponentType::MUSIC) {
218  auto music = std::make_shared<MusicComponent>(_clientCore, _socket);
219  addComponent(music);
220  }
221  }
222  if (p->code == DELETE_COMPONENT) {
223  std::string attribute = static_cast<char *>(p->data);
224  for (auto &component : _components) {
225  if (component->getAttribute() == attribute) {
226  _components.erase(std::remove(_components.begin(), _components.end(), component),
227  _components.end());
228  break;
229  }
230  }
231  std::cout << "delete component: " << attribute << std::endl;
232  }
233 
234  if (p->code == MESSAGE) {
235  std::string message = static_cast<char *>(p->data);
236  std::cout << "Message: " << message << std::endl;
237  if (message.find("event: ") != std::string::npos) {
238  std::string event = message.substr(message.find("event: ") + 7);
239  for (auto &component : _components) {
240  if (component->getType() == ComponentType::TEXT) {
241  if (component->getAttribute() == "text event") {
242  dynamic_cast<TextComponent *>(component.get())->setText(event);
243  }
244  }
245  }
246  }
247  }
248 
249  if (p->code == EVENT) {
250  auto *data = static_cast<char *>(p->data);
251  std::string message(data);
252  if (message == "new player") {
253  for (auto &component : _components) {
254  if (component->getType() == ComponentType::SOUND) {
255  if (component->getAttribute() == "new player") {
256  dynamic_cast<SoundComponent *>(component.get())->action();
257  }
258  }
259  }
260  } else if (message == "player left") {
261  for (auto &component : _components) {
262  if (component->getType() == ComponentType::SOUND) {
263  if (component->getAttribute() == "player left") {
264  dynamic_cast<SoundComponent *>(component.get())->action();
265  }
266  }
267  }
268  }
269  }
270  free(p->data);
271  packet = _socket->receive();
272  p = std::move(std::get<0>(packet));
273  }
274 }
275 
276 /**
277  * @brief getTextureByType, get the texture by type
278  * @param type
279  * @return texture of the type
280  */
282 {
283  return _textures.at(type);
284 }
285 
286 /**
287  * @brief initTextures, init the textures
288  */
290 {
291  _textures[Type::MISSINGTXT] = sf::Texture();
292  _textures[Type::MISSINGTXT].loadFromFile("../src/client/assets/missing.png");
293  _textures[Type::PLAYER] = sf::Texture();
294  _textures[Type::PLAYER].loadFromFile("../sprites/r-typesheet1.gif");
295  _textures[Type::ENEMY] = sf::Texture();
296  _textures[Type::ENEMY].loadFromFile("../testsprites/r-typesheet5_invert.png");
297  _textures[Type::BULLET] = sf::Texture();
298  _textures[Type::BULLET].loadFromFile("../sprites/r-typesheet1.gif");
299  _textures[Type::BACKGROUND1] = sf::Texture();
300  _textures[Type::BACKGROUND1].loadFromFile("../testsprites/bg_800_600/background_1.png");
301  _textures[Type::BACKGROUND2] = sf::Texture();
302  _textures[Type::BACKGROUND2].loadFromFile("../testsprites/bg_800_600/background_2.png");
303  _textures[Type::BACKGROUND3] = sf::Texture();
304  _textures[Type::BACKGROUND3].loadFromFile("../testsprites/bg_800_600/background_3.png");
305  _textures[Type::BACKGROUND4] = sf::Texture();
306  _textures[Type::BACKGROUND4].loadFromFile("../testsprites/bg_800_600/background_4.png");
307  _textures[Type::FLOOR_BACKGROUND] = sf::Texture();
308  _textures[Type::FLOOR_BACKGROUND].loadFromFile("../testsprites/bg_800_600/ground_texture_bg.png");
309  _textures[Type::ROOF_BACKGROUND] = sf::Texture();
310  _textures[Type::ROOF_BACKGROUND].loadFromFile("../testsprites/bg_800_600/roof_texture_bg.png");
311  _textures[Type::BOSS] = sf::Texture();
312  _textures[Type::BOSS].loadFromFile("../testsprites/r-typesheet30-alone.png");
313  _textures[Type::BOSS_BULLET] = sf::Texture();
314  _textures[Type::BOSS_BULLET].loadFromFile("../testsprites/boss-bullets.png");
315 }
316 
317 /**
318  * @brief handleEvent, handle the event
319  * @param event
320  * @param window
321  */
322 void GameScene::handleEvent(const sf::Event &event, sf::RenderWindow &window)
323 {
324  while (window.pollEvent(const_cast<sf::Event &>(event))) {
325  if (event.type == sf::Event::Closed) {
326  window.close();
327  Packet packet{};
328  packet.code = MESSAGE;
329  packet.data_size = 9;
330  packet.data = malloc(packet.data_size);
331  memcpy(packet.data, "exit game", packet.data_size);
332  _socket->send(&packet, _socket->serv_addr);
333  return;
334  }
335  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Escape)) {
337  for (auto &component : _clientCore->getCurrentScene()->getComponents()) {
338  if (component->getType() == ComponentType::MUSIC) {
339  dynamic_cast<MusicComponent *>(component.get())->action();
340  }
341  }
342  Packet packet{};
343  packet.code = MESSAGE;
344  packet.data_size = 9;
345  packet.data = malloc(packet.data_size);
346  memcpy(packet.data, "exit game", packet.data_size);
347  _socket->send(&packet, _socket->serv_addr);
348  return;
349  }
350  }
351 
352  if (!window.hasFocus())
353  return;
354 
355  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Space)) {
356  Packet packet{};
357  Event event1{};
358  packet.code = CODE::EVENT;
359  packet.data_size = sizeof(Event);
360  packet.data = malloc(packet.data_size);
361  event1.key = static_cast<int>(sf::Keyboard::Space);
362  event1.eventType = static_cast<int>(sf::Event::KeyPressed);
363  memcpy(packet.data, &event1, packet.data_size);
364  _socket->send(&packet, _socket->serv_addr);
365  free(packet.data);
366  }
367 
368  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Up)) {
369  Packet packet{};
370  Event event1{};
371  packet.code = CODE::EVENT;
372  packet.data_size = sizeof(Event);
373  packet.data = malloc(packet.data_size);
374  event1.key = static_cast<int>(sf::Keyboard::Up);
375  event1.eventType = static_cast<int>(sf::Event::KeyPressed);
376  memcpy(packet.data, &event1, packet.data_size);
377  _socket->send(&packet, _socket->serv_addr);
378  free(packet.data);
379  }
380 
381  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Down)) {
382  Packet packet{};
383  Event event1{};
384  packet.code = CODE::EVENT;
385  packet.data_size = sizeof(Event);
386  packet.data = malloc(packet.data_size);
387  event1.key = static_cast<int>(sf::Keyboard::Down);
388  event1.eventType = static_cast<int>(sf::Event::KeyReleased);
389  memcpy(packet.data, &event1, packet.data_size);
390  _socket->send(&packet, _socket->serv_addr);
391  free(packet.data);
392  }
393 
394  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Left)) {
395  Packet packet{};
396  Event event1{};
397  packet.code = CODE::EVENT;
398  packet.data_size = sizeof(Event);
399  packet.data = malloc(packet.data_size);
400  event1.key = static_cast<int>(sf::Keyboard::Left);
401  event1.eventType = static_cast<int>(sf::Event::KeyPressed);
402  memcpy(packet.data, &event1, packet.data_size);
403  _socket->send(&packet, _socket->serv_addr);
404  free(packet.data);
405  }
406 
407  if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scancode::Right)) {
408  Packet packet{};
409  Event event1{};
410  packet.code = CODE::EVENT;
411  packet.data_size = sizeof(Event);
412  packet.data = malloc(packet.data_size);
413  event1.key = static_cast<int>(sf::Keyboard::Right);
414  event1.eventType = static_cast<int>(sf::Event::KeyPressed);
415  memcpy(packet.data, &event1, packet.data_size);
416  _socket->send(&packet, _socket->serv_addr);
417  free(packet.data);
418  }
419 
420  for (auto &component : _components) {
421  component->handleEvent(event, window);
422  }
423 }