summaryrefslogtreecommitdiffhomepage
path: root/editor
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-03-09 20:14:38 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-03-09 20:21:00 +0100
commitabc0ca438938d9ccad9097a671556988b7625696 (patch)
tree514468365bfa1b83411fc673a3b84b4f87c8fab8 /editor
parent2b38bfa07bf20afc27646c5fdf43f0e3899bf914 (diff)
editor: add some wip character stuff
Diffstat (limited to 'editor')
-rw-r--r--editor/character.cpp83
-rw-r--r--editor/character.hpp30
2 files changed, 113 insertions, 0 deletions
diff --git a/editor/character.cpp b/editor/character.cpp
new file mode 100644
index 00000000..d1f648c6
--- /dev/null
+++ b/editor/character.cpp
@@ -0,0 +1,83 @@
+#include "character.hpp"
+#include "src/anim-atlas.hpp"
+#include "loader/loader.hpp"
+#include "src/world.hpp"
+#include "src/RTree.hpp"
+#include <cmath>
+
+namespace floormat {
+
+namespace {
+
+template <typename T>
+constexpr T sgn(T val) { return T(T(0) < val) - T(val < T(0)); }
+
+constexpr int tile_size_1 = iTILE_SIZE2.sum()/2,
+ framerate = 24, move_speed = tile_size_1 * 2/3;
+constexpr float frame_time = 1.f/framerate;
+constexpr auto inv_tile_size = 1 / TILE_SIZE2;
+
+} // namespace
+
+character_wip::character_wip() :
+ walk_anim{loader.anim_atlas("npc-walk", loader.ANIM_PATH)}
+{
+}
+
+character_wip::~character_wip() = default;
+
+int character_wip::allocate_frame_time(float dt)
+{
+ delta += dt;
+ auto ret = (int)(delta*framerate);
+ delta -= ret;
+ delta = std::fmax(0.f, delta);
+ return ret;
+}
+
+Vector2 character_wip::move_vec(int left_right, int top_bottom)
+{
+ constexpr auto c = move_speed * frame_time;
+ return c * Vector2(sgn(left_right), sgn(top_bottom)).normalized();
+}
+
+void character_wip::tick(world& w, float dt, int left_right, int top_bottom)
+{
+ if (!left_right && !top_bottom)
+ {
+ delta = 0;
+ return;
+ }
+
+ int nframes = allocate_frame_time(dt);
+ const auto vec = move_vec(left_right, top_bottom);
+
+ for (int i = 0; i < nframes; i++)
+ {
+ auto pos_ = pos;
+ Vector2 offset_ = offset;
+ offset_ += vec;
+ auto pos_1 = Vector2i(offset_ * inv_tile_size);
+ pos_ += pos_1;
+ offset_ = Vector2(std::fmod(offset_[0], TILE_SIZE2[0]), std::fmod(offset_[1], TILE_SIZE2[1]));
+ auto [c, t] = w[pos_];
+ const auto& r = c.rtree();
+ auto center = Vector2(pos_.local()) * TILE_SIZE2 + offset;
+ auto half = Vector2(bbox_size)*.5f;
+ auto min = center - half;
+ auto max = center + half;
+ bool is_blocked = false;
+ r->Search(min.data(), max.data(), [&](const std::uint64_t data, const auto&) {
+ auto cdata = std::bit_cast<collision_data>(data);
+ is_blocked |= (pass_mode)cdata.pass != pass_mode::pass;
+ return !is_blocked;
+ });
+ if (is_blocked)
+ break;
+ pos = pos_;
+ offset = offset_;
+ ++frame %= walk_anim->info().nframes;
+ }
+}
+
+} // namespace floormat
diff --git a/editor/character.hpp b/editor/character.hpp
new file mode 100644
index 00000000..b201be8f
--- /dev/null
+++ b/editor/character.hpp
@@ -0,0 +1,30 @@
+#pragma once
+#include "src/global-coords.hpp"
+#include "src/rotation.hpp"
+#include <memory>
+
+namespace floormat {
+
+struct anim_atlas;
+struct world;
+
+struct character_wip final
+{
+ character_wip();
+ ~character_wip();
+ void tick(world& w, float dt, int left_right, int top_bottom);
+
+ std::shared_ptr<anim_atlas> walk_anim;
+ global_coords pos;
+ std::size_t frame = 0;
+ float delta = 0;
+ Vector2 offset;
+ Vector2ub bbox_size;
+ rotation r = rotation::NE;
+
+private:
+ int allocate_frame_time(float dt);
+ static Vector2 move_vec(int left_right, int top_bottom);
+};
+
+} // namespace floormat