Very basic collision and combat to work out the idea and a logging system on the left.

main
Zed A. Shaw 4 weeks ago
parent 98993481b0
commit dbc2a10933
  1. 12
      components.hpp
  2. 23
      gui.cpp
  3. 2
      scratchpad/collider.cpp
  4. 8
      status.txt
  5. 25
      systems.cpp

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "dinkyecs.hpp" #include "dinkyecs.hpp"
#include <deque>
namespace Components { namespace Components {
struct Player { struct Player {
@ -27,4 +28,15 @@ namespace Components {
struct Tile { struct Tile {
std::string chr = "!"; std::string chr = "!";
}; };
struct ActionLog {
std::deque<std::string> messages;
void log(std::string msg) {
messages.push_front(msg);
if(messages.size() > 20) {
messages.pop_back();
}
}
};
} }

@ -83,12 +83,24 @@ void GUI::create_renderer() {
$document = Renderer([&, player]{ $document = Renderer([&, player]{
const auto& player_combat = $world.component<Combat>(player.entity); const auto& player_combat = $world.component<Combat>(player.entity);
const auto& log = $world.get<ActionLog>();
$status_text = player_combat.hp > 0 ? "NOT DEAD" : "DEAD!!!!!!";
std::vector<Element> log_list;
for(auto msg : log.messages) {
log_list.push_back(text(msg));
}
auto log_box = vbox(log_list) | yflex_grow | border;
return hbox({ return hbox({
hflow( hflow(
vbox( vbox(
text(format("HP: {}", player_combat.hp)) | border, text(format("HP: {: >3}", player_combat.hp)) | border,
text($status_text) | border text($status_text) | border,
) | xflex_grow separator(),
log_box
) | flex_grow
), ),
separator(), separator(),
hbox(), hbox(),
@ -262,6 +274,9 @@ void GUI::configure_world() {
Player player{$world.entity()}; Player player{$world.entity()};
$world.set<Player>(player); $world.set<Player>(player);
ActionLog log{{"Welcome to the game!"}};
$world.set<ActionLog>(log);
$world.assign<Position>(player.entity, {$game_map.place_entity(0)}); $world.assign<Position>(player.entity, {$game_map.place_entity(0)});
$world.assign<Motion>(player.entity, {0, 0}); $world.assign<Motion>(player.entity, {0, 0});
$world.assign<Combat>(player.entity, {100, 10}); $world.assign<Combat>(player.entity, {100, 10});
@ -286,6 +301,8 @@ void GUI::configure_world() {
} }
void GUI::render_scene() { void GUI::render_scene() {
$screen.Clear();
$map_screen.Clear();
Render($map_screen, $map_view->Render()); Render($map_screen, $map_view->Render());
Render($screen, $document->Render()); Render($screen, $document->Render());

@ -58,6 +58,8 @@ class SpatialHashTable {
std::unordered_map<Point, std::vector<Object*>, PointHash> table; std::unordered_map<Point, std::vector<Object*>, PointHash> table;
}; };
int main() { int main() {
SpatialHashTable hashTable; SpatialHashTable hashTable;
Object obj1 = {{5, 5}}; Object obj1 = {{5, 5}};

@ -1,8 +1,8 @@
TODO: TODO:
* Figure out how to render color fonts from FTUI.
* Dynamically determine the font vs. screensize to get an exact FTXUI screen size.
* Write a test that generates a ton of maps then confirms there's a path from one room to every other room? * Write a test that generates a ton of maps then confirms there's a path from one room to every other room?
* If the player is trapped in a room the enemy just travles through walls.
* Add FLECS.
* Lua integration? * Lua integration?
* Text is not actually cleared when rendered either in FTXUI or SFML.
* Work on collision detection with either a coordinate map or morton codes.
* Bring back sounds, check out SoLoud.

@ -1,6 +1,8 @@
#include "systems.hpp" #include "systems.hpp"
#include <fmt/core.h> #include <fmt/core.h>
#include <string> #include <string>
#include <cmath>
#include "rand.hpp"
using std::string; using std::string;
using namespace fmt; using namespace fmt;
@ -33,8 +35,9 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
}; };
motion = {0,0}; // clear it after getting it motion = {0,0}; // clear it after getting it
// avoid colision, but could this be a different system? if(game_map.inmap(move_to.x, move_to.y) &&
if(game_map.inmap(move_to.x, move_to.y) && !game_map.iswall(move_to.x,move_to.y)) { !game_map.iswall(move_to.x,move_to.y))
{
position.location = move_to; position.location = move_to;
} }
} }
@ -44,12 +47,22 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
void System::combat(DinkyECS::World &world, Player &player) { void System::combat(DinkyECS::World &world, Player &player) {
const auto& player_position = world.component<Position>(player.entity); const auto& player_position = world.component<Position>(player.entity);
auto& player_combat = world.component<Combat>(player.entity);
auto& log = world.get<ActionLog>();
world.system<Position, Combat>([&](const auto &ent, auto &pos, auto &combat) { world.system<Position, Combat>([&](const auto &ent, auto &pos, auto &combat) {
if(ent != player.entity && pos.location.x == player_position.location.x && if(ent != player.entity) {
pos.location.y == player_position.location.y) int dx = std::abs(int(pos.location.x) - int(player_position.location.x));
{ int dy = std::abs(int(pos.location.y) - int(player_position.location.y));
// need to sort out combat here
if(dx <= 1 && dy <= 1) {
if(player_combat.hp > -1) {
int dmg = Random::uniform<int>(1, combat.damage);
player_combat.hp -= dmg;
log.log(format("HIT! You took {} damage.", dmg));
}
}
} }
}); });
}; };

Loading…
Cancel
Save