diff --git a/demo/demo/grid.cpp b/demo/demo/grid.cpp index 16cec01e9a5032b3fa3f37d2dd7a4907a948edad..d3e659fdf07b7cf8d70e487237cf17d34550132e 100644 --- a/demo/demo/grid.cpp +++ b/demo/demo/grid.cpp @@ -74,7 +74,7 @@ namespace demo { } } - static void build_test_env(DemoGrid* area) { + static fggl::entity::EntityID build_test_env(DemoGrid* area) { area->clear(); build_room(area, {5, 5}, {4,4}); build_room(area, {11, 5}, {1,1}); @@ -85,17 +85,63 @@ namespace demo { build_room(area, {25, 5}, {3,3}); // player + fggl::entity::EntityID player = fggl::entity::INVALID; auto& manager = area->entities(); { - auto player = manager.create(); + player = manager.create(); auto& cellPos = manager.add<CellPos>(player); cellPos.pos = {5,5}; cellPos.direction = 1; } + return player; } + struct Action { + const char* name; + std::function<void(void)> callback; + }; + GridScene::GridScene(fggl::App &app) : GameBase(app), m_tiles(), m_animator(15.0F), m_grid(nullptr) { m_animator.add([this](){this->tickPlayer();}); + + std::array<Action, 4> actions{{ + {"<", [=]() { this->rotate(true); }}, + {">", [=]() { this->rotate(false); }}, + {"^", [=]() { this->forward(); }}, + {"Z", [=]() { } } + }}; + + fggl::math::vec2i pos{0, 0}; + for (auto& action : actions) { + fggl::math::vec2i size{32, 32}; + auto btn = std::make_unique<fggl::gui::Button>(pos, size); + btn->label(action.name); + btn->addCallback([=](){ + this->m_program.m_instructions.push_back(action.callback); + }); + m_canvas.add(std::move(btn)); + + if ( pos.x == 0 ) { + pos.x += 32 + 8; + } else { + pos.x = 0; + pos.y += 32 + 8; + } + } + + { + fggl::math::vec2i size{32, 32}; + auto btn = std::make_unique<fggl::gui::Button>(pos, size); + btn->label("go"); + btn->addCallback([=](){ + if ( !this->m_program.playing ) { + this->m_program.m_currInstruction = 0; + this->m_program.playing = true; + } + }); + m_canvas.add(std::move(btn)); + } + } void GridScene::activate() { @@ -107,13 +153,11 @@ namespace demo { // fake loading the tileset if ( m_tiles.m_floors.empty() ) { build_tileset(m_tiles); - //auto* assetLoader = m_owner.service<fggl::assets::Loader>(); - //assetLoader->load("tileset_base.yml", ASSET_TILESET); } // create the grid world m_grid = std::make_unique<DemoGrid>(m_tiles); - build_test_env(m_grid.get()); + m_player = build_test_env(m_grid.get()); } void GridScene::deactivate() { @@ -177,72 +221,67 @@ namespace demo { } } + static void update_canvas(fggl::input::Input& inputs, fggl::gui::Container& canvas) { + fggl::math::vec2f cursorPos { + inputs.mouse.axis(fggl::input::MouseAxis::X), + inputs.mouse.axis(fggl::input::MouseAxis::Y) + }; + + // in canvas space + fggl::math::vec2 projected { + fggl::math::rescale_ndc(cursorPos.x, 0, 1920.f), + fggl::math::rescale_ndc(cursorPos.y, 0, 1080.0f) + }; + + auto *hoverWidget = canvas.getChildAt(projected); + /*if (hoverWidget != m_hover) { + if (m_hover != nullptr) { + m_hover->onExit(); + } + m_hover = hoverWidget; + if (m_hover != nullptr) { + m_hover->onEnter(); + } + }*/ + + if (inputs.mouse.pressed(fggl::input::MouseButton::LEFT)) { + auto* widget = canvas.getChildAt(projected); + if (widget != nullptr) { + fggl::debug::info("Button clicked"); + widget->activate(); + } + } + } + void GridScene::update(float deltaTime) { GameBase::update(deltaTime); m_animator.update(deltaTime); + + update_canvas(input(), m_canvas); } void GridScene::tickPlayer() { + if ( !m_program.playing ){ + return; + } + auto &manager = m_grid->entities(); - auto entities = manager.find<CellPos>(); - for (const auto &entity : entities) { - auto &pos = manager.get<CellPos>(entity); - pos.direction = (pos.direction + 1) % 4; + if ( m_program.m_currInstruction < m_program.m_instructions.size() ) { + m_program.m_instructions[ m_program.m_currInstruction ](); + m_program.m_currInstruction++; + } else { + m_program.playing = false; + m_program.m_currInstruction = 0; + m_program.m_instructions.clear(); } } - //float progress = 0.0f; void GridScene::render(fggl::gfx::Graphics &gfx) { fggl::gfx::Paint paint; render_grid(paint, *m_grid); render_objects(paint, *m_grid); - /* - // draw test shapes to check grid alignment - for (int sides = 3; sides <= 25; ++sides) { - auto hexTest = fggl::gfx::make_shape(fggl::math::vec2{sides, 5} * DRAW_SIZE, DRAW_HALF, sides, {1.0F - (sides / 25.0F), 0.0f, sides / 25.0f}); - paint.fill(hexTest); - } - - // draw with edges - for (int sides = 3; sides <= 25; ++sides) { - auto hexTest = fggl::gfx::make_shape(fggl::math::vec2{sides, 6} * DRAW_SIZE, DRAW_HALF, sides, {1.0F - (sides / 25.0F), 0.0f, sides / 25.0f}); - paint.stroke(hexTest); - } - - // draw test arcs - for (int sides = 0; sides < 12; ++sides) { - float endAngle = progress * (M_PI * 2); - - float startAngle = sides/12.0F * (M_PI * 2); - float endAngle2 = endAngle + startAngle; - - auto hexTest = fggl::gfx::make_arc(fggl::math::vec2{sides + 3, 7} * DRAW_SIZE, DRAW_HALF, startAngle, endAngle2, fggl::gfx::colours::CYAN); - paint.fill(hexTest); - } - - // draw sweep - for (int sides = 2; sides <= 25; ++sides){ - float angle = progress * (M_PI * 2); - float sliceSize = 1 / (float)sides * (M_PI * 2); - - float startAngle = angle; - float endAngle = startAngle + sliceSize; - - auto hexTest = fggl::gfx::make_arc(fggl::math::vec2{sides + 3, 8} * DRAW_SIZE, - DRAW_HALF, - startAngle, - endAngle, - fggl::gfx::colours::CYAN); - paint.fill(hexTest); - } - - - progress += 0.01F; - if ( progress > 1.0F) { - progress = 0.0F; - }*/ - + m_canvas.render(paint); gfx.draw2D(paint); } diff --git a/demo/include/grid.hpp b/demo/include/grid.hpp index 380e7722a6a3da90e01143cde6fc030535168986..99d6b1160ef270d9a76bd1c94e2442835f1b97b9 100644 --- a/demo/include/grid.hpp +++ b/demo/include/grid.hpp @@ -22,9 +22,11 @@ #include <memory> #include "fggl/scenes/game.hpp" -#include "fggl/animation/animator.hpp" #include "fggl/entity/gridworld/zone.hpp" +#include "fggl/animation/animator.hpp" +#include "fggl/gui/gui.hpp" + namespace demo { constexpr int GRID_SIZE = 255; @@ -42,6 +44,12 @@ namespace demo { float rotationOffset{0.0F}; }; + struct Program { + std::vector<std::function<void(void)>> m_instructions; + uint32_t m_currInstruction; + bool playing = false; + }; + class GridScene : public fggl::scenes::GameBase { public: explicit GridScene(fggl::App& app); @@ -54,9 +62,34 @@ namespace demo { fggl::entity::grid::TileSet m_tiles; fggl::animation::FrameAnimator m_animator; std::unique_ptr<DemoGrid> m_grid; + fggl::gui::Container m_canvas; + + fggl::entity::EntityID m_player = fggl::entity::INVALID; + Program m_program; void tickPlayer(); + inline void forward() { + auto& cell = m_grid->entities().get<CellPos>(m_player); + fggl::math::vec2i moveDir{0,0}; + if ( cell.direction == 0) { + moveDir.y = 1; + } else if (cell.direction == 1) { + moveDir.x = 1; + } else if (cell.direction == 2) { + moveDir.y = -1; + } else if (cell.direction == 3) { + moveDir.x = -1; + } + cell.pos += moveDir; + } + + inline void rotate(bool clockwise) { + auto& cell = m_grid->entities().get<CellPos>(m_player); + int direction = clockwise ? +1 : -1; + cell.direction = (cell.direction + 4 + direction) % 4; + } + }; } diff --git a/fggl/gui/widgets.cpp b/fggl/gui/widgets.cpp index 12583aaa0b5247c4a8127ec1c03c4fce45661556..a35a8fa0c123f52589eeb5114070b9eea93c93f5 100644 --- a/fggl/gui/widgets.cpp +++ b/fggl/gui/widgets.cpp @@ -39,8 +39,8 @@ namespace fggl::gui { if (m_active) { for (auto &callback : m_callbacks) { callback(); - m_active = false; } + m_active = false; } } diff --git a/fggl/scenes/menu.cpp b/fggl/scenes/menu.cpp index 2c38180e524c84fe6618d87cb55c23423170fd4e..1c0a64d6926f7a4e66d4ffb72786936574d65fac 100644 --- a/fggl/scenes/menu.cpp +++ b/fggl/scenes/menu.cpp @@ -92,7 +92,6 @@ namespace fggl::scenes { // build the button auto btn = std::make_unique<gui::Button>(pos, btnSize); btn->label(name); - btn->addCallback(cb); m_canvas.add(std::move(btn)); }