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 "components.hpp"
|
||||||
#include "systems.hpp"
|
#include "systems.hpp"
|
||||||
#include "collider.hpp"
|
#include "collider.hpp"
|
||||||
|
#include "events.hpp"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
|
@ -109,12 +110,45 @@ void GUI::create_renderer() {
|
||||||
bool GUI::handle_events() {
|
bool GUI::handle_events() {
|
||||||
sf::Event event;
|
sf::Event event;
|
||||||
bool event_happened = false;
|
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)) {
|
while($window.pollEvent(event)) {
|
||||||
if(event.type == sf::Event::Closed) {
|
if(event.type == sf::Event::Closed) {
|
||||||
$window.close();
|
$window.close();
|
||||||
} else if(event.type == sf::Event::KeyPressed) {
|
} else if(event.type == sf::Event::KeyPressed) {
|
||||||
auto player = $world.get_the<Player>();
|
|
||||||
auto& player_motion = $world.get<Motion>(player.entity);
|
auto& player_motion = $world.get<Motion>(player.entity);
|
||||||
|
|
||||||
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
|
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
|
continue; // skip these, just windows junk
|
||||||
} else {
|
} else {
|
||||||
// it's a visual cell
|
// 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);
|
sf::Sprite &sprite = get_text_sprite(tile);
|
||||||
|
|
||||||
// should look into caching all this instead of calcing it each time
|
// 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;
|
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
|
// 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
|
// get the entity combat and make them light gray if dead
|
||||||
if(tile == L'█') {
|
if(tile == L'█') {
|
||||||
|
@ -259,8 +293,8 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) {
|
||||||
|
|
||||||
void GUI::shake() {
|
void GUI::shake() {
|
||||||
for(int i = 0; i < 10; ++i) {
|
for(int i = 0; i < 10; ++i) {
|
||||||
int x = Random::uniform<int>(-10,10);
|
int x = Random::uniform<int>(-20,20);
|
||||||
int y = Random::uniform<int>(-10,10);
|
int y = Random::uniform<int>(-20,20);
|
||||||
// add x/y back to draw screen
|
// add x/y back to draw screen
|
||||||
draw_screen(true, x, y);
|
draw_screen(true, x, y);
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
|
@ -271,6 +305,7 @@ void GUI::configure_world() {
|
||||||
SoundManager sounds("./assets");
|
SoundManager sounds("./assets");
|
||||||
sounds.load("hit", "hit.wav");
|
sounds.load("hit", "hit.wav");
|
||||||
$world.set_the<SoundManager>(sounds);
|
$world.set_the<SoundManager>(sounds);
|
||||||
|
$world.set_the<GUIEvent>(GUIEvent::START);
|
||||||
|
|
||||||
dbc::check($game_map.room_count() > 1, "not enough rooms in map.");
|
dbc::check($game_map.room_count() > 1, "not enough rooms in map.");
|
||||||
// configure a player as a fact of the world
|
// configure a player as a fact of the world
|
||||||
|
|
|
@ -4,6 +4,13 @@ NOTES:
|
||||||
* src/ftxui/screen/color.cpp
|
* src/ftxui/screen/color.cpp
|
||||||
* Just search for ugrep x1B
|
* Just search for ugrep x1B
|
||||||
* https://man7.org/linux/man-pages/man4/console_codes.4.html
|
* 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:
|
TODO:
|
||||||
|
|
||||||
|
|
17
systems.cpp
17
systems.cpp
|
@ -4,7 +4,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "rand.hpp"
|
#include "rand.hpp"
|
||||||
#include "collider.hpp"
|
#include "collider.hpp"
|
||||||
#include "sound.hpp"
|
#include "events.hpp"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
|
@ -84,13 +84,10 @@ void System::death(DinkyECS::World &world) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void System::combat(DinkyECS::World &world, Player &player) {
|
void System::combat(DinkyECS::World &world, Player &player) {
|
||||||
auto& collider = world.get_the<spatial_map>();
|
auto& collider = world.get_the<spatial_map>();
|
||||||
const auto& player_position = world.get<Position>(player.entity);
|
const auto& player_position = world.get<Position>(player.entity);
|
||||||
auto& player_combat = world.get<Combat>(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
|
// this is guaranteed to not return the given position
|
||||||
auto [found, nearby] = collider.neighbors(player_position.location);
|
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);
|
int player_dmg = player_combat.attack(enemy_combat);
|
||||||
|
|
||||||
if(player_dmg > 0) {
|
if(player_dmg > 0) {
|
||||||
log.log(format("You HIT for {} damage, HP left {}.", player_dmg, enemy_combat.hp));
|
world.send<GUIEvent>(GUIEvent::HIT, entity);
|
||||||
sounds.play("hit");
|
|
||||||
} else {
|
} else {
|
||||||
log.log("You missed! They're quick!");
|
world.send<GUIEvent>(GUIEvent::MISS, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemy_combat.hp > 0) {
|
if(enemy_combat.hp > 0) {
|
||||||
int enemy_dmg = enemy_combat.attack(player_combat);
|
int enemy_dmg = enemy_combat.attack(player_combat);
|
||||||
|
|
||||||
if(enemy_dmg > 0) {
|
if(enemy_dmg > 0) {
|
||||||
sounds.play("hit");
|
world.send<GUIEvent>(GUIEvent::HIT, player.entity);
|
||||||
log.log(format("Enemy HIT YOU for {} damage.", enemy_dmg));
|
|
||||||
} else {
|
} else {
|
||||||
log.log("Enemy MISSED, you dodged it.");
|
world.send<GUIEvent>(GUIEvent::MISS, player.entity);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.log("ENEMY DEAD! YOU WIN!");
|
world.send<GUIEvent>(GUIEvent::DEAD, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue