summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-09-23 00:13:05 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-09-23 00:13:05 +0200
commit11e77a9d65972c8e59aefd72419dfcf9036e9f6a (patch)
tree03288809e9a592849e881d6f3baae2eb41bee5cb
parentc9b41bc1022c75ac6da84f4fa503dd8231a96cf2 (diff)
downloadrpgedit-11e77a9d65972c8e59aefd72419dfcf9036e9f6a.tar
rpgedit-11e77a9d65972c8e59aefd72419dfcf9036e9f6a.zip
Allow player movement
-rw-r--r--src/control/InputHandler.hpp73
-rw-r--r--src/control/MapContext.hpp23
-rw-r--r--src/model/Direction.hpp8
-rw-r--r--src/model/Entity.hpp23
-rw-r--r--src/model/Map.cpp6
-rw-r--r--src/model/Map.hpp5
-rw-r--r--src/rpgedit.cpp33
-rw-r--r--src/view/MapView.cpp2
8 files changed, 165 insertions, 8 deletions
diff --git a/src/control/InputHandler.hpp b/src/control/InputHandler.hpp
new file mode 100644
index 0000000..eba94d1
--- /dev/null
+++ b/src/control/InputHandler.hpp
@@ -0,0 +1,73 @@
+/*
+ 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.
+*/
+
+
+#pragma once
+
+#include <SDL.h>
+
+#include <cstdint>
+#include <unordered_set>
+
+
+namespace RPGEdit {
+
+namespace Control {
+
+class InputHandler {
+private:
+ std::unordered_set<uint16_t> pressedKeys;
+ std::unordered_set<uint16_t> unhandledKeys;
+
+public:
+ void keyPressed(SDL_Scancode key) {
+ pressedKeys.insert(key);
+ unhandledKeys.insert(key);
+ }
+
+ void keyReleased(SDL_Scancode key) {
+ pressedKeys.erase(key);
+ }
+
+ void keyHandled(SDL_Scancode key) {
+ unhandledKeys.erase(key);
+ }
+
+ void resetHandled() {
+ unhandledKeys.clear();
+ }
+
+ bool isKeyPressed(SDL_Scancode key) {
+ return pressedKeys.count(key);
+ }
+
+ bool isKeyUnhandled(SDL_Scancode key) {
+ return unhandledKeys.count(key);
+ }
+};
+
+}
+
+}
diff --git a/src/control/MapContext.hpp b/src/control/MapContext.hpp
index a98d818..4cbf38a 100644
--- a/src/control/MapContext.hpp
+++ b/src/control/MapContext.hpp
@@ -27,6 +27,7 @@
#pragma once
#include "ImageLoader.hpp"
+#include "InputHandler.hpp"
#include "../model/Map.hpp"
#include "../view/MapView.hpp"
@@ -47,9 +48,31 @@ private:
std::vector<SDL_Surface *> tiles;
std::map<std::string, SDL_Surface *> entities;
+ uint64_t totalTicks = 0;
+
public:
MapContext(ImageLoader *imageLoader0, const std::shared_ptr<const Model::Map> &map0);
+ void advance(InputHandler *inputHandler, uint32_t ticks) {
+ uint64_t totalTicksOld = totalTicks;
+ totalTicks += ticks;
+
+ uint64_t advanced = totalTicks/100 - totalTicksOld/100;
+
+ if (inputHandler->isKeyPressed(SDL_SCANCODE_UP)) {
+ map->getPlayerEntity().move(Model::NORTH, advanced);
+ }
+ else if (inputHandler->isKeyPressed(SDL_SCANCODE_RIGHT)) {
+ map->getPlayerEntity().move(Model::EAST, advanced);
+ }
+ else if (inputHandler->isKeyPressed(SDL_SCANCODE_DOWN)) {
+ map->getPlayerEntity().move(Model::SOUTH, advanced);
+ }
+ else if (inputHandler->isKeyPressed(SDL_SCANCODE_LEFT)) {
+ map->getPlayerEntity().move(Model::WEST, advanced);
+ }
+ }
+
std::shared_ptr<View::MapView> initView(const std::shared_ptr<View::Window> &window) {
return std::make_shared<View::MapView>(window, map, tiles, entities);
}
diff --git a/src/model/Direction.hpp b/src/model/Direction.hpp
index c1cb269..db288f6 100644
--- a/src/model/Direction.hpp
+++ b/src/model/Direction.hpp
@@ -27,9 +27,17 @@
#pragma once
+namespace RPGEdit {
+
+namespace Model {
+
enum Direction {
NORTH,
EAST,
SOUTH,
WEST,
};
+
+}
+
+}
diff --git a/src/model/Entity.hpp b/src/model/Entity.hpp
index 518ce5f..a61ae21 100644
--- a/src/model/Entity.hpp
+++ b/src/model/Entity.hpp
@@ -63,10 +63,31 @@ public:
return dir;
}
- void move(float newX, float newY) {
+ void moveTo(float newX, float newY) {
x = newX;
y = newY;
}
+
+ void move(Direction direction, float amount = 1) {
+ dir = direction;
+
+ switch (direction) {
+ case NORTH:
+ y -= amount;
+ break;
+
+ case EAST:
+ x += amount;
+ break;
+
+ case SOUTH:
+ y += amount;
+ break;
+
+ case WEST:
+ x -= amount;
+ }
+ }
};
}
diff --git a/src/model/Map.cpp b/src/model/Map.cpp
index 9cbe880..48f5669 100644
--- a/src/model/Map.cpp
+++ b/src/model/Map.cpp
@@ -45,10 +45,10 @@ std::shared_ptr<Map> Map::load(__attribute__((unused)) const std::string &name)
}
}
- std::shared_ptr<Entity> square(new Entity("square"));
- square->move(6, 6);
+ map->playerEntity.reset(new Entity("square"));
+ map->playerEntity->moveTo(6, 6);
- map->entities.push_back(square);
+ map->entities.push_back(map->playerEntity);
return map;
}
diff --git a/src/model/Map.hpp b/src/model/Map.hpp
index e01d9c4..5d6ba01 100644
--- a/src/model/Map.hpp
+++ b/src/model/Map.hpp
@@ -46,6 +46,7 @@ private:
size_t width, height;
std::unique_ptr<uint32_t[]> tiles;
+ std::shared_ptr<Entity> playerEntity;
mutable std::deque<std::shared_ptr<Entity>> entities;
@@ -66,6 +67,10 @@ public:
return entities;
}
+ Entity & getPlayerEntity() const {
+ return *playerEntity;
+ }
+
size_t getWidth() const {
return width;
}
diff --git a/src/rpgedit.cpp b/src/rpgedit.cpp
index 48425e5..6057339 100644
--- a/src/rpgedit.cpp
+++ b/src/rpgedit.cpp
@@ -24,9 +24,9 @@
*/
+#include "control/InputHandler.hpp"
#include "control/MapContext.hpp"
#include "view/MapView.hpp"
-#include "model/Entity.hpp"
#include <unistd.h>
@@ -34,6 +34,9 @@
#include <SDL_main.h>
+#define MIN_FRAME_DELAY 10
+
+
extern "C"
int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) {
using namespace RPGEdit;
@@ -41,6 +44,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
SDL_Init(SDL_INIT_VIDEO);
{
+ Control::InputHandler inputHandler;
+
Control::ImageLoader tileLoader;
std::shared_ptr<Model::Map> map = Model::Map::load("test");
@@ -50,11 +55,28 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
std::shared_ptr<View::MapView> mapView = ctx->initView(window);
bool running = true;
+ uint32_t ticks = SDL_GetTicks();
while (true) {
SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if (event.type == SDL_QUIT) {
+ while (running) {
+ int timeout = ticks + MIN_FRAME_DELAY - SDL_GetTicks();
+ if (timeout < 0)
+ timeout = 0;
+
+ if (!SDL_WaitEventTimeout(&event, timeout))
+ break;
+
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ inputHandler.keyPressed(event.key.keysym.scancode);
+ break;
+
+ case SDL_KEYUP:
+ inputHandler.keyReleased(event.key.keysym.scancode);
+ break;
+
+ case SDL_QUIT:
running = false;
break;
}
@@ -63,6 +85,11 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
if (!running)
break;
+ uint32_t newTicks = SDL_GetTicks();
+ ctx->advance(&inputHandler, newTicks - ticks);
+
+ ticks = newTicks;
+
mapView->render(8, 8);
}
}
diff --git a/src/view/MapView.cpp b/src/view/MapView.cpp
index 788cee9..33414ce 100644
--- a/src/view/MapView.cpp
+++ b/src/view/MapView.cpp
@@ -121,7 +121,7 @@ void MapView::render(float centerX, float centerY) {
for (const std::shared_ptr<Model::Entity> &entity : map->getEntities()) {
std::pair<float, float> pos = entity->getPosition();
- Direction dir = entity->getDirection();
+ Model::Direction dir = entity->getDirection();
SDL_Rect src = {
.x = 16*dir,