diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | cmake/FindMxml.cmake | 31 | ||||
-rw-r--r-- | entities/checkpoint.xml | 5 | ||||
-rw-r--r-- | maps/embarass.xml (renamed from maps/embarass.txt) | 9 | ||||
-rw-r--r-- | maps/second.xml (renamed from maps/second.txt) | 15 | ||||
-rw-r--r-- | src/components.cpp | 12 | ||||
-rw-r--r-- | src/components.h | 4 | ||||
-rw-r--r-- | src/entity.cpp | 3 | ||||
-rw-r--r-- | src/entity.h | 1 | ||||
-rw-r--r-- | src/entityfactory.cpp | 101 | ||||
-rw-r--r-- | src/entityfactory.h | 15 | ||||
-rw-r--r-- | src/game.cpp | 34 | ||||
-rw-r--r-- | src/game.h | 6 | ||||
-rw-r--r-- | src/map.cpp | 158 | ||||
-rw-r--r-- | src/map.h | 31 | ||||
-rw-r--r-- | src/renderer.cpp | 2 | ||||
-rw-r--r-- | src/renderer.h | 2 |
17 files changed, 345 insertions, 92 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b28397..e86cd95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -27,6 +27,7 @@ find_package(GLEW REQUIRED) | |||
27 | find_package(GLFW REQUIRED) | 27 | find_package(GLFW REQUIRED) |
28 | find_package(portaudio REQUIRED) | 28 | find_package(portaudio REQUIRED) |
29 | find_package(libsndfile REQUIRED) | 29 | find_package(libsndfile REQUIRED) |
30 | find_package(libxml2 REQUIRED) | ||
30 | 31 | ||
31 | set(ALL_LIBS | 32 | set(ALL_LIBS |
32 | ${OPENGL_LIBRARY} | 33 | ${OPENGL_LIBRARY} |
@@ -34,10 +35,15 @@ set(ALL_LIBS | |||
34 | ${GLFW_LIBRARY} | 35 | ${GLFW_LIBRARY} |
35 | ${PORTAUDIO_LIBRARIES} | 36 | ${PORTAUDIO_LIBRARIES} |
36 | ${LIBSNDFILE_LIBRARY} | 37 | ${LIBSNDFILE_LIBRARY} |
38 | ${LIBXML2_LIBRARIES} | ||
39 | ) | ||
40 | |||
41 | include_directories( | ||
42 | ${LIBXML2_INCLUDE_DIR} | ||
37 | ) | 43 | ) |
38 | 44 | ||
39 | # include_directories(${SDL2_INCLUDE_DIR}) | 45 | # include_directories(${SDL2_INCLUDE_DIR}) |
40 | set(CMAKE_BUILD_TYPE Debug) | 46 | set(CMAKE_BUILD_TYPE Debug) |
41 | add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp src/muxer.cpp) | 47 | add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp src/muxer.cpp src/entityfactory.cpp) |
42 | target_link_libraries(Aromatherapy ${ALL_LIBS}) | 48 | target_link_libraries(Aromatherapy ${ALL_LIBS}) |
43 | install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) | 49 | install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) |
diff --git a/cmake/FindMxml.cmake b/cmake/FindMxml.cmake new file mode 100644 index 0000000..49daa4f --- /dev/null +++ b/cmake/FindMxml.cmake | |||
@@ -0,0 +1,31 @@ | |||
1 | # - Try to find Motif (or lesstif) | ||
2 | # Once done this will define: | ||
3 | # MXML_FOUND - system has MXML | ||
4 | # MXML_INCLUDE_DIR - incude paths to use Motif | ||
5 | # MXML_LIBRARIES - Link these to use Motif | ||
6 | |||
7 | SET(MXML_FOUND 0) | ||
8 | |||
9 | IF(UNIX) | ||
10 | FIND_PATH(MXML_INCLUDE_DIR | ||
11 | mxml.h | ||
12 | /usr/include | ||
13 | ) | ||
14 | |||
15 | FIND_LIBRARY(MXML_LIBRARIES | ||
16 | mxml | ||
17 | /usr/lib | ||
18 | ) | ||
19 | |||
20 | ENDIF(UNIX) | ||
21 | |||
22 | # handle the QUIETLY and REQUIRED arguments and set MXML_FOUND to TRUE if | ||
23 | # all listed variables are TRUE | ||
24 | INCLUDE(FindPackageHandleStandardArgs) | ||
25 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(MXML DEFAULT_MSG MXML_LIBRARIES MXML_INCLUDE_DIR) | ||
26 | |||
27 | |||
28 | MARK_AS_ADVANCED( | ||
29 | MXML_INCLUDE_DIR | ||
30 | MXML_LIBRARIES | ||
31 | ) \ No newline at end of file | ||
diff --git a/entities/checkpoint.xml b/entities/checkpoint.xml new file mode 100644 index 0000000..5b081ed --- /dev/null +++ b/entities/checkpoint.xml | |||
@@ -0,0 +1,5 @@ | |||
1 | <entity-def> | ||
2 | <sprite>../res/keyring.png</sprite> | ||
3 | <action>save</action> | ||
4 | <size>8,11</size> | ||
5 | </entity-def> \ No newline at end of file | ||
diff --git a/maps/embarass.txt b/maps/embarass.xml index 0407733..950854c 100644 --- a/maps/embarass.txt +++ b/maps/embarass.xml | |||
@@ -1,4 +1,6 @@ | |||
1 | 0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,18,9,8,10,8,11,8,10,10,8,11,8,9,10,21,0, | 1 | <map-def> |
2 | <name>Everything Is Embarrassing</name> | ||
3 | <environment>0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,18,9,8,10,8,11,8,10,10,8,11,8,9,10,21,0, | ||
2 | 0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,22,21, | 4 | 0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,22,21, |
3 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, | 5 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,8,8,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, |
4 | 0,19,-1,-1,-1,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, | 6 | 0,19,-1,-1,-1,0,0,0,0,0,0,0,0,18,8,8,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12, |
@@ -21,5 +23,6 @@ | |||
21 | 0,0,0,0,0,0,0,0,0,0,24,4,2,1,3,3,1,4,2,2,1,1,1,3,1,2,4,1,3,26,0,0,0,0,0,0,0,0,0,0, | 23 | 0,0,0,0,0,0,0,0,0,0,24,4,2,1,3,3,1,4,2,2,1,1,1,3,1,2,4,1,3,26,0,0,0,0,0,0,0,0,0,0, |
22 | 0,0,0,0,24,3,1,2,1,1,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,27,1,3,2,26,0,0,0,0,0,0, | 24 | 0,0,0,0,24,3,1,2,1,1,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,27,1,3,2,26,0,0,0,0,0,0, |
23 | 1,2,3,1,25,0,0,0,0,0,20,0,0,0,0,0,0,19,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,27,1,2,2,4,3,1, | 25 | 1,2,3,1,25,0,0,0,0,0,20,0,0,0,0,0,0,19,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,27,1,2,2,4,3,1, |
24 | 0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0, | 26 | 0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,</environment> |
25 | Everything Is Embarrassing \ No newline at end of file | 27 | <leftmap>second</leftmap> |
28 | </map-def> | ||
diff --git a/maps/second.txt b/maps/second.xml index de5ec83..b6c2419 100644 --- a/maps/second.txt +++ b/maps/second.xml | |||
@@ -1,4 +1,6 @@ | |||
1 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 1 | <map-def> |
2 | <name>It's A Trap!</name> | ||
3 | <environment>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
2 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0, | 4 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0, |
3 | 0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0, | 5 | 0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0, |
4 | 0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 6 | 0,0,0,0,0,0,0,19,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
@@ -21,5 +23,12 @@ | |||
21 | 0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 23 | 0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
22 | 0,0,0,27,2,2,3,3,3,4,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 24 | 0,0,0,27,2,2,3,3,3,4,26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
23 | 0,20,0,0,0,0,0,19,0,0,27,1,1,1,2,2,2,26,0,0,0,0,0,0,0,0,0,0,24,4,2,2,1,3,2,2,1,2,2,3, | 25 | 0,20,0,0,0,0,0,19,0,0,27,1,1,1,2,2,2,26,0,0,0,0,0,0,0,0,0,0,24,4,2,2,1,3,2,2,1,2,2,3, |
24 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,42,42,42,42,42,42,42,42,42,42,12,0,0,0,0,0,19,0,0,0,0,0, | 26 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,42,42,42,42,42,42,42,42,42,42,12,0,0,0,0,0,19,0,0,0,0,0,</environment> |
25 | It's A Trap! \ No newline at end of file | 27 | <entities> |
28 | <entity> | ||
29 | <entity-type>checkpoint</entity-type> | ||
30 | <entity-position>257,160</entity-position> | ||
31 | </entity> | ||
32 | </entities> | ||
33 | <rightmap>embarass</rightmap> | ||
34 | </map-def> | ||
diff --git a/src/components.cpp b/src/components.cpp index 26aa5d2..ba4fe72 100644 --- a/src/components.cpp +++ b/src/components.cpp | |||
@@ -309,7 +309,7 @@ MapRenderComponent::MapRenderComponent(const Map& map) | |||
309 | 309 | ||
310 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) | 310 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) |
311 | { | 311 | { |
312 | int tile = map.mapdata()[i]; | 312 | int tile = map.getMapdata()[i]; |
313 | int x = i % MAP_WIDTH; | 313 | int x = i % MAP_WIDTH; |
314 | int y = i / MAP_WIDTH; | 314 | int y = i / MAP_WIDTH; |
315 | Rectangle dst {x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; | 315 | Rectangle dst {x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; |
@@ -322,7 +322,7 @@ MapRenderComponent::MapRenderComponent(const Map& map) | |||
322 | } | 322 | } |
323 | 323 | ||
324 | Texture font("../res/font.bmp"); | 324 | Texture font("../res/font.bmp"); |
325 | const char* map_name = map.title(); | 325 | const char* map_name = map.getTitle(); |
326 | int start_x = (40/2) - (strlen(map_name)/2); | 326 | int start_x = (40/2) - (strlen(map_name)/2); |
327 | for (size_t i=0; i<strlen(map_name); i++) | 327 | for (size_t i=0; i<strlen(map_name); i++) |
328 | { | 328 | { |
@@ -348,7 +348,7 @@ MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map) | |||
348 | { | 348 | { |
349 | int x = i % MAP_WIDTH; | 349 | int x = i % MAP_WIDTH; |
350 | int y = i / MAP_WIDTH; | 350 | int y = i / MAP_WIDTH; |
351 | int tile = map.mapdata()[i]; | 351 | int tile = map.getMapdata()[i]; |
352 | 352 | ||
353 | if ((tile > 0) && (tile < 28) && (!((tile >= 5) && (tile <= 7)))) | 353 | if ((tile > 0) && (tile < 28) && (!((tile >= 5) && (tile <= 7)))) |
354 | { | 354 | { |
@@ -600,15 +600,15 @@ void StaticImageComponent::render(Game&, Entity& entity, Texture& buffer) | |||
600 | 600 | ||
601 | // Simple collision | 601 | // Simple collision |
602 | 602 | ||
603 | SimpleColliderComponent::SimpleColliderComponent(std::function<void (Entity& collider)> callback) : callback(callback) | 603 | SimpleColliderComponent::SimpleColliderComponent(std::function<void (Game& game, Entity& collider)> callback) : callback(callback) |
604 | { | 604 | { |
605 | 605 | ||
606 | } | 606 | } |
607 | 607 | ||
608 | void SimpleColliderComponent::receive(Game&, Entity&, const Message& msg) | 608 | void SimpleColliderComponent::receive(Game& game, Entity&, const Message& msg) |
609 | { | 609 | { |
610 | if (msg.type == Message::Type::collision) | 610 | if (msg.type == Message::Type::collision) |
611 | { | 611 | { |
612 | callback(*(msg.collisionEntity)); | 612 | callback(game, *(msg.collisionEntity)); |
613 | } | 613 | } |
614 | } | 614 | } |
diff --git a/src/components.h b/src/components.h index f5c66d4..3d80d1a 100644 --- a/src/components.h +++ b/src/components.h | |||
@@ -111,11 +111,11 @@ class StaticImageComponent : public Component { | |||
111 | 111 | ||
112 | class SimpleColliderComponent : public Component { | 112 | class SimpleColliderComponent : public Component { |
113 | public: | 113 | public: |
114 | SimpleColliderComponent(std::function<void (Entity& collider)> callback); | 114 | SimpleColliderComponent(std::function<void (Game& game, Entity& collider)> callback); |
115 | void receive(Game& game, Entity& entity, const Message& msg); | 115 | void receive(Game& game, Entity& entity, const Message& msg); |
116 | 116 | ||
117 | private: | 117 | private: |
118 | std::function<void (Entity& collider)> callback; | 118 | std::function<void (Game& game, Entity& collider)> callback; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | #endif | 121 | #endif |
diff --git a/src/entity.cpp b/src/entity.cpp index 2b6cd7f..0ede567 100644 --- a/src/entity.cpp +++ b/src/entity.cpp | |||
@@ -1,4 +1,7 @@ | |||
1 | #include "entity.h" | 1 | #include "entity.h" |
2 | #include <libxml/parser.h> | ||
3 | #include "components.h" | ||
4 | #include "muxer.h" | ||
2 | 5 | ||
3 | void Entity::addComponent(std::shared_ptr<Component> c) | 6 | void Entity::addComponent(std::shared_ptr<Component> c) |
4 | { | 7 | { |
diff --git a/src/entity.h b/src/entity.h index e22fd10..44ce973 100644 --- a/src/entity.h +++ b/src/entity.h | |||
@@ -7,6 +7,7 @@ class Component; | |||
7 | #include <list> | 7 | #include <list> |
8 | #include "renderer.h" | 8 | #include "renderer.h" |
9 | #include "game.h" | 9 | #include "game.h" |
10 | #include "map.h" | ||
10 | 11 | ||
11 | class Message { | 12 | class Message { |
12 | public: | 13 | public: |
diff --git a/src/entityfactory.cpp b/src/entityfactory.cpp new file mode 100644 index 0000000..acf9b8e --- /dev/null +++ b/src/entityfactory.cpp | |||
@@ -0,0 +1,101 @@ | |||
1 | #include "entityfactory.h" | ||
2 | #include <libxml/parser.h> | ||
3 | #include "components.h" | ||
4 | #include "muxer.h" | ||
5 | #include <cstdio> | ||
6 | |||
7 | struct EntityData { | ||
8 | char* sprite; | ||
9 | char* action; | ||
10 | bool hasPhysics; | ||
11 | int width; | ||
12 | int height; | ||
13 | }; | ||
14 | |||
15 | static std::map<std::string, EntityData> factories; | ||
16 | |||
17 | std::shared_ptr<Entity> EntityFactory::createNamedEntity(const std::string name, const Map& map) | ||
18 | { | ||
19 | auto it = factories.find(name); | ||
20 | EntityData data = factories[name]; | ||
21 | if (it == factories.end()) | ||
22 | { | ||
23 | xmlDocPtr doc = xmlParseFile(("../entities/" + name + ".xml").c_str()); | ||
24 | if (doc == nullptr) | ||
25 | { | ||
26 | fprintf(stderr, "Error reading entity %s\n", name.c_str()); | ||
27 | exit(-1); | ||
28 | } | ||
29 | |||
30 | xmlNodePtr top = xmlDocGetRootElement(doc); | ||
31 | if (top == nullptr) | ||
32 | { | ||
33 | fprintf(stderr, "Empty entity %s\n", name.c_str()); | ||
34 | exit(-1); | ||
35 | } | ||
36 | |||
37 | if (xmlStrcmp(top->name, (const xmlChar*) "entity-def")) | ||
38 | { | ||
39 | fprintf(stderr, "Invalid entity definition %s\n", name.c_str()); | ||
40 | exit(-1); | ||
41 | } | ||
42 | |||
43 | for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) | ||
44 | { | ||
45 | if (!xmlStrcmp(node->name, (const xmlChar*) "sprite")) | ||
46 | { | ||
47 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
48 | data.sprite = (char*) calloc(xmlStrlen(key)+1, sizeof(char)); | ||
49 | strcpy(data.sprite, (char*) key); | ||
50 | xmlFree(key); | ||
51 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "action")) | ||
52 | { | ||
53 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
54 | data.action = (char*) calloc(xmlStrlen(key)+1, sizeof(char)); | ||
55 | strcpy(data.action, (char*) key); | ||
56 | xmlFree(key); | ||
57 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "size")) | ||
58 | { | ||
59 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
60 | data.hasPhysics = true; | ||
61 | sscanf((char*) key, "%d,%d", &(data.width), &(data.height)); | ||
62 | xmlFree(key); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | xmlFreeDoc(doc); | ||
67 | |||
68 | factories[name] = data; | ||
69 | } | ||
70 | |||
71 | auto entity = std::make_shared<Entity>(); | ||
72 | |||
73 | if (data.sprite) | ||
74 | { | ||
75 | auto component = std::make_shared<StaticImageComponent>(data.sprite); | ||
76 | entity->addComponent(component); | ||
77 | } | ||
78 | |||
79 | if (data.action) | ||
80 | { | ||
81 | if (!strcmp(data.action, "save")) | ||
82 | { | ||
83 | auto component = std::make_shared<SimpleColliderComponent>([&] (Game& game, Entity& collider) { | ||
84 | playSound("../res/Pickup_Coin23.wav", 0.25); | ||
85 | |||
86 | game.saveGame(map, collider.position); | ||
87 | }); | ||
88 | entity->addComponent(component); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | if (data.hasPhysics) | ||
93 | { | ||
94 | auto component = std::make_shared<PhysicsBodyComponent>(); | ||
95 | entity->addComponent(component); | ||
96 | |||
97 | entity->size = std::make_pair(data.width, data.height); | ||
98 | } | ||
99 | |||
100 | return entity; | ||
101 | } | ||
diff --git a/src/entityfactory.h b/src/entityfactory.h new file mode 100644 index 0000000..a35b5f7 --- /dev/null +++ b/src/entityfactory.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef ENTITYFACTORY_H | ||
2 | #define ENTITYFACTORY_H | ||
3 | |||
4 | #include "entity.h" | ||
5 | #include <memory> | ||
6 | #include <string> | ||
7 | #include <map> | ||
8 | #include "map.h" | ||
9 | |||
10 | class EntityFactory { | ||
11 | public: | ||
12 | static std::shared_ptr<Entity> createNamedEntity(const std::string name, const Map& map); | ||
13 | }; | ||
14 | |||
15 | #endif | ||
diff --git a/src/game.cpp b/src/game.cpp index b149392..7ec4460 100644 --- a/src/game.cpp +++ b/src/game.cpp | |||
@@ -2,12 +2,10 @@ | |||
2 | #include "renderer.h" | 2 | #include "renderer.h" |
3 | #include "components.h" | 3 | #include "components.h" |
4 | #include "muxer.h" | 4 | #include "muxer.h" |
5 | #include "entityfactory.h" | ||
5 | 6 | ||
6 | Game::Game() | 7 | Game::Game() |
7 | { | 8 | { |
8 | m.setLeftMap(&m2); | ||
9 | m2.setRightMap(&m); | ||
10 | |||
11 | player = std::make_shared<Entity>(); | 9 | player = std::make_shared<Entity>(); |
12 | player->position = std::make_pair(100.0,100.0); | 10 | player->position = std::make_pair(100.0,100.0); |
13 | player->size = std::make_pair(10.0,12.0); | 11 | player->size = std::make_pair(10.0,12.0); |
@@ -116,32 +114,10 @@ void Game::loadMap(const Map& map) | |||
116 | auto map_collision = std::make_shared<MapCollisionComponent>(map); | 114 | auto map_collision = std::make_shared<MapCollisionComponent>(map); |
117 | mapEn->addComponent(map_collision); | 115 | mapEn->addComponent(map_collision); |
118 | 116 | ||
117 | // Map in the back, player on top, rest of entities in between | ||
119 | nextEntities.clear(); | 118 | nextEntities.clear(); |
120 | nextEntities.push_back(mapEn); | 119 | nextEntities.push_back(mapEn); |
121 | 120 | map.createEntities(nextEntities); | |
122 | // this is cheating but is just for testing | ||
123 | if (&map == &m2) | ||
124 | { | ||
125 | auto saveEn = std::make_shared<Entity>(); | ||
126 | saveEn->position = std::make_pair(257.0, 160.0); | ||
127 | saveEn->size = std::make_pair(8.0, 11.0); | ||
128 | |||
129 | auto save_render = std::make_shared<StaticImageComponent>("../res/keyring.png"); | ||
130 | saveEn->addComponent(save_render); | ||
131 | |||
132 | auto save_physics = std::make_shared<PhysicsBodyComponent>(); | ||
133 | saveEn->addComponent(save_physics); | ||
134 | |||
135 | auto save_collide = std::make_shared<SimpleColliderComponent>([&] (Entity& collider) { | ||
136 | playSound("../res/Pickup_Coin23.wav", 0.25); | ||
137 | |||
138 | saveGame(map, collider.position); | ||
139 | }); | ||
140 | saveEn->addComponent(save_collide); | ||
141 | |||
142 | nextEntities.push_back(saveEn); | ||
143 | } | ||
144 | |||
145 | nextEntities.push_back(player); | 121 | nextEntities.push_back(player); |
146 | 122 | ||
147 | newWorld = true; | 123 | newWorld = true; |
@@ -160,9 +136,9 @@ void Game::saveGame(const Map& map, std::pair<double, double> position) | |||
160 | save = {&map, position}; | 136 | save = {&map, position}; |
161 | } | 137 | } |
162 | 138 | ||
163 | void Game::schedule(double time, std::function<void ()>&& callback) | 139 | void Game::schedule(double time, std::function<void ()> callback) |
164 | { | 140 | { |
165 | scheduled.emplace_front(time, callback); | 141 | scheduled.emplace_front(time, std::move(callback)); |
166 | } | 142 | } |
167 | 143 | ||
168 | void Game::playerDie(Entity& player, const Map& curMap) | 144 | void Game::playerDie(Entity& player, const Map& curMap) |
diff --git a/src/game.h b/src/game.h index c7c2625..33d1965 100644 --- a/src/game.h +++ b/src/game.h | |||
@@ -30,7 +30,7 @@ class Game { | |||
30 | void loadMap(const Map& map); | 30 | void loadMap(const Map& map); |
31 | void detectCollision(Entity& collider, std::pair<double, double> old_position); | 31 | void detectCollision(Entity& collider, std::pair<double, double> old_position); |
32 | void saveGame(const Map& map, std::pair<double, double> position); | 32 | void saveGame(const Map& map, std::pair<double, double> position); |
33 | void schedule(double time, std::function<void ()>&& callback); | 33 | void schedule(double time, std::function<void ()> callback); |
34 | void playerDie(Entity& player, const Map& curMap); | 34 | void playerDie(Entity& player, const Map& curMap); |
35 | 35 | ||
36 | private: | 36 | private: |
@@ -40,8 +40,8 @@ class Game { | |||
40 | std::list<std::shared_ptr<Entity>> nextEntities; | 40 | std::list<std::shared_ptr<Entity>> nextEntities; |
41 | bool newWorld; | 41 | bool newWorld; |
42 | std::shared_ptr<Entity> player; | 42 | std::shared_ptr<Entity> player; |
43 | Map m{"../maps/embarass.txt"}; | 43 | Map m {Map::getNamedMap("embarass")}; |
44 | Map m2{"../maps/second.txt"}; | 44 | Map m2 {Map::getNamedMap("second")}; |
45 | Savefile save; | 45 | Savefile save; |
46 | std::list<std::pair<double, std::function<void ()>>> scheduled; | 46 | std::list<std::pair<double, std::function<void ()>>> scheduled; |
47 | bool shouldQuit = false; | 47 | bool shouldQuit = false; |
diff --git a/src/map.cpp b/src/map.cpp index 3976b63..8c1c6f0 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
@@ -2,43 +2,111 @@ | |||
2 | #include "game.h" | 2 | #include "game.h" |
3 | #include <cstdlib> | 3 | #include <cstdlib> |
4 | #include <cstring> | 4 | #include <cstring> |
5 | #include <libxml/parser.h> | ||
6 | #include <map> | ||
7 | #include "entityfactory.h" | ||
8 | |||
9 | static std::map<std::string, Map> maps; | ||
5 | 10 | ||
6 | Map::Map() | 11 | Map::Map() |
7 | { | 12 | { |
8 | 13 | title = (char*) calloc(1, sizeof(char)); | |
14 | mapdata = (int*) calloc(1, sizeof(int)); | ||
9 | } | 15 | } |
10 | 16 | ||
11 | Map::Map(const char* filename) | 17 | Map::Map(const std::string name) |
12 | { | 18 | { |
13 | FILE* f = fopen(filename, "r"); | 19 | xmlDocPtr doc = xmlParseFile(("../maps/" + name + ".xml").c_str()); |
20 | if (doc == nullptr) | ||
21 | { | ||
22 | fprintf(stderr, "Error reading map %s\n", name.c_str()); | ||
23 | exit(-1); | ||
24 | } | ||
14 | 25 | ||
15 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 26 | xmlNodePtr top = xmlDocGetRootElement(doc); |
16 | for (int i=0; i<MAP_HEIGHT-1; i++) | 27 | if (top == nullptr) |
17 | { | 28 | { |
18 | for (int j=0; j<MAP_WIDTH; j++) | 29 | fprintf(stderr, "Empty map %s\n", name.c_str()); |
30 | exit(-1); | ||
31 | } | ||
32 | |||
33 | if (xmlStrcmp(top->name, (const xmlChar*) "map-def")) | ||
34 | { | ||
35 | fprintf(stderr, "Invalid map definition %s\n", name.c_str()); | ||
36 | exit(-1); | ||
37 | } | ||
38 | |||
39 | for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) | ||
40 | { | ||
41 | if (!xmlStrcmp(node->name, (const xmlChar*) "name")) | ||
42 | { | ||
43 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
44 | title = (char*) calloc(xmlStrlen(key) + 1, sizeof(char)); | ||
45 | strcpy(title, (char*) key); | ||
46 | xmlFree(key); | ||
47 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "environment")) | ||
48 | { | ||
49 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
50 | mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | ||
51 | mapdata[0] = atoi(strtok((char*) key, ",\n")); | ||
52 | for (int i=1; i<(MAP_WIDTH*(MAP_HEIGHT-1)); i++) | ||
53 | { | ||
54 | mapdata[i] = atoi(strtok(NULL, ",\n")); | ||
55 | } | ||
56 | xmlFree(key); | ||
57 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "entities")) | ||
19 | { | 58 | { |
20 | fscanf(f, "%d,", &(m_mapdata[i*MAP_WIDTH + j])); | 59 | for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next) |
60 | { | ||
61 | if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity")) | ||
62 | { | ||
63 | EntityData data; | ||
64 | for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next) | ||
65 | { | ||
66 | if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type")) | ||
67 | { | ||
68 | xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); | ||
69 | data.name = std::string((char*) key); | ||
70 | xmlFree(key); | ||
71 | } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position")) | ||
72 | { | ||
73 | xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); | ||
74 | sscanf((char*) key, "%lf,%lf", &(data.position.first), &(data.position.second)); | ||
75 | xmlFree(key); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | entities.push_back(data); | ||
80 | } | ||
81 | } | ||
82 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "leftmap")) | ||
83 | { | ||
84 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
85 | leftMap = &Map::getNamedMap(std::string((char*) key)); | ||
86 | xmlFree(key); | ||
87 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "rightmap")) | ||
88 | { | ||
89 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
90 | rightMap = &Map::getNamedMap(std::string((char*) key)); | ||
91 | xmlFree(key); | ||
21 | } | 92 | } |
22 | |||
23 | fgetc(f); | ||
24 | } | 93 | } |
25 | 94 | ||
26 | m_title = (char*) calloc(41, sizeof(char)); | 95 | xmlFreeDoc(doc); |
27 | fgets(m_title, 41, f); | ||
28 | |||
29 | fclose(f); | ||
30 | } | 96 | } |
31 | 97 | ||
32 | Map::Map(Map& map) | 98 | Map::Map(const Map& map) |
33 | { | 99 | { |
34 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 100 | mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); |
35 | memcpy(m_mapdata, map.m_mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | 101 | memcpy(mapdata, map.mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); |
102 | |||
103 | title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); | ||
104 | strncpy(title, map.title, MAP_WIDTH+1); | ||
36 | 105 | ||
37 | m_title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); | 106 | leftMap = map.leftMap; |
38 | strncpy(m_title, map.m_title, MAP_WIDTH+1); | 107 | rightMap = map.rightMap; |
39 | 108 | ||
40 | m_leftMap = map.m_leftMap; | 109 | entities = map.entities; |
41 | m_rightMap = map.m_rightMap; | ||
42 | } | 110 | } |
43 | 111 | ||
44 | Map::Map(Map&& map) : Map() | 112 | Map::Map(Map&& map) : Map() |
@@ -48,8 +116,8 @@ Map::Map(Map&& map) : Map() | |||
48 | 116 | ||
49 | Map::~Map() | 117 | Map::~Map() |
50 | { | 118 | { |
51 | free(m_mapdata); | 119 | free(mapdata); |
52 | free(m_title); | 120 | free(title); |
53 | } | 121 | } |
54 | 122 | ||
55 | Map& Map::operator= (Map map) | 123 | Map& Map::operator= (Map map) |
@@ -61,38 +129,60 @@ Map& Map::operator= (Map map) | |||
61 | 129 | ||
62 | void swap(Map& first, Map& second) | 130 | void swap(Map& first, Map& second) |
63 | { | 131 | { |
64 | std::swap(first.m_mapdata, second.m_mapdata); | 132 | std::swap(first.mapdata, second.mapdata); |
65 | std::swap(first.m_title, second.m_title); | 133 | std::swap(first.title, second.title); |
66 | std::swap(first.m_leftMap, second.m_leftMap); | 134 | std::swap(first.leftMap, second.leftMap); |
67 | std::swap(first.m_rightMap, second.m_rightMap); | 135 | std::swap(first.rightMap, second.rightMap); |
136 | std::swap(first.entities, second.entities); | ||
68 | } | 137 | } |
69 | 138 | ||
70 | const int* Map::mapdata() const | 139 | const int* Map::getMapdata() const |
71 | { | 140 | { |
72 | return m_mapdata; | 141 | return mapdata; |
73 | } | 142 | } |
74 | 143 | ||
75 | const char* Map::title() const | 144 | const char* Map::getTitle() const |
76 | { | 145 | { |
77 | return m_title; | 146 | return title; |
78 | } | 147 | } |
79 | 148 | ||
80 | const Map* Map::getLeftMap() const | 149 | const Map* Map::getLeftMap() const |
81 | { | 150 | { |
82 | return m_leftMap; | 151 | return leftMap; |
83 | } | 152 | } |
84 | 153 | ||
85 | const Map* Map::getRightMap() const | 154 | const Map* Map::getRightMap() const |
86 | { | 155 | { |
87 | return m_rightMap; | 156 | return rightMap; |
88 | } | 157 | } |
89 | 158 | ||
90 | void Map::setLeftMap(const Map* m) | 159 | void Map::setLeftMap(const Map* m) |
91 | { | 160 | { |
92 | m_leftMap = m; | 161 | leftMap = m; |
93 | } | 162 | } |
94 | 163 | ||
95 | void Map::setRightMap(const Map* m) | 164 | void Map::setRightMap(const Map* m) |
96 | { | 165 | { |
97 | m_rightMap = m; | 166 | rightMap = m; |
167 | } | ||
168 | |||
169 | void Map::createEntities(std::list<std::shared_ptr<Entity>>& entities) const | ||
170 | { | ||
171 | for (auto data : this->entities) | ||
172 | { | ||
173 | auto entity = EntityFactory::createNamedEntity(data.name, *this); | ||
174 | entity->position = data.position; | ||
175 | |||
176 | entities.push_back(entity); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | Map& Map::getNamedMap(const std::string name) | ||
181 | { | ||
182 | if (maps.count(name) == 0) | ||
183 | { | ||
184 | maps[name] = Map {name}; | ||
185 | } | ||
186 | |||
187 | return maps[name]; | ||
98 | } | 188 | } |
diff --git a/src/map.h b/src/map.h index 071b6f2..fa2edcc 100644 --- a/src/map.h +++ b/src/map.h | |||
@@ -1,28 +1,41 @@ | |||
1 | #ifndef MAP_H | 1 | #ifndef MAP_H |
2 | #define MAP_H | 2 | #define MAP_H |
3 | 3 | ||
4 | #include <string> | ||
5 | #include <list> | ||
6 | |||
7 | class Entity; | ||
8 | |||
4 | class Map { | 9 | class Map { |
5 | public: | 10 | public: |
6 | Map(const char* filename); | 11 | Map(); |
7 | Map(Map& map); | 12 | Map(const std::string name); |
13 | Map(const Map& map); | ||
8 | Map(Map&& map); | 14 | Map(Map&& map); |
9 | ~Map(); | 15 | ~Map(); |
10 | Map& operator= (Map other); | 16 | Map& operator= (Map other); |
11 | friend void swap(Map& first, Map& second); | 17 | friend void swap(Map& first, Map& second); |
12 | 18 | ||
13 | const int* mapdata() const; | 19 | static Map& getNamedMap(const std::string name); |
14 | const char* title() const; | 20 | |
21 | const int* getMapdata() const; | ||
22 | const char* getTitle() const; | ||
15 | const Map* getLeftMap() const; | 23 | const Map* getLeftMap() const; |
16 | const Map* getRightMap() const; | 24 | const Map* getRightMap() const; |
17 | void setLeftMap(const Map* m); | 25 | void setLeftMap(const Map* m); |
18 | void setRightMap(const Map* m); | 26 | void setRightMap(const Map* m); |
27 | void createEntities(std::list<std::shared_ptr<Entity>>& entities) const; | ||
19 | private: | 28 | private: |
20 | Map(); | 29 | struct EntityData { |
30 | std::string name; | ||
31 | std::pair<double, double> position; | ||
32 | }; | ||
21 | 33 | ||
22 | int* m_mapdata; | 34 | int* mapdata; |
23 | char* m_title; | 35 | char* title; |
24 | const Map* m_leftMap = nullptr; | 36 | const Map* leftMap = nullptr; |
25 | const Map* m_rightMap = nullptr; | 37 | const Map* rightMap = nullptr; |
38 | std::list<EntityData> entities; | ||
26 | }; | 39 | }; |
27 | 40 | ||
28 | #endif | 41 | #endif |
diff --git a/src/renderer.cpp b/src/renderer.cpp index 64c9fd0..c2b37d2 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -513,7 +513,7 @@ Texture::Texture(const char* filename) | |||
513 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 513 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
514 | } | 514 | } |
515 | 515 | ||
516 | Texture::Texture(Texture& tex) | 516 | Texture::Texture(const Texture& tex) |
517 | { | 517 | { |
518 | if (!rendererInitialized) | 518 | if (!rendererInitialized) |
519 | { | 519 | { |
diff --git a/src/renderer.h b/src/renderer.h index 90ec101..84ad688 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -15,7 +15,7 @@ class Texture { | |||
15 | public: | 15 | public: |
16 | Texture(int width, int height); | 16 | Texture(int width, int height); |
17 | Texture(const char* file); | 17 | Texture(const char* file); |
18 | Texture(Texture& tex); | 18 | Texture(const Texture& tex); |
19 | Texture(Texture&& tex); | 19 | Texture(Texture&& tex); |
20 | ~Texture(); | 20 | ~Texture(); |
21 | Texture& operator= (Texture tex); | 21 | Texture& operator= (Texture tex); |