From 3907ef6d6d94977430c97a19f6afb33ff0fbad10 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Mon, 30 Jan 2017 12:29:57 +0000 Subject: [PATCH] Move movement logic out from the gameplay scene. Character now knows how to move by itself. --- CMakeLists.txt | 2 ++ src/character.cpp | 29 +++++++++++++++++++++++++++-- src/character.hpp | 12 +++++++++--- src/gameactions.hpp | 29 +++++++++++++++++++++++++++++ src/ingamescene.cpp | 42 +++++++++++++++++------------------------- src/moveable.cpp | 25 +++++++++++++++++++++++++ src/moveable.hpp | 32 ++++++++++++++++++++++++++++++++ src/worlditems.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/worlditems.hpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 225 insertions(+), 30 deletions(-) create mode 100644 src/gameactions.hpp create mode 100644 src/moveable.cpp create mode 100644 src/moveable.hpp create mode 100644 src/worlditems.cpp create mode 100644 src/worlditems.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 97279de..ddae753 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,8 @@ add_executable(${PROJECT_NAME} src/character.cpp src/rect_to_sdl.cpp src/worldsizenotifiable.cpp + src/worlditems.cpp + src/moveable.cpp ) target_include_directories(${PROJECT_NAME} SYSTEM diff --git a/src/character.cpp b/src/character.cpp index 630bea0..aebdec6 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -18,17 +18,23 @@ */ #include "character.hpp" +#include "inputbag.hpp" +#include "gameactions.hpp" #include +#include namespace curry { namespace { } //unnamed namespace - Character::Character (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) : + Character::Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) : WorldSizeNotifiable(parDeferredRegister), m_position(vec2f(0.0f), vec2f(0.0f), vec2f(0.0f)), - m_width_height(0.0f) + m_width_height(0.0f), + m_input_bag(parInputBag), + m_speed(1.0f) { + assert(m_input_bag); } void Character::load (const char* parTexturePath, cloonel::SDLMain& parSDLMain) { @@ -77,4 +83,23 @@ namespace curry { void Character::world_size_changed (const vec2us&, const vec2i& parPixelSize) { m_position.change_minmax(m_position.get_min(), vector_cast(parPixelSize)); } + + void Character::do_movement (float parDeltaT) { + const float speed = parDeltaT * m_speed; + vec2f offset(0.0f); + if (cloonel::IsPressed(*m_input_bag, ActionRight)) + offset.x() += speed; + if (cloonel::IsPressed(*m_input_bag, ActionLeft)) + offset.x() -= speed; + if (cloonel::IsPressed(*m_input_bag, ActionUp)) + offset.y() -= speed; + if (cloonel::IsPressed(*m_input_bag, ActionDown)) + offset.y() += speed; + this->set_position(this->position() + offset); + } + + void Character::set_speed (float parSpeed) { + assert(parSpeed > 0.0f); + m_speed = parSpeed; + } } //namespace curry diff --git a/src/character.hpp b/src/character.hpp index 9db2503..51fd4a8 100644 --- a/src/character.hpp +++ b/src/character.hpp @@ -24,15 +24,17 @@ #include "rect.hpp" #include "constrained_position.hpp" #include "worldsizenotifiable.hpp" +#include "moveable.hpp" namespace cloonel { class SDLMain; + class InputBag; } //namespace cloonel namespace curry { - class Character : public WorldSizeNotifiable { + class Character : public WorldSizeNotifiable, public Moveable { public: - explicit Character (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister); + Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister); virtual ~Character() noexcept = default; void load (const char* parTexturePath, cloonel::SDLMain& parSDLMain); @@ -43,11 +45,15 @@ namespace curry { Texture& texture(); Rect destination_rect (const vec2f& parWorldPos) const; Rect source_rect() const; - virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize); + virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize) override; + virtual void do_movement (float parDeltaT) override; + void set_speed (float parSpeed); private: ConstrainedPosition m_position; Texture m_texture; vec2f m_width_height; + cloonel::InputBag* m_input_bag; + float m_speed; }; } //namespace curry diff --git a/src/gameactions.hpp b/src/gameactions.hpp new file mode 100644 index 0000000..6c899c0 --- /dev/null +++ b/src/gameactions.hpp @@ -0,0 +1,29 @@ +/* + Copyright 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 . +*/ + +#pragma once + +namespace curry { + enum Actions : int { + ActionLeft, + ActionUp, + ActionRight, + ActionDown + }; +} //namespace curry diff --git a/src/ingamescene.cpp b/src/ingamescene.cpp index f7bb66b..d2a15cd 100644 --- a/src/ingamescene.cpp +++ b/src/ingamescene.cpp @@ -1,5 +1,5 @@ /* - Copyright 2016 Michele "King_DuckZ" Santullo + Copyright 2016, 2017 Michele "King_DuckZ" Santullo This file is part of MyCurry. @@ -29,6 +29,8 @@ #include "rect.hpp" #include "character.hpp" #include "csvloader.hpp" +#include "worlditems.hpp" +#include "gameactions.hpp" #include #include #include @@ -39,20 +41,14 @@ namespace curry { namespace { - enum Actions : int { - ActionLeft, - ActionUp, - ActionRight, - ActionDown - }; } //unnamed namespace struct IngameScene::LocalData { - LocalData (const vec2us& parTileSize, cloonel::SDLMain* parSDLMain) : + LocalData (const vec2us& parTileSize, cloonel::SDLMain* parSDLMain, cloonel::InputBag* parInputBag) : world(parTileSize), viewport(&world, vec2f(parSDLMain->WidthHeight()), WorldSizeNotifiable::DeferredRegister(&world, &viewport)), player(parTileSize), - character(WorldSizeNotifiable::DeferredRegister(&world, &character)) + character(parInputBag, WorldSizeNotifiable::DeferredRegister(&world, &character)) { } @@ -61,11 +57,12 @@ namespace curry { Texture worldtiles; MovingObject player; Character character; + WorldItems moveable_items; }; IngameScene::IngameScene (cloonel::SDLMain* parSDLMain) : GameSceneBase(parSDLMain), - m_local_data(std::make_unique(vec2us(32), parSDLMain)) + m_local_data(std::make_unique(vec2us(32), parSDLMain, &this->input_bag())) { using cloonel::Key; using cloonel::InputDevice_Keyboard; @@ -94,27 +91,21 @@ namespace curry { m_local_data->viewport.allow_overscan(false); m_local_data->character.load(RESOURCES_PATH "LPC_Sara_Preview.png", *this->sdl_main()); + const float speed_per_sec = + static_cast( + std::max(m_local_data->world.tile_size().x(), m_local_data->world.tile_size().y()) + ) * 4.5f; + m_local_data->character.set_speed(speed_per_sec); + + assert(m_local_data->moveable_items.no_items_registered()); + m_local_data->moveable_items.register_observer(&m_local_data->character); } void IngameScene::on_update (float parDeltaT) { const auto& world = m_local_data->world; - const float speed_per_sec = - static_cast( - std::max(world.tile_size().x(), world.tile_size().y()) - ) * 4.5f; auto& viewport = m_local_data->viewport; - const float speed = parDeltaT * speed_per_sec; - vec2f offset(0.0f); - if (cloonel::IsPressed(input_bag(), ActionRight)) - offset.x() += speed; - if (cloonel::IsPressed(input_bag(), ActionLeft)) - offset.x() -= speed; - if (cloonel::IsPressed(input_bag(), ActionUp)) - offset.y() -= speed; - if (cloonel::IsPressed(input_bag(), ActionDown)) - offset.y() += speed; - m_local_data->character.set_position(m_local_data->character.position() + offset); + m_local_data->moveable_items.move_items(parDeltaT); viewport.set_position(m_local_data->character.position() - (viewport.size() - m_local_data->character.width_height()) / 2.0f); const auto tilesize(static_cast(world.tile_size())); @@ -136,6 +127,7 @@ namespace curry { } void IngameScene::on_destroy() noexcept { + m_local_data->moveable_items.unregister_all(); m_local_data->worldtiles.unload(); m_local_data->character.unload(); } diff --git a/src/moveable.cpp b/src/moveable.cpp new file mode 100644 index 0000000..94420cf --- /dev/null +++ b/src/moveable.cpp @@ -0,0 +1,25 @@ +/* + Copyright 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 . +*/ + +#include "moveable.hpp" + +namespace curry { + Moveable::Moveable() = default; + Moveable::~Moveable() noexcept = default; +} //namespace curry diff --git a/src/moveable.hpp b/src/moveable.hpp new file mode 100644 index 0000000..73dd9bc --- /dev/null +++ b/src/moveable.hpp @@ -0,0 +1,32 @@ +/* + Copyright 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 . +*/ + +#pragma once + +namespace curry { + class Moveable { + public: + Moveable(); + virtual ~Moveable() noexcept; + + virtual void do_movement (float parDeltaT) = 0; + + private: + }; +} //namespace curry diff --git a/src/worlditems.cpp b/src/worlditems.cpp new file mode 100644 index 0000000..a4801dd --- /dev/null +++ b/src/worlditems.cpp @@ -0,0 +1,42 @@ +/* + Copyright 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 . +*/ + +#include "worlditems.hpp" +#include "moveable.hpp" +#include + +namespace curry { + WorldItems::WorldItems() = default; + + void WorldItems::register_observer (Moveable* parMoveable) { + m_moveables.Add(parMoveable); + } + + void WorldItems::unregister_all() noexcept { + m_moveables.RemoveAll(); + } + + void WorldItems::move_items (float parDeltaT) { + std::for_each(m_moveables.begin(), m_moveables.end(), [=](Moveable* m) {m->do_movement(parDeltaT);}); + } + + bool WorldItems::no_items_registered() const { + return static_cast(not m_moveables.size()); + } +} //namespace curry diff --git a/src/worlditems.hpp b/src/worlditems.hpp new file mode 100644 index 0000000..1dcda58 --- /dev/null +++ b/src/worlditems.hpp @@ -0,0 +1,42 @@ +/* + Copyright 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 . +*/ + +#pragma once + +#include "observersmanager.hpp" + +namespace curry { + class Moveable; + + class WorldItems { + //typedef cloonel::ObserversManager::TicketType MoveableTicketType; + + public: + WorldItems(); + ~WorldItems() noexcept = default; + + void register_observer (Moveable* parMoveable); + void unregister_all() noexcept; + void move_items (float parDeltaT); + bool no_items_registered() const; + + private: + cloonel::ObserversManager m_moveables; + }; +} //namespace curry