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.
This commit is contained in:
parent
da8011cb14
commit
04350cb51e
4 changed files with 58 additions and 16 deletions
5
events.hpp
Normal file
5
events.hpp
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
enum GUIEvent {
|
||||
START, HIT, MISS, DEAD
|
||||
};
|
45
gui.cpp
45
gui.cpp
|
@ -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:
|
||||
|
||||
|
|
17
systems.cpp
17
systems.cpp
|
@ -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…
Add table
Add a link
Reference in a new issue