Move movement logic out from the gameplay scene.

Character now knows how to move by itself.
This commit is contained in:
King_DuckZ 2017-01-30 12:29:57 +00:00
parent 7a0d2c3267
commit 3907ef6d6d
9 changed files with 225 additions and 30 deletions

View file

@ -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

View file

@ -18,17 +18,23 @@
*/
#include "character.hpp"
#include "inputbag.hpp"
#include "gameactions.hpp"
#include <ciso646>
#include <cassert>
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<vec2f>(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

View file

@ -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<float> destination_rect (const vec2f& parWorldPos) const;
Rect<float> 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<vec2f> m_position;
Texture m_texture;
vec2f m_width_height;
cloonel::InputBag* m_input_bag;
float m_speed;
};
} //namespace curry

29
src/gameactions.hpp Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace curry {
enum Actions : int {
ActionLeft,
ActionUp,
ActionRight,
ActionDown
};
} //namespace curry

View file

@ -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 <SDL2/SDL.h>
#include <algorithm>
#include <vector>
@ -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<LocalData>(vec2us(32), parSDLMain))
m_local_data(std::make_unique<LocalData>(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<float>(
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<float>(
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<vec2f>(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();
}

25
src/moveable.cpp Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "moveable.hpp"
namespace curry {
Moveable::Moveable() = default;
Moveable::~Moveable() noexcept = default;
} //namespace curry

32
src/moveable.hpp Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace curry {
class Moveable {
public:
Moveable();
virtual ~Moveable() noexcept;
virtual void do_movement (float parDeltaT) = 0;
private:
};
} //namespace curry

42
src/worlditems.cpp Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "worlditems.hpp"
#include "moveable.hpp"
#include <algorithm>
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<bool>(not m_moveables.size());
}
} //namespace curry

42
src/worlditems.hpp Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "observersmanager.hpp"
namespace curry {
class Moveable;
class WorldItems {
//typedef cloonel::ObserversManager<Moveable*>::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<Moveable*> m_moveables;
};
} //namespace curry