summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-09-25 18:39:03 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-09-25 18:39:03 +0200
commiteb40e3de7226d0005ce0a41c67c9355e675a489b (patch)
tree2ca2b4c14fcfa8c94370dfe0d192f82e41943b92
parentefa8640aabb3b4df31531ecd41ed1073dda63ed2 (diff)
downloadrpgedit-eb40e3de7226d0005ce0a41c67c9355e675a489b.tar
rpgedit-eb40e3de7226d0005ce0a41c67c9355e675a489b.zip
Add collision layer to maps and prevent movement into blocked areas
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/control/MapContext.cpp8
-rw-r--r--src/model/Entity.cpp68
-rw-r--r--src/model/Entity.hpp26
-rw-r--r--src/model/Map.cpp9
-rw-r--r--src/model/Map.hpp24
6 files changed, 107 insertions, 29 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54836d0..b2d55ac 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,6 +5,7 @@ add_executable(rpgedit
rpgedit.cpp
control/MapContext.cpp
control/RPGEdit.cpp
+ model/Entity.cpp
model/Map.cpp
view/MapView.cpp
view/SpriteCache.cpp
diff --git a/src/control/MapContext.cpp b/src/control/MapContext.cpp
index 1904db4..acad969 100644
--- a/src/control/MapContext.cpp
+++ b/src/control/MapContext.cpp
@@ -37,7 +37,7 @@ MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const s
map.getEntities().emplace_back("square");
playerEntity = &map.getEntities().back();
- playerEntity->moveTo(Model::Position{8, 8});
+ playerEntity->moveTo(&map, Model::Position{8, 8});
view->updateEntities(map.getEntities());
@@ -50,14 +50,12 @@ MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const s
}
void MapContext::movePlayer(Model::Direction dir, uint64_t time) {
- if (playerEntity->hasTransition())
+ if (!playerEntity->move(&map, dir, time, time+250))
return;
- playerEntity->move(dir, time, time+250);
-
eventBus->enqueue(
[=] {
- playerEntity->finishTransition();
+ playerEntity->finishTransition(&map);
movePlayerContinue(time+250);
},
time+250
diff --git a/src/model/Entity.cpp b/src/model/Entity.cpp
new file mode 100644
index 0000000..71447e6
--- /dev/null
+++ b/src/model/Entity.cpp
@@ -0,0 +1,68 @@
+/*
+ Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include "Entity.hpp"
+#include "Map.hpp"
+
+
+namespace RPGEdit {
+
+namespace Model {
+
+bool Entity::move(Map *map, Direction dir, uint64_t start, uint64_t end) {
+ if (hasTransition())
+ return false;
+
+ direction = dir;
+
+ Position newPos = translate(dir, 1);
+ if (map->getCollisionAt(newPos.x, newPos.y) == Map::BLOCKED)
+ return false;
+
+ map->setCollisionAt(newPos.x, newPos.y, Map::BLOCKED);
+
+ transitionStart = start;
+ transitionEnd = end;
+
+ return true;
+}
+
+void Entity::moveTo(Map *map, Position newPos) {
+ map->setCollisionAt(pos.x, pos.y, Map::EMPTY);
+ map->setCollisionAt(newPos.x, newPos.y, Map::BLOCKED);
+
+ pos = newPos;
+ transitionStart = transitionEnd = 0;
+}
+
+void Entity::finishTransition(Map *map) {
+ if (hasTransition())
+ moveTo(map, translate(direction, 1));
+}
+
+}
+
+}
diff --git a/src/model/Entity.hpp b/src/model/Entity.hpp
index 1ff444a..170f23a 100644
--- a/src/model/Entity.hpp
+++ b/src/model/Entity.hpp
@@ -39,6 +39,8 @@ namespace RPGEdit {
namespace Model {
+class Map;
+
class Entity {
private:
const std::string name;
@@ -97,29 +99,13 @@ public:
return direction;
}
- void moveTo(Position newPos) {
- pos = newPos;
- transitionStart = transitionEnd = 0;
- }
-
- void move(Direction dir, uint64_t start, uint64_t end) {
- if (hasTransition())
- return;
-
- direction = dir;
-
- transitionStart = start;
- transitionEnd = end;
- }
-
- void finishTransition() {
- if (hasTransition())
- moveTo(translate(direction, 1));
- }
-
bool hasTransition() const {
return transitionEnd;
}
+
+ void moveTo(Map *map, Position newPos);
+ bool move(Map *map, Direction dir, uint64_t start, uint64_t end);
+ void finishTransition(Map *map);
};
}
diff --git a/src/model/Map.cpp b/src/model/Map.cpp
index 21fbe00..faead6d 100644
--- a/src/model/Map.cpp
+++ b/src/model/Map.cpp
@@ -39,10 +39,13 @@ std::unique_ptr<Map> Map::load(__attribute__((unused)) const std::string &name)
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
- if (4 <= i && i < 12 && 4 <= j && j < 12)
+ if (4 <= i && i < 12 && 4 <= j && j < 12) {
map->setTileAt(0, i, j, 1);
- else
+ map->setCollisionAt(i, j, EMPTY);
+ }
+ else {
map->setTileAt(0, i, j, 0);
+ }
if (4 <= i && i < 12 && j == 8)
map->setTileAt(1, i, j, 2);
@@ -52,7 +55,7 @@ std::unique_ptr<Map> Map::load(__attribute__((unused)) const std::string &name)
}
map->entities.emplace_back("square");
- map->entities.back().moveTo(Model::Position{6, 6});
+ map->entities.back().moveTo(map.get(), Model::Position{6, 6});
return map;
}
diff --git a/src/model/Map.hpp b/src/model/Map.hpp
index 421b487..abbf2f1 100644
--- a/src/model/Map.hpp
+++ b/src/model/Map.hpp
@@ -40,16 +40,23 @@ namespace RPGEdit {
namespace Model {
class Map {
+public:
+ enum CollisionType {
+ BLOCKED = 0,
+ EMPTY,
+ };
+
private:
std::vector<std::string> tileset;
size_t width, height;
+ std::vector<CollisionType> collision;
std::vector<std::vector<uint32_t>> tiles;
std::deque<Entity> entities;
Map(size_t width0, size_t height0, size_t layers)
- : width(width0), height(height0) {
+ : width(width0), height(height0), collision(width*height) {
for (size_t i = 0; i < layers; i++)
tiles.emplace_back(width*height);
}
@@ -83,6 +90,21 @@ public:
return tiles.size();
}
+ void setCollisionAt(size_t x, size_t y, CollisionType value) {
+ if (x >= width || y >= height)
+ throw std::range_error("Map::setTileAt: bad coordinates");
+
+ collision[y*width + x] = value;
+ }
+
+ CollisionType getCollisionAt(ssize_t x, ssize_t y) const {
+ if (x < 0 || (size_t)x >= width || y < 0 || (size_t)y >= height)
+ return BLOCKED;
+
+ return collision[y*width + x];
+ }
+
+
void setTileAt(size_t layer, size_t x, size_t y, uint32_t value) {
if (layer >= tiles.size() || x >= width || y >= height)
throw std::range_error("Map::setTileAt: bad coordinates");