GUI is now decoupled from the ECS using the new DinkyECS event queues. That makes it easier to update and change the GUI without having to constantly alter the systems.

main
Zed A. Shaw 2 weeks ago
parent da8011cb14
commit 04350cb51e
  1. 5
      events.hpp
  2. 45
      gui.cpp
  3. 7
      status.txt
  4. 17
      systems.cpp

@ -0,0 +1,5 @@
#pragma once
enum GUIEvent {
START, HIT, MISS, DEAD
};

@ -23,6 +23,7 @@
#include "components.hpp"
#include "systems.hpp"
#include "collider.hpp"
#include "events.hpp"
using std::string;
using namespace fmt;
@ -109,12 +110,45 @@ void GUI::create_renderer() {
bool GUI::handle_events() {
sf::Event event;
bool event_happened = false;
auto& log = $world.get_the<ActionLog>();
auto player = $world.get_the<Player>();
auto sounds = $world.get_the<SoundManager>();
while($world.has_event<GUIEvent>()) {
auto [evt, entity] = $world.recv<GUIEvent>();
switch(evt) {
case GUIEvent::HIT: {
auto combat = $world.get<Combat>(entity);
if(entity == player.entity) {
log.log(format("Enemy HIT YOU, you have {} HP!", combat.hp));
sounds.play("hit");
shake();
} else {
log.log(format("You HIT enemy, they have {} HP!", combat.hp));
sounds.play("hit");
shake();
}
} break;
case GUIEvent::MISS:
if(entity == player.entity) {
log.log("You MISSED the enemy.");
} else {
log.log("Enemy MISSED YOU.");
}
break;
case GUIEvent::DEAD:
log.log("--- ENEMY DEAD!");
break;
default:
log.log(format("INVALID EVENT! {},{}", evt, entity));
}
}
while($window.pollEvent(event)) {
if(event.type == sf::Event::Closed) {
$window.close();
} else if(event.type == sf::Event::KeyPressed) {
auto player = $world.get_the<Player>();
auto& player_motion = $world.get<Motion>(player.entity);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
@ -211,7 +245,7 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) {
continue; // skip these, just windows junk
} else {
// it's a visual cell
bg_sprite.setPosition({x, y});
bg_sprite.setPosition({x+map_off_x, y+map_off_y});
sf::Sprite &sprite = get_text_sprite(tile);
// should look into caching all this instead of calcing it each time
@ -222,7 +256,7 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) {
auto height_delta = bg_bounds.height > sp_bounds.width ? (bg_bounds.height - sp_bounds.height) / 2 : 0;
// TODO: need to center it inside the bg_sprite
sprite.setPosition({x+width_delta, y+height_delta});
sprite.setPosition({x+width_delta+map_off_x, y+height_delta+map_off_y});
// get the entity combat and make them light gray if dead
if(tile == L'') {
@ -259,8 +293,8 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) {
void GUI::shake() {
for(int i = 0; i < 10; ++i) {
int x = Random::uniform<int>(-10,10);
int y = Random::uniform<int>(-10,10);
int x = Random::uniform<int>(-20,20);
int y = Random::uniform<int>(-20,20);
// add x/y back to draw screen
draw_screen(true, x, y);
std::this_thread::sleep_for(1ms);
@ -271,6 +305,7 @@ void GUI::configure_world() {
SoundManager sounds("./assets");
sounds.load("hit", "hit.wav");
$world.set_the<SoundManager>(sounds);
$world.set_the<GUIEvent>(GUIEvent::START);
dbc::check($game_map.room_count() > 1, "not enough rooms in map.");
// configure a player as a fact of the world

@ -4,6 +4,13 @@ NOTES:
* src/ftxui/screen/color.cpp
* Just search for ugrep x1B
* https://man7.org/linux/man-pages/man4/console_codes.4.html
* amit note:
Struct A {
int data;
template <typename T> A(T t) : data(static_cast<int>(t)) {}
};
A a(my_enum);
TODO:

@ -4,7 +4,7 @@
#include <cmath>
#include "rand.hpp"
#include "collider.hpp"
#include "sound.hpp"
#include "events.hpp"
using std::string;
using namespace fmt;
@ -84,13 +84,10 @@ void System::death(DinkyECS::World &world) {
});
}
void System::combat(DinkyECS::World &world, Player &player) {
auto& collider = world.get_the<spatial_map>();
const auto& player_position = world.get<Position>(player.entity);
auto& player_combat = world.get<Combat>(player.entity);
auto& log = world.get_the<ActionLog>();
auto& sounds = world.get_the<SoundManager>();
// this is guaranteed to not return the given position
auto [found, nearby] = collider.neighbors(player_position.location);
@ -101,23 +98,21 @@ void System::combat(DinkyECS::World &world, Player &player) {
int player_dmg = player_combat.attack(enemy_combat);
if(player_dmg > 0) {
log.log(format("You HIT for {} damage, HP left {}.", player_dmg, enemy_combat.hp));
sounds.play("hit");
world.send<GUIEvent>(GUIEvent::HIT, entity);
} else {
log.log("You missed! They're quick!");
world.send<GUIEvent>(GUIEvent::MISS, entity);
}
if(enemy_combat.hp > 0) {
int enemy_dmg = enemy_combat.attack(player_combat);
if(enemy_dmg > 0) {
sounds.play("hit");
log.log(format("Enemy HIT YOU for {} damage.", enemy_dmg));
world.send<GUIEvent>(GUIEvent::HIT, player.entity);
} else {
log.log("Enemy MISSED, you dodged it.");
world.send<GUIEvent>(GUIEvent::MISS, player.entity);
}
} else {
log.log("ENEMY DEAD! YOU WIN!");
world.send<GUIEvent>(GUIEvent::DEAD, entity);
}
}
}

Loading…
Cancel
Save