Add transitions for entity movement
This commit is contained in:
parent
0c3dbabb92
commit
d41e2dae45
6 changed files with 144 additions and 50 deletions
|
@ -45,6 +45,36 @@ MapContext::MapContext(ImageLoader *imageLoader0, const std::shared_ptr<const Mo
|
||||||
entities[entity->getName()] = imageLoader->get("entity/" + entity->getName());
|
entities[entity->getName()] = imageLoader->get("entity/" + entity->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapContext::advance(InputHandler *inputHandler, uint32_t ticks) {
|
||||||
|
uint64_t totalTicksOld = totalTicks;
|
||||||
|
totalTicks += ticks;
|
||||||
|
|
||||||
|
unsigned advance = totalTicks - totalTicksOld;
|
||||||
|
|
||||||
|
while (advance) {
|
||||||
|
advance = map->getPlayerEntity().advance(advance);
|
||||||
|
|
||||||
|
if (map->getPlayerEntity().hasTransition())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (inputHandler->isKeyPressed(SDL_SCANCODE_UP)) {
|
||||||
|
map->getPlayerEntity().move(Model::NORTH, 250);
|
||||||
|
}
|
||||||
|
else if (inputHandler->isKeyPressed(SDL_SCANCODE_RIGHT)) {
|
||||||
|
map->getPlayerEntity().move(Model::EAST, 250);
|
||||||
|
}
|
||||||
|
else if (inputHandler->isKeyPressed(SDL_SCANCODE_DOWN)) {
|
||||||
|
map->getPlayerEntity().move(Model::SOUTH, 250);
|
||||||
|
}
|
||||||
|
else if (inputHandler->isKeyPressed(SDL_SCANCODE_LEFT)) {
|
||||||
|
map->getPlayerEntity().move(Model::WEST, 250);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,25 +53,7 @@ private:
|
||||||
public:
|
public:
|
||||||
MapContext(ImageLoader *imageLoader0, const std::shared_ptr<const Model::Map> &map0);
|
MapContext(ImageLoader *imageLoader0, const std::shared_ptr<const Model::Map> &map0);
|
||||||
|
|
||||||
void advance(InputHandler *inputHandler, uint32_t ticks) {
|
void advance(InputHandler *inputHandler, unsigned 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) {
|
std::shared_ptr<View::MapView> initView(const std::shared_ptr<View::Window> &window) {
|
||||||
return std::make_shared<View::MapView>(window, map, tiles, entities);
|
return std::make_shared<View::MapView>(window, map, tiles, entities);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
|
Copyright (c) 20amount4, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
amount. Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "Direction.hpp"
|
#include "Direction.hpp"
|
||||||
|
#include "Position.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -42,50 +43,91 @@ class Entity {
|
||||||
private:
|
private:
|
||||||
const std::string name;
|
const std::string name;
|
||||||
|
|
||||||
float x, y;
|
Position pos;
|
||||||
|
Direction direction;
|
||||||
|
|
||||||
Direction dir;
|
unsigned transition = 0;
|
||||||
|
unsigned step = 0;
|
||||||
|
|
||||||
|
Position translate(Direction dir, float amount) const {
|
||||||
|
Position p = pos;
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case NORTH:
|
||||||
|
p.y -= amount;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EAST:
|
||||||
|
p.x += amount;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOUTH:
|
||||||
|
p.y += amount;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WEST:
|
||||||
|
p.x -= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Entity(const std::string &name0)
|
Entity(const std::string &name0)
|
||||||
: name(name0), dir(NORTH) {
|
: name(name0), direction(NORTH) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & getName() const {
|
const std::string & getName() const {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<float, float> getPosition() const {
|
Position getPosition() const {
|
||||||
return std::pair<float, float>(x, y);
|
if (transition)
|
||||||
|
return translate(direction, (float)step / transition);
|
||||||
|
else
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction getDirection() const {
|
Direction getDirection() const {
|
||||||
return dir;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveTo(float newX, float newY) {
|
void moveTo(float newX, float newY) {
|
||||||
x = newX;
|
pos.x = newX;
|
||||||
y = newY;
|
pos.y = newY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void move(Direction direction, float amount = 1) {
|
void move(Direction dir, unsigned steps = 0) {
|
||||||
dir = direction;
|
if (transition)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (direction) {
|
direction = dir;
|
||||||
case NORTH:
|
|
||||||
y -= amount;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EAST:
|
if (steps)
|
||||||
x += amount;
|
transition = steps;
|
||||||
break;
|
else
|
||||||
|
pos = translate(direction, 1);
|
||||||
|
}
|
||||||
|
|
||||||
case SOUTH:
|
bool hasTransition() const {
|
||||||
y += amount;
|
return transition;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case WEST:
|
unsigned advance(unsigned ticks) {
|
||||||
x -= amount;
|
if (!transition)
|
||||||
|
return ticks;
|
||||||
|
|
||||||
|
step += ticks;
|
||||||
|
|
||||||
|
if (step >= transition) {
|
||||||
|
ticks = step - transition;
|
||||||
|
transition = step = 0;
|
||||||
|
pos = translate(direction, 1);
|
||||||
|
|
||||||
|
return ticks;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
40
src/model/Position.hpp
Normal file
40
src/model/Position.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 20amount4, 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:
|
||||||
|
|
||||||
|
amount. 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
|
||||||
|
|
||||||
|
|
||||||
|
namespace RPGEdit {
|
||||||
|
|
||||||
|
namespace Model {
|
||||||
|
|
||||||
|
struct Position {
|
||||||
|
float x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -91,8 +91,8 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[])
|
||||||
if (!SDL_TICKS_PASSED(SDL_GetTicks(), lastFrameTicks + MIN_FRAME_DELAY))
|
if (!SDL_TICKS_PASSED(SDL_GetTicks(), lastFrameTicks + MIN_FRAME_DELAY))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::pair<float, float> pos = map->getPlayerEntity().getPosition();
|
Model::Position pos = map->getPlayerEntity().getPosition();
|
||||||
mapView->render(pos.first, pos.second);
|
mapView->render(pos.x, pos.y);
|
||||||
|
|
||||||
lastFrameTicks = ticks;
|
lastFrameTicks = ticks;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ void MapView::render(float centerX, float centerY) {
|
||||||
int minX = std::floor(centerX - tilesW/2 - 0.5f), maxX = std::ceil(centerX + tilesW/2 + 0.5f);
|
int minX = std::floor(centerX - tilesW/2 - 0.5f), maxX = std::ceil(centerX + tilesW/2 + 0.5f);
|
||||||
int minY = std::floor(centerY - tilesH/2 - 0.5f), maxY = std::ceil(centerY + tilesH/2 + 0.5f);
|
int minY = std::floor(centerY - tilesH/2 - 0.5f), maxY = std::ceil(centerY + tilesH/2 + 0.5f);
|
||||||
|
|
||||||
int baseX = viewport.first/2 - (centerX + 0.5f)*tilePixels, baseY = viewport.second/2 - (centerY + 0.5f)*tilePixels;
|
int baseX = viewport.first/2 - int(centerX * tilePixels) - tilePixels/2, baseY = viewport.second/2 - int(centerY * tilePixels) - tilePixels/2;
|
||||||
|
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
for (int y = minY; y <= maxY; y++) {
|
for (int y = minY; y <= maxY; y++) {
|
||||||
|
@ -120,7 +120,7 @@ void MapView::render(float centerX, float centerY) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::shared_ptr<Model::Entity> &entity : map->getEntities()) {
|
for (const std::shared_ptr<Model::Entity> &entity : map->getEntities()) {
|
||||||
std::pair<float, float> pos = entity->getPosition();
|
Model::Position pos = entity->getPosition();
|
||||||
Model::Direction dir = entity->getDirection();
|
Model::Direction dir = entity->getDirection();
|
||||||
|
|
||||||
SDL_Rect src = {
|
SDL_Rect src = {
|
||||||
|
@ -131,8 +131,8 @@ void MapView::render(float centerX, float centerY) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SDL_Rect dst = {
|
SDL_Rect dst = {
|
||||||
.x = baseX + int(pos.first*tilePixels),
|
.x = baseX + int(pos.x * tilePixels),
|
||||||
.y = baseY + int(pos.second*tilePixels),
|
.y = baseY + int(pos.y * tilePixels),
|
||||||
.w = tilePixels,
|
.w = tilePixels,
|
||||||
.h = tilePixels,
|
.h = tilePixels,
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue