The Table Engine
scenemanager.cpp
Go to the documentation of this file.
1 #include <iostream>
2 
3 #include "gameobject.h"
4 #include "transform.h"
5 #include "resourcemanager.h"
6 #include "texture.h"
7 #include "scenemanager.h"
8 #include "gameobjectfactory.h"
9 #include <fstream>
10 #include <iostream>
11 
12 std::atomic<uint64_t> SceneManager::m_totalObjects = 0;
13 std::atomic<uint64_t> SceneManager::m_aliveObjects = 0;
14 
16  static SceneManager instance;
17  return instance;
18 }
19 
21  m_camera = new Camera();
22 }
23 
24 void SceneManager::setRenderer(SDL_Renderer* renderer) {
25  m_renderer = renderer;
26 }
27 
30 }
31 
33  isDemo = true;
34  m_sceneTrees.push_back(createSceneTest1());
35  m_sceneTrees.push_back(createSceneTest2());
36  m_sceneTrees.push_back(createSceneTest3());
37 }
38 
39 void SceneManager::loadScenesFromJSON(const std::string& filePath) {
40  std::ifstream file(filePath);
41  if (!file) {
42  throw std::runtime_error("Could not open JSON file: " + filePath);
43  }
44 
45  nlohmann::json gameData;
46  file >> gameData;
47 
48  // Parse object definitions
49  std::unordered_map<std::string, nlohmann::json> objectDefinitions;
50  if (gameData.contains("object_definitions")) {
51  for (const auto& [type, objects] : gameData["object_definitions"].items()) {
52  for (const auto& [name, definition] : objects.items()) {
53  objectDefinitions[name] = definition;
54  }
55  }
56  } else {
57  std::cerr << "No object definitions found in JSON file.\n";
58  }
59 
60  // Parse levels and create scenes
61  if (gameData.contains("levels")) {
62  for (const auto& level : gameData["levels"]) {
63  SceneTree* sceneTree = new SceneTree();
64 
65  for (const auto& object : level["objects"]) {
66  std::string name = object["name"];
67  if (objectDefinitions.find(name) != objectDefinitions.end()) {
68  const auto& definition = objectDefinitions[name];
69  int x = object["x"];
70  int y = object["y"];
71 
72  // Create a tile or other object based on its definition
73  if (definition["properties"].contains("type") && definition["properties"]["type"] == "Tile") {
74  std::cout << "Creating tile\n";
76  definition["file"],
77  Vec2(x, y),
78  Vec2(definition["length"], definition["width"]),
79  Vec2(definition["size_width"], definition["size_height"]),
80  Vec2(definition["top_left_x"], definition["top_left_y"]),
81  Vec2(definition["rows"], definition["columns"])
82  );
83  std::cout << "Added tile: " << name << '\n' << " at (" << x << ", " << y << ")\n";
84  sceneTree->addChild(tile, true);
85  }
86 
87  else if (definition["properties"].contains("type") && definition["properties"]["type"] == "Wall") {
88  std::cout << "Creating wall\n";
90  definition["file"],
91  Vec2(x, y),
92  Vec2(definition["length"], definition["width"]),
93  Vec2(definition["size_width"], definition["size_height"]),
94  Vec2(definition["top_left_x"], definition["top_left_y"])
95  );
96  std::cout << "Added wall: " << name << " at (" << x << ", " << y << ")\n";
97  sceneTree->addChild(wall, true);
98  }
99  else if (definition["properties"].contains("type") && definition["properties"]["type"] == "Table") {
100  std::cout << "Creating table\n";
102  definition["file"],
103  Vec2(x, y),
104  Vec2(definition["length"], definition["width"]),
105  Vec2(definition["size_width"], definition["size_height"]),
106  Vec2(definition["top_left_x"], definition["top_left_y"])
107  );
108  std::cout << "Added table: " << name << " at (" << x << ", " << y << ")\n";
109  sceneTree->addChild(table, true);
110  }
111  // Add additional logic for other object types later...
112 
113  else if (definition["properties"].contains("type") && definition["properties"]["type"] == "Enemy") {
114  std::cout << "Creating enemy\n";
116  definition["file"],
117  definition["rows"],
118  definition["columns"],
119  definition["animation_time"],
120  x,
121  y,
122  definition["width"],
123  definition["length"]
124  );
125  std::cout << "Created enemy\n";
126  sceneTree->addChild(enemy, true);
127 
128  std::cout << "Added enemy: " << name << " at (" << x << ", " << y << ")\n";
129  }
130  } else {
131  std::cerr << "Object definition not found for: " << name << "\n";
132  }
133  }
134 
136  sceneTree->addChild(player);
137 
139  player->getSceneNode()->addChild(bow);
140 
141  m_sceneTrees.push_back(sceneTree);
142  std::cout<< "Loaded scene\n";
143 
144  GameObject* crosshair = GameObjectFactory::createCrosshair(); // Assuming this method exists in GameObjectFactory
145  sceneTree->addChild(crosshair);
146  }
147  } else {
148  std::cerr << "No levels found in JSON file.\n";
149  }
150 }
151 
152 SDL_Renderer* SceneManager::getRenderer() {
153  return m_renderer;
154 }
155 
157  return m_camera->getWorldPosition();
158 }
159 
161  // int numScenes = static_cast<int>(m_sceneTrees.size());
162  if (m_currentSceneIndex < static_cast<int>(m_sceneTrees.size()) - 1) {
164  } else {
165  std::cout << "Finished all scenes.\n";
166  exit(0);
167  // std::cerr << "No more scenes to transition to.\n";
168  }
169 }
170 
172  return m_currentSceneIndex;
173 }
174 
176  SceneTree* sceneTree = new SceneTree();
177 
178  int lenTiles = 20;
179  for (int i = -lenTiles; i < lenTiles; i++) {
180  for (int j = -lenTiles; j < lenTiles; j++) {
182  tile->getComponent<Transform>()->setWorldPosition(i * 32, j * 32);
183  sceneTree->addChild(tile, true);
184  }
185  }
186 
187  for (int i = 0; i < 10; i++)
188  {
189  int x = rand() % 1200 - 600;
190  int y = rand() % 1200 - 600;
192  key->getComponent<Transform>()->setWorldPosition(x, y);
193  sceneTree->addChild(key);
194  }
195 
197  sceneTree->addChild(player);
199  player->getSceneNode()->addChild(bow);
200 
201  for (int i = 0; i < 10; i++) {
203  enemy->getComponent<Transform>()->setWorldPosition(100 + i * 50, 100);
204  sceneTree->addChild(enemy);
205  }
206 
207  GameObject* crosshair = GameObjectFactory::createCrosshair(); // Assuming this method exists in GameObjectFactory
208  sceneTree->addChild(crosshair);
209 
210  return sceneTree;
211 }
212 
214  SceneTree* sceneTree = new SceneTree();
215 
216  int lenTiles = 20;
217  for (int i = -lenTiles; i < lenTiles; i++) {
218  for (int j = -lenTiles; j < lenTiles; j++) {
220  tile->getComponent<Transform>()->setWorldPosition(i * 32, j * 32);
221  sceneTree->addChild(tile, true);
222  }
223  }
224 
225  for (int i = 0; i < 20; i++)
226  {
227  int x = rand() % 1200 - 600;
228  int y = rand() % 1200 - 600;
230  key->getComponent<Transform>()->setWorldPosition(x, y);
231  sceneTree->addChild(key);
232  }
233 
235  sceneTree->addChild(player);
237  player->getSceneNode()->addChild(bow);
238 
239  for (int i = 0; i < 20; i++) {
241  enemy->getComponent<Transform>()->setWorldPosition(100 + i * 50, 100);
242  sceneTree->addChild(enemy);
243  }
244 
245  GameObject* crosshair = GameObjectFactory::createCrosshair(); // Assuming this method exists in GameObjectFactory
246  sceneTree->addChild(crosshair);
247 
248  return sceneTree;
249 }
250 
252  SceneTree* sceneTree = new SceneTree();
253 
254  int lenTiles = 20;
255  for (int i = -lenTiles; i < lenTiles; i++) {
256  for (int j = -lenTiles; j < lenTiles; j++) {
258  tile->getComponent<Transform>()->setWorldPosition(i * 32, j * 32);
259  sceneTree->addChild(tile, true);
260  }
261  }
262 
263  for (int i = 0; i < 30; i++)
264  {
265  int x = rand() % 1200 - 600;
266  int y = rand() % 1200 - 600;
268  key->getComponent<Transform>()->setWorldPosition(x, y);
269  sceneTree->addChild(key);
270  }
271 
273  sceneTree->addChild(player);
275  player->getSceneNode()->addChild(bow);
276 
277  for (int i = 0; i < 30; i++) {
279  enemy->getComponent<Transform>()->setWorldPosition(100 + i * 50, 100);
280  sceneTree->addChild(enemy);
281  }
282 
283  GameObject* crosshair = GameObjectFactory::createCrosshair(); // Assuming this method exists in GameObjectFactory
284  sceneTree->addChild(crosshair);
285 
286  return sceneTree;
287 }
288 
290 {
291  auto sceneTree = SceneManager::getInstance().getSceneTree();
292  if (sceneTree == nullptr) return;
293 
294  sceneTree->traverseTree([](SceneNode* node) {
295  if (node->getGameObject() != nullptr) {
296  }
297  if (node->readyToDestroy()) {
298  delete node;
299  }
300  });
301 }
302 
304 {
305  auto sceneTree = SceneManager::getInstance().getSceneTree();
306  if (sceneTree == nullptr) return;
307 
308  sceneTree->traverseTree([](SceneNode* node) {
309  if (!node->isBackground() && node->getGameObject())
310  node->getGameObject()->input();
311  });
312 }
313 
315 {
316  m_camera->update();
317  auto sceneTree = SceneManager::getInstance().getSceneTree();
318  if (sceneTree == nullptr) return;
319 
320  sceneTree->traverseTree([](SceneNode* node) {
321  if (node->getGameObject())
322  node->getGameObject()->update();
323  });
324 
325  cleanTree();
326 
327  if (sceneTree->gameStatus() == -1)
328  {
329  // render a white screen for 1s
330  SDL_SetRenderDrawColor(m_renderer, 255, 0, 0, 0);
331  SDL_RenderClear(m_renderer);
332  SDL_RenderPresent(m_renderer);
333 
334  // std::string font = "../Assets/Fonts/BruceForever.ttf";
335 
336  // SDL_Color color = {255, 0, 0, 255};
337  // std::string victory = "You failed at level " + std::to_string(SceneManager::getInstance().getSceneIndex() + 1) + "!";
338  // SDL_Texture* text = ResourceManager::getInstance().loadText(font, victory, color, 40);
339  // SDL_Rect rect = {50, 200, 540, 100};
340  // SDL_RenderCopy(m_renderer, text, NULL, &rect);
341  // SDL_SetRenderDrawColor(m_renderer, 0, 255, 0, 255);
342  // SDL_RenderPresent(m_renderer);
343 
344  SDL_Delay(1000);
345  exit(0);
346  }
347  else if (sceneTree->gameStatus() == 1)
348  {
349  // render a white screen for 1s
350  SDL_SetRenderDrawColor(m_renderer, 0, 255, 0, 255);
351  SDL_RenderClear(m_renderer);
352  SDL_RenderPresent(m_renderer);
353 
354  // std::string font = "../Assets/Fonts/BruceForever.ttf";
355 
356  // SDL_Color color = {0, 255, 0, 255};
357  // std::string victory = "Level " + std::to_string(SceneManager::getInstance().getSceneIndex() + 1) + " cleared!";
358  // SDL_Texture* text = ResourceManager::getInstance().loadText(font, victory, color, 40);
359  // SDL_Rect rect = {50, 200, 540, 100};
360  // SDL_RenderCopy(m_renderer, text, NULL, &rect);
361  // SDL_SetRenderDrawColor(m_renderer, 0, 255, 0, 255);
362  // SDL_RenderPresent(m_renderer);
363 
364  SDL_Delay(1000);
365  getNextScene();
366  }
367 }
368 
370 {
371  auto sceneTree = SceneManager::getInstance().getSceneTree();
372  if (sceneTree == nullptr) return;
373 
374  sceneTree->traverseTree([](SceneNode* node) {
375  if (node->getGameObject())
376  node->getGameObject()->render();
377  });
378 
379  sceneTree->resetCachedGameObjectsInFrame();
380 }
Manages the camera's view in a game, handling its position in the world space.
Definition: camera.h:14
void update()
Definition: camera.cpp:17
Vec2 getWorldPosition()
Definition: camera.cpp:62
static GameObject * createEnemyWarriorCustom(std::string path, int row, int col, float animationTime, int pos_x, int pos_y, int size_x, int size_y)
Creates a customized enemy warrior object with specific texture and animations.
static GameObject * createTableCustom(std::string path, Vec2 pos, Vec2 size, Vec2 sprite_size, Vec2 sprite_pos)
Creates a customized table object with specific texture.
static GameObject * createKey()
Creates a key object.
static GameObject * createEnemyWarrior()
Creates an enemy warrior object.
static GameObject * createTileCustom(std::string path, Vec2 pos, Vec2 size, Vec2 sprite_size, Vec2 sprite_pos, Vec2 rc)
Creates a customized tile object with specific texture.
static GameObject * createTile1()
Creates a basic tile object.
static GameObject * createCrosshair()
Creates a crosshair object.
static GameObject * createWallCustom(std::string path, Vec2 pos, Vec2 size, Vec2 sprite_size, Vec2 sprite_pos)
Creates a customized wall object with specific texture.
static GameObject * createPlayerTest()
Creates a test player object.
static GameObject * createBow()
Creates a bow object.
Core class representing an entity in the game world.
Definition: gameobject.h:20
void render()
Renders this GameObject and its components.
Definition: gameobject.cpp:75
SceneNode * getSceneNode()
Gets the SceneNode associated with this GameObject.
Definition: gameobject.cpp:36
T * getComponent()
Gets a component of the specified type.
Definition: gameobject.h:123
void input()
Processes input for this GameObject and its components.
Definition: gameobject.cpp:57
void update()
Updates this GameObject and its components.
Definition: gameobject.cpp:66
Singleton class that manages scenes and their transitions.
Definition: scenemanager.h:27
static SceneManager & getInstance()
Retrieves the singleton instance of SceneManager.
SceneTree * createSceneTest2()
std::vector< SceneTree * > m_sceneTrees
Array of scene trees.
Definition: scenemanager.h:30
SceneTree * createSceneTest1()
Creates a test scene. This method is an example of how to define specific scenes.
SceneTree * getSceneTree()
Retrieves the current scene tree managing the game objects.
void getNextScene()
Advances to the next scene based on the current scene index.
void render()
Renders the current scene.
void cleanTree()
Cleans up the scene tree, removing all inactive game objects.
void input()
Processes input for the current scene.
SceneManager()
Private constructor for singleton pattern.
SDL_Renderer * m_renderer
Renderer used to render the game objects.
Definition: scenemanager.h:29
int m_currentSceneIndex
Index of the current scene in the game.
Definition: scenemanager.h:32
void loadScenesFromJSON(const std::string &filePath)
void update()
Updates the state of the current scene.
SceneTree * createSceneTest3()
SDL_Renderer * getRenderer()
Retrieves the current SDL_Renderer used by the SceneManager.
int getSceneIndex()
Retrieves the index of the current scene.
Camera * m_camera
Definition: scenemanager.h:33
static std::atomic< uint64_t > m_totalObjects
Total number of game objects created.
Definition: scenemanager.h:57
static std::atomic< uint64_t > m_aliveObjects
Current number of active game objects.
Definition: scenemanager.h:58
Vec2 getCameraWorldPosition()
Retrieves the world position of the camera.
void setRenderer(SDL_Renderer *renderer)
Sets the renderer used for drawing game objects.
Represents a node in the scene graph, encapsulating a game object and its hierarchy.
Definition: scene.h:25
void addChild(GameObject *child, bool isBackground=false)
Adds a child game object to this node.
Definition: scene.cpp:40
bool isBackground()
Checks if this node is part of the background.
Definition: scene.cpp:69
bool readyToDestroy()
Checks if this node is marked for destruction.
Definition: scene.cpp:61
GameObject * getGameObject()
Gets the GameObject associated with this node.
Definition: scene.cpp:57
Manages a tree structure of SceneNodes, facilitating scene graph operations.
Definition: scene.h:109
void addChild(GameObject *child, bool isBackground=false)
Adds a child GameObject to the scene tree.
Definition: scene.cpp:87
void traverseTree(std::function< void(SceneNode *)> callback)
Traverses the entire tree, executing a callback on each node.
Definition: scene.cpp:91
Component for handling the transformation of game objects.
Definition: transform.h:23
Manages resources such as textures, fonts, and potentially sounds for a game engine.
Defines the SceneManager class for managing scenes in the game.
A structure to represent 2D vectors.
Definition: vec2.h:16
Defines the Texture component for managing textures within the Game Engine, encapsulating SDL texture...
Provides the Transform component for positioning and sizing game objects.