Refactor moving logic out from Character into a new class.

This commit is contained in:
King_DuckZ 2017-07-31 09:56:49 +01:00
parent 84e7ca952e
commit 7783cb8e5e
5 changed files with 119 additions and 35 deletions

View file

@ -21,6 +21,7 @@ add_library(${PROJECT_NAME}
grid_raytrace.cpp grid_raytrace.cpp
drawable.cpp drawable.cpp
drawing_queue.cpp drawing_queue.cpp
world_moveable.cpp
) )
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)

View file

@ -32,28 +32,17 @@
namespace curry { namespace curry {
Character::Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) : Character::Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) :
WorldSizeNotifiable(parDeferredRegister), WorldMoveable(parDeferredRegister),
m_position(vec2f(0.0f), vec2f(0.0f), vec2f(0.0f)),
m_input_bag(parInputBag), m_input_bag(parInputBag),
m_world(parDeferredRegister.world()),
m_speed(1.0f) m_speed(1.0f)
{ {
assert(m_input_bag); assert(m_input_bag);
assert(m_world);
}
void Character::set_position (const vec2f& parPos) {
m_position = parPos;
}
const vec2f& Character::position() const {
return m_position.get();
} }
Rect<float> Character::destination_rect (const vec2f& parWorldPos) const { Rect<float> Character::destination_rect (const vec2f& parWorldPos) const {
return Rect<float>( return Rect<float>(
m_position.get() - parWorldPos, position() - parWorldPos,
m_position.get() - parWorldPos + width_height() position() - parWorldPos + width_height()
); );
} }
@ -64,10 +53,6 @@ namespace curry {
); );
} }
void Character::world_size_changed (const vec2us&, const vec2i& parPixelSize) {
m_position.change_minmax(m_position.get_min(), vector_cast<vec2f>(parPixelSize));
}
void Character::do_movement (float parDeltaT) { void Character::do_movement (float parDeltaT) {
const float speed = parDeltaT * m_speed; const float speed = parDeltaT * m_speed;
vec2f offset(0.0f); vec2f offset(0.0f);
@ -85,10 +70,12 @@ namespace curry {
if (position() == old_pos) if (position() == old_pos)
return; return;
const vec2us character_tile = pixel_to_world_tile(*m_world, position()); WorldGrid& world = this->world();
vec2us stop_at = pixel_to_world_tile(*m_world, old_pos);
auto is_walkable = [world=m_world,&stop_at](vec2us idx) { const vec2us character_tile = pixel_to_world_tile(world, position());
const bool walkable = world->tile_property(world->tile(idx)).walkable; vec2us stop_at = pixel_to_world_tile(world, old_pos);
auto is_walkable = [&world,&stop_at](vec2us idx) {
const bool walkable = world.tile_property(world.tile(idx)).walkable;
if (walkable) if (walkable)
stop_at = idx; stop_at = idx;
else else
@ -96,10 +83,10 @@ namespace curry {
return walkable; return walkable;
}; };
for_each_voxel_under_segment(old_pos, this->position(), width_height(), *m_world, is_walkable, false); for_each_voxel_under_segment(old_pos, this->position(), width_height(), world, is_walkable, false);
if (character_tile != stop_at) { if (character_tile != stop_at) {
vec2f blocked_pos = world_tile_to_pixel(*m_world, stop_at); vec2f blocked_pos = world_tile_to_pixel(world, stop_at);
vec2f new_pos = position(); vec2f new_pos = position();
if (character_tile.x() != stop_at.x()) if (character_tile.x() != stop_at.x())
new_pos.x() = blocked_pos.x(); new_pos.x() = blocked_pos.x();
@ -125,7 +112,6 @@ namespace curry {
} }
void Character::on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) { void Character::on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) {
if (m_position.get_min() != m_position.get_max()) this->update_moveable_size(parOldSz, parNewSz);
m_position.change_minmax(m_position.get_min(), m_position.get_max() + parOldSz - parNewSz);
} }
} //namespace curry } //namespace curry

View file

@ -21,9 +21,7 @@
#include "vector.hpp" #include "vector.hpp"
#include "rect.hpp" #include "rect.hpp"
#include "constrained_position.hpp" #include "world_moveable.hpp"
#include "worldsizenotifiable.hpp"
#include "moveable.hpp"
#include "drawable.hpp" #include "drawable.hpp"
namespace cloonel { namespace cloonel {
@ -34,16 +32,13 @@ namespace cloonel {
namespace curry { namespace curry {
class WorldGrid; class WorldGrid;
class Character : public Drawable, public WorldSizeNotifiable, public Moveable { class Character : public Drawable, public WorldMoveable {
public: public:
Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister); Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
virtual ~Character() noexcept = default; virtual ~Character() noexcept = default;
const vec2f& position() const;
void set_position (const vec2f& parPos);
Rect<float> destination_rect (const vec2f& parWorldPos) const; Rect<float> destination_rect (const vec2f& parWorldPos) const;
Rect<float> source_rect() const; Rect<float> source_rect() const;
virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize) override;
virtual void do_movement (float parDeltaT) override; virtual void do_movement (float parDeltaT) override;
void set_speed (float parSpeed); void set_speed (float parSpeed);
virtual void draw (DrawingQueue& parDQ, const WorldViewport& parViewport) override; virtual void draw (DrawingQueue& parDQ, const WorldViewport& parViewport) override;
@ -51,9 +46,7 @@ namespace curry {
private: private:
virtual void on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) override; virtual void on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) override;
ConstrainedPosition<vec2f> m_position;
cloonel::InputBag* m_input_bag; cloonel::InputBag* m_input_bag;
WorldGrid* m_world;
float m_speed; float m_speed;
}; };
} //namespace curry } //namespace curry

View file

@ -0,0 +1,57 @@
/*
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
This file is part of MyCurry.
MyCurry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyCurry is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
*/
#include "world_moveable.hpp"
#include <cassert>
namespace curry {
WorldMoveable::WorldMoveable (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) :
WorldSizeNotifiable(parDeferredRegister),
m_position(vec2f(0.0f), vec2f(0.0f), vec2f(0.0f)),
m_world(parDeferredRegister.world())
{
assert(m_world);
}
void WorldMoveable::world_size_changed (const vec2us&, const vec2i& parPixelSize) {
m_position.change_minmax(m_position.get_min(), vector_cast<vec2f>(parPixelSize));
}
void WorldMoveable::set_position (const vec2f& parPos) {
m_position = parPos;
}
const vec2f& WorldMoveable::position() const {
return m_position.get();
}
void WorldMoveable::update_moveable_size (const vec2f& parOldSz, const vec2f& parNewSz) {
if (m_position.get_min() != m_position.get_max())
m_position.change_minmax(m_position.get_min(), m_position.get_max() + parOldSz - parNewSz);
}
WorldGrid& WorldMoveable::world() {
assert(m_world);
return *m_world;
}
const WorldGrid& WorldMoveable::world() const {
assert(m_world);
return *m_world;
}
} //namespace curry

View file

@ -0,0 +1,47 @@
/*
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
This file is part of MyCurry.
MyCurry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyCurry is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "moveable.hpp"
#include "worldsizenotifiable.hpp"
#include "constrained_position.hpp"
namespace curry {
class WorldGrid;
class WorldMoveable : public Moveable, public WorldSizeNotifiable {
public:
explicit WorldMoveable (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
virtual ~WorldMoveable() = default;
virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize) override;
const vec2f& position() const;
void set_position (const vec2f& parPos);
WorldGrid& world();
const WorldGrid& world() const;
protected:
void update_moveable_size (const vec2f& parOldSz, const vec2f& parNewSz);
private:
ConstrainedPosition<vec2f> m_position;
WorldGrid* m_world;
};
} //namespace curry