Tinkering with a way to do modal UIs for things like inventory etc.

This commit is contained in:
Zed A. Shaw 2024-12-30 09:41:16 -05:00
parent db441000f8
commit d8400d0a76
9 changed files with 120 additions and 92 deletions

109
gui.cpp
View file

@ -29,38 +29,13 @@ using namespace std::chrono_literals;
using namespace ftxui;
using namespace components;
const std::string modal_shader = R"(
uniform sampler2D source;
uniform sampler2D bloom;
uniform vec2 offsetFactor;
uniform float darkness;
void main()
{
vec2 textureCoordinates = gl_TexCoord[0].xy;
vec4 color = vec4(0.0);
color += texture2D(source, textureCoordinates - 4.0 * offsetFactor) * 0.0162162162;
color += texture2D(source, textureCoordinates - 3.0 * offsetFactor) * 0.0540540541;
color += texture2D(source, textureCoordinates - 2.0 * offsetFactor) * 0.1216216216;
color += texture2D(source, textureCoordinates - offsetFactor) * 0.1945945946;
color += texture2D(source, textureCoordinates) * 0.2270270270;
color += texture2D(source, textureCoordinates + offsetFactor) * 0.1945945946;
color += texture2D(source, textureCoordinates + 2.0 * offsetFactor) * 0.1216216216;
color += texture2D(source, textureCoordinates + 3.0 * offsetFactor) * 0.0540540541;
color += texture2D(source, textureCoordinates + 4.0 * offsetFactor) * 0.0162162162;
vec4 sourceFragment = texture2D(source, gl_TexCoord[0].xy);
vec4 bloomFragment = texture2D(bloom, gl_TexCoord[0].xy);
gl_FragColor = color + sourceFragment - bloomFragment - darkness;
}
)";
GUI::GUI(DinkyECS::World &world, Map& game_map) :
$game_map(game_map),
$log({{"Welcome to the game!"}}),
$status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
$map_view(GAME_MAP_POS, 0, 0, 0, true),
$status_ui(0, 0, STATUS_UI_WIDTH, STATUS_UI_HEIGHT),
$map_view(GAME_MAP_PIXEL_POS, 0, 0, 0, true),
$inventory_ui(INVENTORY_PIXEL_X, INVENTORY_PIXEL_Y, INVENTORY_WIDTH, INVENTORY_HEIGHT),
$lights(game_map.width(), game_map.height()),
$world(world),
$sounds("./assets"),
@ -72,8 +47,8 @@ GUI::GUI(DinkyECS::World &world, Map& game_map) :
$sounds.load("combat_player_hit", "combat_player_hit.mp3");
$sounds.load("combat_enemy_hit", "combat_enemy_hit.mp3");
$sounds.load("combat_miss", "combat_miss.mp3");
resize_map(MAX_FONT_SIZE);
init_shaders();
}
void GUI::resize_map(int new_size) {
@ -96,27 +71,21 @@ void GUI::create_renderer() {
return canvas($canvas);
}));
auto modal_buttons = Container::Horizontal({
Button("OK", [&]{ $show_modal = false; }),
Button("CANCEL", [&]{ $show_modal = false; }),
auto cell = [](const char* t) { return text(t) | border; };
auto inventory_test = Renderer([cell] {
return hflow({
gridbox({
{cell("one"), cell("two"), cell("three")},
{cell("four"), cell("five"), cell("six")},
{cell("seven"), cell("eight"), cell("nine")},
}) | yflex_grow,
separator() | yflex_grow,
paragraph("Item UI Goes Here") | yflex_grow
}) | border | flex;
});
auto modal_test = Renderer([&, modal_buttons] {
return hbox({
hflow(
vbox(
text("Hello!"),
modal_buttons->Render()
))}) | border;
});
modal_test->Add(modal_buttons);
auto test_button = Container::Horizontal({
Button("Open Test Modal", [&]{ $show_modal = true; }),
Button("Close It", [&]{ $show_modal = false; }),
});
auto status_rend = Renderer(test_button, [&, modal_test, test_button, player]{
auto status_rend = Renderer([&, player]{
const auto& player_combat = $world.get<Combat>(player.entity);
const auto& inventory = $world.get<Inventory>(player.entity);
$status_text = player_combat.hp > 0 ? "NOT DEAD" : "DEAD!!!!!!";
@ -131,7 +100,6 @@ void GUI::create_renderer() {
return hbox({
hflow(
vbox(
test_button->Render(),
text(format("HP: {: >3} GOLD: {: >3}",
player_combat.hp, inventory.gold)) | border,
text($status_text) | border,
@ -144,10 +112,8 @@ void GUI::create_renderer() {
});
});
status_rend |= Modal(modal_test, &$show_modal);
$status_ui.set_renderer(status_rend);
$status_ui.add(modal_test);
$inventory_ui.set_renderer(inventory_test);
}
void GUI::handle_world_events() {
@ -232,8 +198,13 @@ bool GUI::handle_ui_events() {
auto &debug = $world.get_the<Debug>();
debug.LIGHT = !debug.LIGHT;
} else if(KB::isKeyPressed(KB::I)) {
create_modal();
$show_modal = !$show_modal;
// yes, using an if to avoid double grabbing screen
if($show_modal) {
$show_modal = false;
} else {
pause_screen();
$show_modal = true;
}
} else if(KB::isKeyPressed(KB::P)) {
auto &debug = $world.get_the<Debug>();
debug.PATHS = !debug.PATHS;
@ -257,24 +228,24 @@ bool GUI::handle_ui_events() {
return event_happened;
}
void GUI::create_modal() {
println("CREATING MODAL");
void GUI::init_shaders() {
auto& shader = $paused.load_shader("./shaders/modal.frag");
shader.setUniform("offsetFactor", sf::Glsl::Vec2{0.001f, 0.001f});
shader.setUniform("darkness", 0.05f);
}
void GUI::pause_screen() {
auto &window = $renderer.$window;
auto size = window.getSize();
paused_texture.create(size.x, size.y);
paused_texture.update(window);
bool good = paused_shader.loadFromMemory(modal_shader, sf::Shader::Fragment);
paused_shader.setUniform("offsetFactor", sf::Glsl::Vec2{0.001f, 0.001f});
paused_shader.setUniform("darkness", 0.05f);
dbc::check(good, "shader could not be loaded");
paused_sprite.setTexture(paused_texture);
paused_sprite.setPosition(0,0);
$paused.texture.create(size.x, size.y);
$paused.texture.update(window);
$paused.sprite.setTexture($paused.texture);
$paused.sprite.setPosition(0,0);
}
void GUI::draw_modal() {
auto &window = $renderer.$window;
window.draw(paused_sprite, &paused_shader);
void GUI::draw_paused() {
$renderer.draw_sprite($paused.sprite, &$paused.shader);
}
void GUI::run_systems() {
@ -301,7 +272,9 @@ void GUI::render_scene() {
$renderer.clear();
if($show_modal) {
draw_modal();
draw_paused();
$inventory_ui.render();
$renderer.draw($inventory_ui);
} else {
$map_view.render();
$renderer.draw($map_view);