diff --git a/main.cpp b/main.cpp index 5c2e66f..871694e 100644 --- a/main.cpp +++ b/main.cpp @@ -1,195 +1,6 @@ -// Copyright 2020 Arthur Sonzogni. All rights reserved. -// Use of this source code is governed by the MIT license that can be found in -// the LICENSE file. -#include // for operator""s, chrono_literals -#include // for cout, ostream -#include -#include -#include -#include // for allocator, shared_ptr -#include // for string, operator<< -#include // for sleep_for - -#include // for hflow, paragraph, separator, hbox, vbox, filler, operator|, border, Element -#include // for Render -#include // for ftxui -#include -#include -#include -#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive -#include -#include -#include -#include -#include -#include - -#include -#include "fsm.hpp" -#include "map.hpp" -#include "entity.hpp" -#include "dbc.hpp" - -using std::string; -using namespace fmt; -using namespace std::chrono_literals; - -enum class Value { - BLACK=0, DARK_DARK, DARK_MID, - DARK_LIGHT, MID, LIGHT_DARK, LIGHT_MID, - LIGHT_LIGHT, WHITE, TRANSPARENT -}; - -std::array VALUES{ - sf::Color{1, 4, 2}, // black - sf::Color{9, 29, 16}, // dark dark - sf::Color{14, 50, 26}, // dark mid - sf::Color{0, 109, 44}, // dark light - sf::Color{63, 171, 92}, // mid - sf::Color{161, 217, 155}, // light dark - sf::Color{199, 233, 192}, // light mid - sf::Color{229, 245, 224}, // light light - sf::Color{255, 255, 255}, // white - sf::Color::Transparent, // white -}; - -sf::SoundBuffer g_hit_buf; -sf::Sound g_hit_sound; +#include "gui.hpp" int main() { - using namespace ftxui; - auto c = Canvas(60 * 2, 20 * 4); - - int res = g_hit_buf.loadFromFile("./assets/hit.wav"); - dbc::check(res, "faile to load hit.wav"); - g_hit_sound.setBuffer(g_hit_buf); - - Map game_map(50, 20); - game_map.generate(); - Matrix &walls = game_map.walls(); - Room &start = game_map.room(0); - Room &bad_room = game_map.room(1); - Room &gold_room = game_map.room(game_map.room_count() - 1); - - Entity me({.x=start.x+1, .y=start.y+1}); - Entity enemy({.x=bad_room.x+1, .y=bad_room.y+1}); - Point goal{.x=gold_room.x+1, .y=gold_room.y+1}; - string status_text = "NOT DEAD"; - - bool show_paths = false; - bool bomb = false; - - auto map = Renderer([&] { - game_map.set_target(me.location); - game_map.make_paths(); - Matrix &paths = game_map.paths(); - - if(me.in_state(EntityState::DEAD)) { - status_text = "DEAD!"; - } - - for(size_t x = 0; x < walls[0].size(); ++x) { - for(size_t y = 0; y < walls.size(); ++y) { - string tile = walls[y][x] == 1 ? "#" : format("{}", paths[y][x]); - if(tile == "#") { - c.DrawText(x*2, y*4, tile); - } else if(show_paths) { - //int pnum = paths[y][x]; - c.DrawText(x*2, y*4, tile); - } else { - c.DrawText(x*2, y*4, "."); - } - } - } - - if(bomb) { - /// draw - bomb = false; - c.DrawPointCircle(me.location.x*2, me.location.y*4, 4); - } - - c.DrawText(enemy.location.x*2, enemy.location.y*4, "!"); - c.DrawText(me.location.x*2, me.location.y*4, "@"); - c.DrawText(goal.x*2, goal.y*4, "$"); - - return canvas(c); - }); - - auto document = Renderer([&]{ - return hbox({ - hflow( - vbox( - text(format("HP: {}", me.hp)) | border, - text(status_text) | border - ) | xflex_grow - ), - separator(), - hbox(map->Render()), - }); - }); - - auto screen = Screen::Create(Dimension::Full()); - - sf::RenderWindow window(sf::VideoMode(1600,900), "Roguish"); - - sf::Font font; - font.loadFromFile("./assets/text.otf"); - sf::Text text; - text.setFont(font); - text.setCharacterSize(30); - text.setFillColor(VALUES[size_t(Value::LIGHT_DARK)]); - - while(window.isOpen()) { - Render(screen, document->Render()); - std::string screen_out = screen.ToString(); - std::wstring_convert> converter; - std::wstring utf8 = converter.from_bytes(screen_out); - - text.setString(utf8); - text.setPosition({0,0}); - window.clear(); - window.draw(text); - window.display(); - - sf::Event event; - while(window.pollEvent(event)) { - if(event.type == sf::Event::Closed) { - window.close(); - } else if(event.type == sf::Event::KeyPressed) { - size_t x = me.location.x; - size_t y = me.location.y; - - if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { - x -= 1; - } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { - x += 1; - } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { - y -= 1; - } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { - y += 1; - } - - if(game_map.inmap(x,y) && !game_map.iswall(x,y)) { - game_map.clear_target(me.location); - me.move({x, y}); - } else { - g_hit_sound.play(); - } - - // move enemy here - bool found = game_map.neighbors(enemy.location, true); - if(!found) { - status_text = "ENEMY STUCK!"; - } - - if(enemy.location.x == me.location.x && enemy.location.y == me.location.y) { - me.event(EntityEvent::HIT); - } else if(goal.x == me.location.x && goal.y == me.location.y) { - status_text = "YOU WIN!"; - } - } - } - } - - return 0; + GUI gui; + return gui.main(); } diff --git a/map.cpp b/map.cpp index abe78be..2abea56 100644 --- a/map.cpp +++ b/map.cpp @@ -263,6 +263,8 @@ bool Map::walk(Point &src, Point &target) { make_paths(); bool found = false; Point out{src.x, src.y}; + int count = 0; + do { walls_[out.y][out.x] = INV_SPACE; found = neighbors(out, true); @@ -271,7 +273,7 @@ bool Map::walk(Point &src, Point &target) { walls_[out.y][out.x] = INV_SPACE; return true; } - } while(found && out.x > 0 && out.y > 0); + } while(found && out.x > 0 && out.y > 0 && ++count < 100); return false; } @@ -324,7 +326,6 @@ bool Map::iswall(size_t x, size_t y) { return walls_[y][x] == WALL_VALUE; } - void Map::dump() { dump_map("PATHS", paths_); dump_map("WALLS", walls_); diff --git a/meson.build b/meson.build index 6bfc4d0..8c56172 100644 --- a/meson.build +++ b/meson.build @@ -27,6 +27,7 @@ roguish = executable('roguish', [ 'dbc.cpp', 'main.cpp', 'map.cpp', + 'gui.cpp', 'entity.cpp', ], dependencies: dependencies)