Now has an actual game loop where you die and start over.

This commit is contained in:
Zed A. Shaw 2026-04-03 12:44:35 -04:00
parent 514bfec0ea
commit 009c5c1cd2
10 changed files with 124 additions and 86 deletions

View file

@ -17,15 +17,12 @@ namespace gui {
using namespace components;
using game::Event;
FSM::FSM() :
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
FSM::FSM(sf::RenderWindow& window) :
$window(window),
$main_ui($window),
$dnd_loot($status_ui, $loot_ui, $window, $router)
{
$window.setVerticalSyncEnabled(VSYNC);
if(FRAME_LIMIT) $window.setFramerateLimit(FRAME_LIMIT);
$window.setPosition({0,0});
System::init($systems);
}
void FSM::event(Event ev, std::any data) {
@ -41,7 +38,9 @@ namespace gui {
FSM_STATE(State, ROTATING, ev);
FSM_STATE(State, IDLE, ev, data);
FSM_STATE(State, LOOTING, ev, data);
FSM_STATE(State, END, ev);
FSM_STATE(State, END_QUIT, ev);
FSM_STATE(State, END_PLAY_AGAIN, ev);
FSM_STATE(State, END_PLAYER_DIED, ev);
}
}
@ -59,9 +58,9 @@ namespace gui {
$debug_ui.init(cell);
$status_ui.init();
run_systems();
$story = std::make_shared<storyboard::UI>("intro_story");
$story->init();
state(State::INTRO);
show_scene("STARTING");
state(State::START_SCENE);
}
void FSM::INTRO(Event ev) {
@ -73,8 +72,7 @@ namespace gui {
}
} else {
$story = nullptr;
show_scene("STARTING");
state(State::START_SCENE);
state(State::IDLE);
}
}
@ -90,7 +88,9 @@ namespace gui {
} break;
case START:
close_scene();
state(State::IDLE);
$story = std::make_shared<storyboard::UI>("intro_story");
$story->init();
state(State::INTRO);
break;
case QUIT:
FSM::IDLE(ev, {});
@ -115,7 +115,7 @@ namespace gui {
} break;
case START:
close_scene();
state(State::IDLE);
state(State::END_PLAYER_DIED);
break;
case QUIT:
FSM::IDLE(ev, {});
@ -137,7 +137,7 @@ namespace gui {
} break;
case START:
close_scene();
state(State::IDLE);
state(State::END_PLAY_AGAIN);
break;
case QUIT:
FSM::IDLE(ev, {});
@ -232,7 +232,7 @@ namespace gui {
switch(ev) {
case QUIT:
$window.close();
state(State::END);
state(State::END_QUIT);
return; // done
case MOVE_FORWARD:
try_move(1, false);
@ -317,8 +317,16 @@ namespace gui {
}
}
void FSM::END(Event ev) {
dbc::log($F("END: received event after done: {}", int(ev)));
void FSM::END_QUIT(Event ev) {
dbc::log($F("END_QUIT: received event after done: {}", int(ev)));
}
void FSM::END_PLAYER_DIED(Event ev) {
dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev)));
}
void FSM::END_PLAY_AGAIN(Event ev) {
dbc::log($F("END_PLAY_AGAIN: received event after done: {}", int(ev)));
}
sf::Vector2f FSM::mouse_position() {
@ -458,7 +466,9 @@ namespace gui {
}
bool FSM::active() {
return !in_state(State::END);
return !(in_state(State::END_QUIT)
|| in_state(State::END_PLAY_AGAIN)
|| in_state(State::END_PLAYER_DIED));
}
void FSM::handle_world_events() {

View file

@ -27,12 +27,14 @@ namespace gui {
ROTATING=__LINE__,
LOOTING=__LINE__,
IDLE=__LINE__,
END=__LINE__,
END_QUIT=__LINE__,
END_PLAYER_DIED=__LINE__,
END_PLAY_AGAIN=__LINE__,
};
class FSM : public DeadSimpleFSM<State, game::Event> {
public:
sf::RenderWindow $window;
sf::RenderWindow& $window;
bool $draw_stats = false;
DebugUI $debug_ui;
MainUI $main_ui;
@ -51,7 +53,7 @@ namespace gui {
std::shared_ptr<gui::SceneUI> $cur_scene = nullptr;
std::shared_ptr<storyboard::UI> $story = nullptr;
FSM();
FSM(sf::RenderWindow& window);
void event(game::Event ev, std::any data={});
@ -67,7 +69,9 @@ namespace gui {
void MAPPING(game::Event ev);
void ROTATING(game::Event ev);
void LOOTING(game::Event ev, std::any data);
void END(game::Event ev);
void END_QUIT(game::Event ev);
void END_PLAYER_DIED(game::Event ev);
void END_PLAY_AGAIN(game::Event ev);
void try_move(int dir, bool strafe);
sf::Vector2f mouse_position();

View file

@ -7,10 +7,19 @@
namespace gui {
using namespace guecs;
LootUI::LootUI() :
$temp_loot(GameDB::current_world()->entity()),
$target($temp_loot)
LootUI::LootUI()
{
}
void LootUI::make_button(const std::string &name, const std::wstring& label, game::Event event) {
auto button = $gui.entity(name);
$gui.set<guecs::Rectangle>(button, {});
$gui.set<guecs::Text>(button, {label});
$gui.set<guecs::Clickable>(button,
guecs::make_action(button, event));
}
void LootUI::init() {
$gui.position(RAY_VIEW_X+RAY_VIEW_WIDTH/2-200,
RAY_VIEW_Y+RAY_VIEW_HEIGHT/2-200, 400, 400);
@ -21,21 +30,14 @@ namespace gui {
"[=item_12| =item_13|=item_14|=item_15 ]"
"[ =take_all | =close| =destroy]");
// setup a fake container for our loot
$temp_loot = GameDB::current_world()->entity();
$target = $temp_loot;
auto world = GameDB::current_world();
world->set<inventory::Model>($temp_loot, {});
world->make_constant($temp_loot);
}
void LootUI::make_button(const std::string &name, const std::wstring& label, game::Event event) {
auto button = $gui.entity(name);
$gui.set<guecs::Rectangle>(button, {});
$gui.set<guecs::Text>(button, {label});
$gui.set<guecs::Clickable>(button,
guecs::make_action(button, event));
}
void LootUI::init() {
using guecs::THEME;
auto bg_color = THEME.DARK_LIGHT;
bg_color.a = 140;
@ -65,7 +67,7 @@ namespace gui {
auto world = GameDB::current_world();
dbc::check(world->has<inventory::Model>($target),
"update called but $target isn't in world");
$F("update called but $target isn't in world: {}", $target));
auto& contents = world->get<inventory::Model>($target);