Very basic collision and combat to work out the idea and a logging system on the left.
This commit is contained in:
parent
98993481b0
commit
dbc2a10933
5 changed files with 57 additions and 13 deletions
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
23
gui.cpp
23
gui.cpp
|
@ -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.
|
||||||
|
|
25
systems.cpp
25
systems.cpp
|
@ -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…
Add table
Add a link
Reference in a new issue