summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--res/maps.xml32
-rw-r--r--src/components/map_collision.cpp29
-rw-r--r--src/components/map_collision.h3
-rw-r--r--src/components/map_render.cpp1
-rw-r--r--src/components/physics_body.cpp1
-rw-r--r--src/components/player_physics.cpp1
-rw-r--r--src/consts.h14
-rw-r--r--src/game.cpp168
-rw-r--r--src/game.h21
-rw-r--r--src/main.cpp2
-rw-r--r--src/map.cpp263
-rw-r--r--src/map.h56
-rw-r--r--src/renderer.cpp2
13 files changed, 421 insertions, 172 deletions
diff --git a/res/maps.xml b/res/maps.xml index dff3775..594cd18 100644 --- a/res/maps.xml +++ b/res/maps.xml
@@ -1,5 +1,5 @@
1<?xml version="1.0" encoding="ISO-8859-1"?> 1<?xml version="1.0" encoding="ISO-8859-1"?>
2<world><nextmapid>4</nextmapid><lastmap>1</lastmap><root>0</root><startpos id="0" pos="203,44"/><map id="0"><name>Everything Is Embarrassing</name><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<world><nextmapid>5</nextmapid><lastmap>4</lastmap><root>0</root><startpos id="0" pos="203,44"/><map id="0"><name>Everything Is Embarrassing</name><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,
30,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, 30,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,
40,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, 40,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,
50,19,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,0,0,0,0,0,0,0,0,0,12, 50,19,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,0,0,0,0,0,0,0,0,0,12,
@@ -23,7 +23,7 @@
230,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, 230,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,
241,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, 241,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,
250,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, 250,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</environment><leftmap type="warp" map="1"/><rightmap type="wall"/><upmap type="wall"/><downmap type="wall"/><entities/><child>1</child><expanded>1</expanded></map><map id="1"><name>It's A Trap!</name><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, 26</environment><leftmap type="warp" map="1"/><rightmap type="wall"/><upmap type="wall"/><downmap type="wall"/><entities/><child>1</child><child>4</child><expanded>1</expanded></map><map id="1"><name>It's A Trap!</name><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,
270,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, 270,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,
280,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, 280,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,
290,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, 290,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,
@@ -46,5 +46,29 @@
460,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, 460,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,
470,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, 470,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,
480,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, 480,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,
490,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, 490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,19,0,0,0,0,0,
50</environment><leftmap type="wall"/><rightmap type="warp" map="0"/><upmap type="wall"/><downmap type="wall"/><entities><entity><entity-type>checkpoint</entity-type><entity-position>262,156</entity-position></entity></entities></map></world> 50</environment><leftmap type="wall"/><rightmap type="warp" map="0"/><upmap type="wall"/><downmap type="warp" map="4"/><entities><entity><entity-type>checkpoint</entity-type><entity-position>262,156</entity-position></entity></entities></map><map id="4"><name>The Visitors</name><environment>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
510,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,20,0,0,0,0,
520,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
530,0,0,0,19,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
540,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
550,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,19,0,0,0,0,20,0,
560,0,19,0,0,0,0,0,0,0,20,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,19,0,0,0,0,
590,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,19,0,0,0,0,0,0,0,
600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
610,0,0,0,20,0,0,0,0,0,0,20,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,28,29,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
630,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,14,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,19,0,0,0,0,0,
640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,30,31,32,41,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
650,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,19,0,0,0,
660,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,19,0,0,0,0,0,0,0,
670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
680,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
690,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,19,0,0,0,0,0,0,
700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,20,0,0,
710,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
720,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,15,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,
730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,
74</environment><leftmap type="wall"/><rightmap type="wall"/><upmap type="warp" map="1"/><downmap type="wall"/><entities/></map></world>
diff --git a/src/components/map_collision.cpp b/src/components/map_collision.cpp index 9afa6f8..9adad26 100644 --- a/src/components/map_collision.cpp +++ b/src/components/map_collision.cpp
@@ -1,11 +1,14 @@
1#include "map_collision.h" 1#include "map_collision.h"
2#include "map.h" 2#include "map.h"
3#include "game.h" 3#include "game.h"
4#include "consts.h"
4 5
5MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map) 6MapCollisionComponent::MapCollisionComponent(const Map& map) : map(map)
6{ 7{
7 addCollision(-6, 0, GAME_WIDTH, Direction::left, (map.getLeftMap() == nullptr) ? Collision::Type::wrap : Collision::Type::teleport); 8 addCollision(-6, 0, GAME_HEIGHT, Direction::left, collisionFromMoveType(map.getLeftMoveType()));
8 addCollision(GAME_WIDTH+6, 0, GAME_WIDTH, Direction::right, (map.getRightMap() == nullptr) ? Collision::Type::reverse : Collision::Type::teleport); 9 addCollision(GAME_WIDTH+6, 0, GAME_HEIGHT, Direction::right, collisionFromMoveType(map.getRightMoveType()));
10 addCollision(-7, 0, GAME_WIDTH, Direction::up, collisionFromMoveType(map.getUpMoveType()));
11 addCollision(GAME_HEIGHT+6, 0, GAME_WIDTH, Direction::down, collisionFromMoveType(map.getDownMoveType()));
9 12
10 for (int i=0; i<MAP_WIDTH*MAP_HEIGHT; i++) 13 for (int i=0; i<MAP_WIDTH*MAP_HEIGHT; i++)
11 { 14 {
@@ -186,13 +189,20 @@ void MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli
186 { 189 {
187 if (dir == Direction::left) 190 if (dir == Direction::left)
188 { 191 {
189 game.loadMap(*map.getLeftMap(), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second)); 192 game.loadMap(game.getMap(map.getLeftMapID()), std::make_pair(GAME_WIDTH-collider.size.first/2, old_position.second));
190 } else if (dir == Direction::right) 193 } else if (dir == Direction::right)
191 { 194 {
192 game.loadMap(*map.getRightMap(), std::make_pair(-collider.size.first/2, old_position.second)); 195 game.loadMap(game.getMap(map.getRightMapID()), std::make_pair(-collider.size.first/2, old_position.second));
196 } else if (dir == Direction::up)
197 {
198 game.loadMap(game.getMap(map.getUpMapID()), std::make_pair(old_position.first, GAME_HEIGHT-collider.size.second/2));
199 } else if (dir == Direction::down)
200 {
201 game.loadMap(game.getMap(map.getDownMapID()), std::make_pair(old_position.first, -collider.size.second/2));
193 } 202 }
194 } else if (collision.type == Collision::Type::reverse) 203 } else if (collision.type == Collision::Type::reverse)
195 { 204 {
205 // TODO reverse
196 if (dir == Direction::right) 206 if (dir == Direction::right)
197 { 207 {
198 collider.position.first = collision.axis - collider.size.first; 208 collider.position.first = collision.axis - collider.size.first;
@@ -209,3 +219,14 @@ void MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli
209 game.playerDie(); 219 game.playerDie();
210 } 220 }
211} 221}
222
223MapCollisionComponent::Collision::Type MapCollisionComponent::collisionFromMoveType(Map::MoveType type)
224{
225 switch (type)
226 {
227 case Map::MoveType::Wall: return Collision::Type::wall;
228 case Map::MoveType::Wrap: return Collision::Type::wrap;
229 case Map::MoveType::Warp: return Collision::Type::teleport;
230 case Map::MoveType::ReverseWarp: return Collision::Type::reverse;
231 }
232}
diff --git a/src/components/map_collision.h b/src/components/map_collision.h index 3b718b6..18b9397 100644 --- a/src/components/map_collision.h +++ b/src/components/map_collision.h
@@ -2,9 +2,9 @@
2#define MAP_COLLISION_H 2#define MAP_COLLISION_H
3 3
4#include "entity.h" 4#include "entity.h"
5#include "map.h"
5#include <list> 6#include <list>
6 7
7class Map;
8class Game; 8class Game;
9 9
10class MapCollisionComponent : public Component { 10class MapCollisionComponent : public Component {
@@ -35,6 +35,7 @@ class MapCollisionComponent : public Component {
35 35
36 void addCollision(double axis, double lower, double upper, Direction dir, Collision::Type type); 36 void addCollision(double axis, double lower, double upper, Direction dir, Collision::Type type);
37 void processCollision(Game& game, Entity& collider, Collision collision, Direction dir, std::pair<double, double> old_position); 37 void processCollision(Game& game, Entity& collider, Collision collision, Direction dir, std::pair<double, double> old_position);
38 Collision::Type collisionFromMoveType(Map::MoveType type);
38 39
39 std::list<Collision> left_collisions; 40 std::list<Collision> left_collisions;
40 std::list<Collision> right_collisions; 41 std::list<Collision> right_collisions;
diff --git a/src/components/map_render.cpp b/src/components/map_render.cpp index 10c5db8..45766e1 100644 --- a/src/components/map_render.cpp +++ b/src/components/map_render.cpp
@@ -1,6 +1,7 @@
1#include "map_render.h" 1#include "map_render.h"
2#include "map.h" 2#include "map.h"
3#include "game.h" 3#include "game.h"
4#include "consts.h"
4 5
5MapRenderComponent::MapRenderComponent(const Map& map) : screen(GAME_WIDTH, GAME_HEIGHT) 6MapRenderComponent::MapRenderComponent(const Map& map) : screen(GAME_WIDTH, GAME_HEIGHT)
6{ 7{
diff --git a/src/components/physics_body.cpp b/src/components/physics_body.cpp index 72f2fd8..acbdc5d 100644 --- a/src/components/physics_body.cpp +++ b/src/components/physics_body.cpp
@@ -1,5 +1,6 @@
1#include "physics_body.h" 1#include "physics_body.h"
2#include "game.h" 2#include "game.h"
3#include "consts.h"
3 4
4void PhysicsBodyComponent::receive(Game&, Entity&, const Message& msg) 5void PhysicsBodyComponent::receive(Game&, Entity&, const Message& msg)
5{ 6{
diff --git a/src/components/player_physics.cpp b/src/components/player_physics.cpp index e366d6e..1d14f35 100644 --- a/src/components/player_physics.cpp +++ b/src/components/player_physics.cpp
@@ -1,6 +1,7 @@
1#include "player_physics.h" 1#include "player_physics.h"
2#include "muxer.h" 2#include "muxer.h"
3#include "game.h" 3#include "game.h"
4#include "consts.h"
4 5
5#define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) 6#define JUMP_VELOCITY(h, l) (-2 * (h) / (l))
6#define JUMP_GRAVITY(h, l) (2 * ((h) / (l)) / (l)) 7#define JUMP_GRAVITY(h, l) (2 * ((h) / (l)) / (l))
diff --git a/src/consts.h b/src/consts.h new file mode 100644 index 0000000..804c761 --- /dev/null +++ b/src/consts.h
@@ -0,0 +1,14 @@
1#ifndef CONSTS_H
2#define CONSTS_H
3
4const int TILE_WIDTH = 8;
5const int TILE_HEIGHT = 8;
6const int GAME_WIDTH = 320;
7const int GAME_HEIGHT = 200;
8const int MAP_WIDTH = GAME_WIDTH/TILE_WIDTH;
9const int MAP_HEIGHT = GAME_HEIGHT/TILE_HEIGHT - 1;
10
11const int FRAMES_PER_SECOND = 60;
12const double SECONDS_PER_FRAME = 1.0 / FRAMES_PER_SECOND;
13
14#endif
diff --git a/src/game.cpp b/src/game.cpp index 1c9bb58..4a08744 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -1,4 +1,6 @@
1#include "game.h" 1#include "game.h"
2#include <cstdlib>
3#include <libxml/parser.h>
2#include "renderer.h" 4#include "renderer.h"
3#include "muxer.h" 5#include "muxer.h"
4#include "map.h" 6#include "map.h"
@@ -7,11 +9,166 @@
7#include "components/player_sprite.h" 9#include "components/player_sprite.h"
8#include "components/map_render.h" 10#include "components/map_render.h"
9#include "components/map_collision.h" 11#include "components/map_collision.h"
12#include "consts.h"
10 13
11Game::Game() 14Game::Game(const char* mapfile)
12{ 15{
16 // Load maps
17 xmlDocPtr doc = xmlParseFile(mapfile);
18 if (doc == nullptr)
19 {
20 exit(2);
21 }
22
23 xmlNodePtr top = xmlDocGetRootElement(doc);
24 if (top == nullptr)
25 {
26 exit(2);
27 }
28
29 if (xmlStrcmp(top->name, (const xmlChar*) "world"))
30 {
31 exit(2);
32 }
33
34 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
35 {
36 if (!xmlStrcmp(node->name, (const xmlChar*) "startpos"))
37 {
38 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
39 if (idKey == 0) exit(2);
40 startMap = atoi((char*) idKey);
41 xmlFree(idKey);
42
43 xmlChar* posKey = xmlGetProp(node, (xmlChar*) "pos");
44 if (posKey == 0) exit(2);
45 sscanf((char*) posKey, "%d,%d", &startPos.first, &startPos.second);
46 xmlFree(posKey);
47 } else if (!xmlStrcmp(node->name, (const xmlChar*) "map"))
48 {
49 xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id");
50 if (idKey == 0) exit(2);
51 int theId = atoi((char*) idKey);
52 xmlFree(idKey);
53
54 Map map {theId};
55
56 for (xmlNodePtr mapNode = node->xmlChildrenNode; mapNode != NULL; mapNode = mapNode->next)
57 {
58 if (!xmlStrcmp(mapNode->name, (const xmlChar*) "name"))
59 {
60 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
61 if (key != 0)
62 {
63 map.setTitle((char*) key);
64 }
65
66 xmlFree(key);
67 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "environment"))
68 {
69 xmlChar* key = xmlNodeListGetString(doc, mapNode->xmlChildrenNode, 1);
70 int* mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
71 mapdata[0] = atoi(strtok((char*) key, ",\n"));
72 for (int i=1; i<(MAP_WIDTH*MAP_HEIGHT); i++)
73 {
74 mapdata[i] = atoi(strtok(NULL, ",\n"));
75 }
76 map.setMapdata(mapdata);
77 xmlFree(key);
78 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "leftmap"))
79 {
80 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
81 if (typeKey == 0) exit(2);
82 map.setLeftMoveType(Map::moveTypeForShort((char*) typeKey));
83 xmlFree(typeKey);
84
85 if (Map::moveTypeTakesMap(map.getLeftMoveType()))
86 {
87 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
88 if (idKey == 0) exit(2);
89 map.setLeftMapID(atoi((char*) idKey));
90 xmlFree(idKey);
91 }
92 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "rightmap"))
93 {
94 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
95 if (typeKey == 0) exit(2);
96 map.setRightMoveType(Map::moveTypeForShort((char*) typeKey));
97 xmlFree(typeKey);
98
99 if (Map::moveTypeTakesMap(map.getRightMoveType()))
100 {
101 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
102 if (idKey == 0) exit(2);
103 map.setRightMapID(atoi((char*) idKey));
104 xmlFree(idKey);
105 }
106 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "upmap"))
107 {
108 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
109 if (typeKey == 0) exit(2);
110 map.setUpMoveType(Map::moveTypeForShort((char*) typeKey));
111 xmlFree(typeKey);
112
113 if (Map::moveTypeTakesMap(map.getUpMoveType()))
114 {
115 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
116 if (idKey == 0) exit(2);
117 map.setUpMapID(atoi((char*) idKey));
118 xmlFree(idKey);
119 }
120 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "downmap"))
121 {
122 xmlChar* typeKey = xmlGetProp(mapNode, (xmlChar*) "type");
123 if (typeKey == 0) exit(2);
124 map.setDownMoveType(Map::moveTypeForShort((char*) typeKey));
125 xmlFree(typeKey);
126
127 if (Map::moveTypeTakesMap(map.getDownMoveType()))
128 {
129 xmlChar* idKey = xmlGetProp(mapNode, (xmlChar*) "map");
130 if (idKey == 0) exit(2);
131 map.setDownMapID(atoi((char*) idKey));
132 xmlFree(idKey);
133 }
134 } else if (!xmlStrcmp(mapNode->name, (const xmlChar*) "entities"))
135 {
136 for (xmlNodePtr entityNode = mapNode->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next)
137 {
138 if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity"))
139 {
140 Map::EntityData data;
141
142 for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next)
143 {
144 if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type"))
145 {
146 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
147 data.name = (char*) key;
148 xmlFree(key);
149 } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position"))
150 {
151 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
152 sscanf((char*) key, "%d,%d", &data.position.first, &data.position.second);
153 xmlFree(key);
154 }
155 }
156
157 map.addEntity(data);
158 }
159 }
160 }
161 }
162
163 maps[theId] = map;
164 }
165 }
166
167 xmlFreeDoc(doc);
168
169 // Set up entities
13 player = std::make_shared<Entity>(); 170 player = std::make_shared<Entity>();
14 player->position = std::make_pair(100.0,100.0); 171 player->position = startPos;
15 player->size = std::make_pair(10.0,12.0); 172 player->size = std::make_pair(10.0,12.0);
16 173
17 auto player_input = std::make_shared<UserMovementComponent>(); 174 auto player_input = std::make_shared<UserMovementComponent>();
@@ -23,7 +180,7 @@ Game::Game()
23 auto player_anim = std::make_shared<PlayerSpriteComponent>(); 180 auto player_anim = std::make_shared<PlayerSpriteComponent>();
24 player->addComponent(player_anim); 181 player->addComponent(player_anim);
25 182
26 Map& startingMap = Map::getNamedMap("embarass"); 183 Map& startingMap = maps[startMap];
27 save = {&startingMap, player->position}; 184 save = {&startingMap, player->position};
28 185
29 loadMap(startingMap, player->position); 186 loadMap(startingMap, player->position);
@@ -168,3 +325,8 @@ void Game::playerDie()
168 player->send(*this, Message::Type::stopDying); 325 player->send(*this, Message::Type::stopDying);
169 }); 326 });
170} 327}
328
329const Map& Game::getMap(int id) const
330{
331 return maps.at(id);
332}
diff --git a/src/game.h b/src/game.h index 1818cec..3f0fcc8 100644 --- a/src/game.h +++ b/src/game.h
@@ -3,21 +3,12 @@
3 3
4#include <memory> 4#include <memory>
5#include <functional> 5#include <functional>
6#include "renderer.h"
7#include <list> 6#include <list>
7#include <map>
8#include "map.h"
8 9
9class Entity; 10class Entity;
10class Map; 11struct GLFWwindow;
11
12const int TILE_WIDTH = 8;
13const int TILE_HEIGHT = 8;
14const int GAME_WIDTH = 320;
15const int GAME_HEIGHT = 200;
16const int MAP_WIDTH = GAME_WIDTH/TILE_WIDTH;
17const int MAP_HEIGHT = GAME_HEIGHT/TILE_HEIGHT - 1;
18
19const int FRAMES_PER_SECOND = 60;
20const double SECONDS_PER_FRAME = 1.0 / FRAMES_PER_SECOND;
21 12
22struct Savefile { 13struct Savefile {
23 const Map* map; 14 const Map* map;
@@ -26,17 +17,21 @@ struct Savefile {
26 17
27class Game { 18class Game {
28 public: 19 public:
29 Game(); 20 Game(const char* maps);
30 void execute(GLFWwindow* window); 21 void execute(GLFWwindow* window);
31 void loadMap(const Map& map, std::pair<double, double> position); 22 void loadMap(const Map& map, std::pair<double, double> position);
32 void detectCollision(Entity& collider, std::pair<double, double> old_position); 23 void detectCollision(Entity& collider, std::pair<double, double> old_position);
33 void saveGame(); 24 void saveGame();
34 void schedule(double time, std::function<void ()> callback); 25 void schedule(double time, std::function<void ()> callback);
35 void playerDie(); 26 void playerDie();
27 const Map& getMap(int id) const;
36 28
37 private: 29 private:
38 friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); 30 friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
39 31
32 std::map<int, Map> maps;
33 int startMap;
34 std::pair<int, int> startPos;
40 std::list<std::shared_ptr<Entity>> entities; 35 std::list<std::shared_ptr<Entity>> entities;
41 std::list<std::shared_ptr<Entity>> nextEntities; 36 std::list<std::shared_ptr<Entity>> nextEntities;
42 std::pair<double, double> nextPosition; 37 std::pair<double, double> nextPosition;
diff --git a/src/main.cpp b/src/main.cpp index 96eb7da..4157350 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -14,7 +14,7 @@ int main()
14 14
15 // Put this in a block so game goes out of scope before we destroy the renderer 15 // Put this in a block so game goes out of scope before we destroy the renderer
16 { 16 {
17 Game game; 17 Game game {"res/maps.xml"};
18 game.execute(window); 18 game.execute(window);
19 } 19 }
20 20
diff --git a/src/map.cpp b/src/map.cpp index 11d1d52..fa940ef 100644 --- a/src/map.cpp +++ b/src/map.cpp
@@ -1,129 +1,34 @@
1#include "map.h" 1#include "map.h"
2#include "game.h"
3#include <cstdlib> 2#include <cstdlib>
4#include <cstring> 3#include <cstring>
5#include <libxml/parser.h>
6#include <map> 4#include <map>
7#include "entityfactory.h" 5#include "entityfactory.h"
8#include "entity.h" 6#include "entity.h"
7#include "game.h"
8#include "consts.h"
9 9
10static std::map<std::string, Map> maps; 10Map::Map(int id)
11
12Map::Map()
13{ 11{
12 this->id = id;
14 mapdata = (int*) calloc(1, sizeof(int)); 13 mapdata = (int*) calloc(1, sizeof(int));
15} 14}
16 15
17Map::Map(const std::string name)
18{
19 this->name = name;
20
21 xmlDocPtr doc = xmlParseFile(("maps/" + name + ".xml").c_str());
22 if (doc == nullptr)
23 {
24 fprintf(stderr, "Error reading map %s\n", name.c_str());
25 exit(-1);
26 }
27
28 xmlNodePtr top = xmlDocGetRootElement(doc);
29 if (top == nullptr)
30 {
31 fprintf(stderr, "Empty map %s\n", name.c_str());
32 exit(-1);
33 }
34
35 if (xmlStrcmp(top->name, (const xmlChar*) "map-def"))
36 {
37 fprintf(stderr, "Invalid map definition %s\n", name.c_str());
38 exit(-1);
39 }
40
41 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
42 {
43 if (!xmlStrcmp(node->name, (const xmlChar*) "name"))
44 {
45 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
46 if (key != 0)
47 {
48 title = (char*) key;
49 }
50
51 xmlFree(key);
52 } else if (!xmlStrcmp(node->name, (const xmlChar*) "environment"))
53 {
54 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
55 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
56 mapdata[0] = atoi(strtok((char*) key, ",\n"));
57 for (int i=1; i<(MAP_WIDTH*MAP_HEIGHT); i++)
58 {
59 mapdata[i] = atoi(strtok(NULL, ",\n"));
60 }
61 xmlFree(key);
62 } else if (!xmlStrcmp(node->name, (const xmlChar*) "entities"))
63 {
64 for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next)
65 {
66 if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity"))
67 {
68 EntityData data;
69 for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next)
70 {
71 if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type"))
72 {
73 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
74 if (key != 0)
75 {
76 data.name = (char*) key;
77 }
78
79 xmlFree(key);
80 } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position"))
81 {
82 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
83 sscanf((char*) key, "%lf,%lf", &data.position.first, &data.position.second);
84 xmlFree(key);
85 }
86 }
87
88 entities.push_back(data);
89 }
90 }
91 } else if (!xmlStrcmp(node->name, (const xmlChar*) "leftmap"))
92 {
93 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
94 if (key != 0)
95 {
96 leftMap = &Map::getNamedMap((char*) key);
97 }
98
99 xmlFree(key);
100 } else if (!xmlStrcmp(node->name, (const xmlChar*) "rightmap"))
101 {
102 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
103 if (key != 0)
104 {
105 rightMap = &Map::getNamedMap((char*) key);
106 }
107
108 xmlFree(key);
109 }
110 }
111
112 xmlFreeDoc(doc);
113}
114
115Map::Map(const Map& map) 16Map::Map(const Map& map)
116{ 17{
117 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int)); 18 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
118 memcpy(mapdata, map.mapdata, MAP_WIDTH*MAP_HEIGHT*sizeof(int)); 19 memcpy(mapdata, map.mapdata, MAP_WIDTH*MAP_HEIGHT*sizeof(int));
119 20
21 id = map.id;
120 title = map.title; 22 title = map.title;
121 leftMap = map.leftMap; 23 leftMap = map.leftMap;
122 rightMap = map.rightMap; 24 rightMap = map.rightMap;
123 25 downMap = map.downMap;
26 upMap = map.upMap;
27 leftType = map.leftType;
28 rightType = map.rightType;
29 upType = map.upType;
30 downType = map.downType;
124 entities = map.entities; 31 entities = map.entities;
125
126 name = map.name;
127} 32}
128 33
129Map::Map(Map&& map) : Map() 34Map::Map(Map&& map) : Map()
@@ -149,8 +54,19 @@ void swap(Map& first, Map& second)
149 std::swap(first.title, second.title); 54 std::swap(first.title, second.title);
150 std::swap(first.leftMap, second.leftMap); 55 std::swap(first.leftMap, second.leftMap);
151 std::swap(first.rightMap, second.rightMap); 56 std::swap(first.rightMap, second.rightMap);
57 std::swap(first.downMap, second.downMap);
58 std::swap(first.upMap, second.upMap);
59 std::swap(first.leftType, second.leftType);
60 std::swap(first.rightType, second.rightType);
61 std::swap(first.upType, second.upType);
62 std::swap(first.downType, second.downType);
63 std::swap(first.id, second.id);
152 std::swap(first.entities, second.entities); 64 std::swap(first.entities, second.entities);
153 std::swap(first.name, second.name); 65}
66
67int Map::getID() const
68{
69 return id;
154} 70}
155 71
156const int* Map::getMapdata() const 72const int* Map::getMapdata() const
@@ -163,53 +79,140 @@ std::string Map::getTitle() const
163 return title; 79 return title;
164} 80}
165 81
166const Map* Map::getLeftMap() const 82void Map::createEntities(std::list<std::shared_ptr<Entity>>& entities) const
83{
84 for (auto data : this->entities)
85 {
86 auto entity = EntityFactory::createNamedEntity(data.name);
87 entity->position = data.position;
88
89 entities.push_back(entity);
90 }
91}
92
93bool Map::operator==(const Map& other) const
94{
95 return id == other.id;
96}
97
98bool Map::operator!=(const Map& other) const
99{
100 return id != other.id;
101}
102
103Map::MoveType Map::moveTypeForShort(std::string str)
104{
105 if (str == "wrap") return MoveType::Wrap;
106 if (str == "warp") return MoveType::Warp;
107 if (str == "reverseWarp") return MoveType::ReverseWarp;
108
109 return MoveType::Wall;
110}
111
112Map::MoveType Map::getLeftMoveType() const
113{
114 return leftType;
115}
116
117Map::MoveType Map::getRightMoveType() const
118{
119 return rightType;
120}
121
122Map::MoveType Map::getUpMoveType() const
123{
124 return upType;
125}
126
127Map::MoveType Map::getDownMoveType() const
128{
129 return downType;
130}
131
132int Map::getLeftMapID() const
167{ 133{
168 return leftMap; 134 return leftMap;
169} 135}
170 136
171const Map* Map::getRightMap() const 137int Map::getRightMapID() const
172{ 138{
173 return rightMap; 139 return rightMap;
174} 140}
175 141
176void Map::setLeftMap(const Map* m) 142int Map::getUpMapID() const
177{ 143{
178 leftMap = m; 144 return upMap;
179} 145}
180 146
181void Map::setRightMap(const Map* m) 147int Map::getDownMapID() const
182{ 148{
183 rightMap = m; 149 return downMap;
184} 150}
185 151
186void Map::createEntities(std::list<std::shared_ptr<Entity>>& entities) const 152bool Map::moveTypeTakesMap(MoveType type)
187{ 153{
188 for (auto data : this->entities) 154 switch (type)
189 { 155 {
190 auto entity = EntityFactory::createNamedEntity(data.name); 156 case MoveType::Wall: return false;
191 entity->position = data.position; 157 case MoveType::Wrap: return false;
192 158 case MoveType::Warp: return true;
193 entities.push_back(entity); 159 case MoveType::ReverseWarp: return true;
194 } 160 }
195} 161}
196 162
197bool Map::operator==(const Map& other) const 163void Map::setMapdata(int* mapdata)
198{ 164{
199 return name == other.name; 165 free(this->mapdata);
166 this->mapdata = mapdata;
200} 167}
201 168
202bool Map::operator!=(const Map& other) const 169void Map::setTitle(std::string title)
203{ 170{
204 return name != other.name; 171 this->title = title;
205} 172}
206 173
207Map& Map::getNamedMap(const std::string name) 174void Map::setLeftMoveType(MoveType type)
208{ 175{
209 if (maps.count(name) == 0) 176 leftType = type;
210 {
211 maps[name] = Map {name};
212 }
213
214 return maps[name];
215} 177}
178
179void Map::setRightMoveType(MoveType type)
180{
181 rightType = type;
182}
183
184void Map::setUpMoveType(MoveType type)
185{
186 upType = type;
187}
188
189void Map::setDownMoveType(MoveType type)
190{
191 downType = type;
192}
193
194void Map::setLeftMapID(int id)
195{
196 leftMap = id;
197}
198
199void Map::setRightMapID(int id)
200{
201 rightMap = id;
202}
203
204void Map::setUpMapID(int id)
205{
206 upMap = id;
207}
208
209void Map::setDownMapID(int id)
210{
211 downMap = id;
212}
213
214void Map::addEntity(EntityData& data)
215{
216 entities.push_back(data);
217}
218
diff --git a/src/map.h b/src/map.h index 3b3d42c..1234dbb 100644 --- a/src/map.h +++ b/src/map.h
@@ -8,37 +8,63 @@ class Entity;
8 8
9class Map { 9class Map {
10 public: 10 public:
11 Map(); 11 Map(int id);
12 Map(std::string name); 12 Map() : Map(-1) {}
13 Map(const Map& map); 13 Map(const Map& map);
14 Map(Map&& map); 14 Map(Map&& map);
15 ~Map(); 15 ~Map();
16 Map& operator= (Map other); 16 Map& operator= (Map other);
17 friend void swap(Map& first, Map& second); 17 friend void swap(Map& first, Map& second);
18 18
19 static Map& getNamedMap(std::string name); 19 enum class MoveType {
20 Wall,
21 Wrap,
22 Warp,
23 ReverseWarp
24 };
25
26 struct EntityData {
27 std::string name;
28 std::pair<int, int> position;
29 };
30
31 static MoveType moveTypeForShort(std::string str);
32 static bool moveTypeTakesMap(MoveType type);
20 33
34 int getID() const;
21 const int* getMapdata() const; 35 const int* getMapdata() const;
22 std::string getTitle() const; 36 std::string getTitle() const;
23 const Map* getLeftMap() const; 37 MoveType getLeftMoveType() const;
24 const Map* getRightMap() const; 38 MoveType getRightMoveType() const;
25 void setLeftMap(const Map* m); 39 MoveType getUpMoveType() const;
26 void setRightMap(const Map* m); 40 MoveType getDownMoveType() const;
41 int getLeftMapID() const;
42 int getRightMapID() const;
43 int getUpMapID() const;
44 int getDownMapID() const;
45
27 void createEntities(std::list<std::shared_ptr<Entity>>& entities) const; 46 void createEntities(std::list<std::shared_ptr<Entity>>& entities) const;
28 bool operator==(const Map& other) const; 47 bool operator==(const Map& other) const;
29 bool operator!=(const Map& other) const; 48 bool operator!=(const Map& other) const;
30 private:
31 struct EntityData {
32 std::string name;
33 std::pair<double, double> position;
34 };
35 49
50 void setMapdata(int* mapdata);
51 void setTitle(std::string title);
52 void setLeftMoveType(MoveType type);
53 void setRightMoveType(MoveType type);
54 void setUpMoveType(MoveType type);
55 void setDownMoveType(MoveType type);
56 void setLeftMapID(int id);
57 void setRightMapID(int id);
58 void setUpMapID(int id);
59 void setDownMapID(int id);
60 void addEntity(EntityData& data);
61 private:
36 int* mapdata; 62 int* mapdata;
37 std::string title; 63 std::string title;
38 std::string name; 64 int id;
39 const Map* leftMap = nullptr;
40 const Map* rightMap = nullptr;
41 std::list<EntityData> entities; 65 std::list<EntityData> entities;
66 MoveType leftType, rightType, upType, downType;
67 int leftMap, rightMap, upMap, downMap;
42}; 68};
43 69
44#endif 70#endif
diff --git a/src/renderer.cpp b/src/renderer.cpp index d50901b..99d5389 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -5,9 +5,9 @@
5#include <cstdio> 5#include <cstdio>
6#include <cstring> 6#include <cstring>
7#include <cstdlib> 7#include <cstdlib>
8#include "game.h"
9#include <glm/glm.hpp> 8#include <glm/glm.hpp>
10#include <glm/gtc/matrix_transform.hpp> 9#include <glm/gtc/matrix_transform.hpp>
10#include "consts.h"
11 11
12// include stb_image 12// include stb_image
13#define STB_IMAGE_IMPLEMENTATION 13#define STB_IMAGE_IMPLEMENTATION