Commit f3fde2ae authored by Georg Schaefer's avatar Georg Schaefer
Browse files

Merge branch 'feature/19-level-datastructure' into 'develop'

Resolve "Level: Datastructure"

Closes #19

See merge request !1
parents 6ad48533 00b61bf9
Pipeline #3246 passed with stage
in 7 minutes and 36 seconds
{
"tile_size": 4,
"tiles": {
"|": {
"blueprint": "dummy_wall",
"solid": true
},
"-": {
"blueprint": "dummy_wall",
"solid": true
},
" ": {
"blueprint": "dummy_floor",
"solid": false
},
"#": {
"blueprint": "dummy_ceiling",
"solid": true
},
"p": {
"blueprint": "dummy_floor",
"solid": false,
"spawn": true,
"spawns": "player"
}
}
}
#include "game_screen.hpp"
#include "game_engine.hpp"
#include "level/level_system.hpp"
#include "meta_system.hpp"
#include <mirrage/renderer/animation_comp.hpp>
......@@ -52,6 +53,8 @@ namespace phase_shifter {
{
_meta_system.shrink_to_fit();
_mailbox.enable();
_meta_system.level_system().load("dummy");
}
void Game_screen::_on_leave(mirrage::util::maybe<Screen&>) { _mailbox.disable(); }
......
......@@ -4,7 +4,7 @@
#include <mirrage/utils/sf2_glm.hpp>
namespace phase_shifter::gameplay {
struct Viewtarget_comp : public mirrage::ecs::Component<Viewtarget_comp> {
static constexpr const char* name() { return "Viewtarget"; }
using Component::Component;
......@@ -15,4 +15,4 @@ namespace phase_shifter::gameplay {
};
sf2_structDef(Viewtarget_comp, offset);
}
\ No newline at end of file
} // namespace phase_shifter::gameplay
......@@ -55,7 +55,7 @@ namespace phase_shifter::input {
switch(e.id) {
case "aim"_strid:
for(auto&& [_, m] : _ecs.list<Input_controller_comp, gameplay::Movement_comp>()) {
m.aim = {-e.abs.x, -e.abs.y};
m.aim = {e.abs.x, e.abs.y};
}
break;
}
......@@ -78,13 +78,13 @@ namespace phase_shifter::input {
auto aim = glm::vec2{0.f, 0.f};
if(_key_move_up)
aim.y += 1.f;
if(_key_move_down)
aim.y -= 1.f;
if(_key_move_down)
aim.y += 1.f;
if(_key_move_left)
aim.x += 1.f;
if(_key_move_right)
aim.x -= 1.f;
if(_key_move_right)
aim.x += 1.f;
for(auto&& [_, m] : _ecs.list<Input_controller_comp, gameplay::Movement_comp>()) {
m.aim = aim;
......
#include "level.hpp"
#include <sstream>
namespace phase_shifter::level {
Level::Level(Tileset_ptr tileset, vector_2d<char> tiles) : _tileset(tileset), _tiles(tiles) {}
} // namespace phase_shifter::level
namespace mirrage::asset {
auto Loader<phase_shifter::level::Level>::load(istream in) -> async::task<phase_shifter::level::Level>
{
std::string tileset_name;
in >> tileset_name;
in.ignore();
auto tileset = in.manager().load<phase_shifter::level::Tileset>(AID("tiles:" + tileset_name));
auto all_loaded = async::when_all(tileset.internal_task());
using Task_type = decltype(all_loaded)::result_type;
auto lines = in.lines();
phase_shifter::level::Level::vector_2d<char> tiles;
for(auto&& line : lines) {
std::vector<char> row;
for(auto&& key : line) {
row.emplace_back(key);
}
tiles.emplace_back(row);
}
return all_loaded.then(
[=](const Task_type&) mutable { return phase_shifter::level::Level(tileset, tiles); });
}
} // namespace mirrage::asset
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include <mirrage/asset/asset_manager.hpp>
namespace phase_shifter::level {
struct Tile {
std::string blueprint;
bool solid = false;
bool spawn = false;
std::string spawns;
};
sf2_structDef(Tile, blueprint, solid, spawn, spawns);
struct Tileset {
float tile_size;
std::unordered_map<std::string, Tile> tiles;
};
sf2_structDef(Tileset, tile_size, tiles);
using Tileset_ptr = mirrage::asset::Ptr<Tileset>;
class Level {
friend class Level_system;
public:
template <typename T>
using vector_2d = std::vector<std::vector<T>>;
Level(Tileset_ptr tileset, vector_2d<char> tiles);
private:
Tileset_ptr _tileset;
vector_2d<char> _tiles;
};
using Level_ptr = mirrage::asset::Ptr<Level>;
} // namespace phase_shifter::level
namespace mirrage::asset {
template <>
struct Loader<phase_shifter::level::Level> {
public:
auto load(istream in) -> async::task<phase_shifter::level::Level>;
void save(ostream, const phase_shifter::level::Level&)
{
MIRRAGE_FAIL("Save of levels is not supported!");
}
};
} // namespace mirrage::asset
#include "level_system.hpp"
#include "../gameplay/viewtarget_comp.hpp"
#include <mirrage/ecs/components/transform_comp.hpp>
#include <mirrage/ecs/ecs.hpp>
namespace phase_shifter::level {
using namespace mirrage;
using namespace mirrage::ecs::components;
Level_system::Level_system(mirrage::ecs::Entity_manager& entities, mirrage::asset::Asset_manager& assets)
: _entities(entities), _assets(assets)
{
_spawners.emplace("p", [&](const Tile& tile, const glm::vec3& position) {
mirrage::ecs::Entity_facet player =
_entities.entity_builder(tile.spawns).position(position).create();
auto playerhandle = player.handle();
auto cam_elevation = 0.3f * glm::pi<float>();
auto cam_azimuth = 0.0f;
auto cam_dir = glm::quat(glm::vec3(
(cam_elevation - 2.f) * glm::pi<float>() / 2.f, glm::pi<float>() * cam_azimuth, 0.f));
_entities.entity_builder("camera")
.rotation(cam_dir)
.position(glm::rotate(cam_dir, glm::vec3(0, 0, -1)) * 8.f + position)
.post_create([=](ecs::Entity_facet entity) {
entity.process<Transform_comp>([&](auto& transform) {
transform.position = transform.direction() * -10.f + position;
transform.look_at(position);
});
entity.process([=](gameplay::Viewtarget_comp& viewtarget) {
viewtarget.target = playerhandle;
});
})
.create();
});
}
auto Level_system::load(const std::string& name) -> void
{
_current_level = _assets.load<Level>(mirrage::asset::AID("level:" + name));
auto& level = _current_level.get_blocking();
auto& tiles = level._tileset->tiles;
auto offset = level._tileset->tile_size;
glm::vec3 position{0.f};
for(auto&& row : level._tiles) {
position.x = 0.f;
for(auto&& tile_key : row) {
std::string key(1, tile_key);
if(auto tile_it = tiles.find(key); tile_it != tiles.end()) {
auto& tile = tile_it->second;
_entities.entity_builder(tile.blueprint).position(position).create();
if(tile.spawn) {
_spawn_function(key)(tile, position);
}
position.x += offset;
}
}
position.z += offset;
}
}
auto Level_system::_spawn_function(const std::string& key)
-> std::function<auto(const Tile&, const glm::vec3&)->void>
{
if(auto spawner_it = _spawners.find(key); spawner_it != _spawners.end()) {
return spawner_it->second;
}
return [&](const Tile& tile, const glm::vec3& position) {
_entities.entity_builder(tile.spawns).position(position).create();
};
}
} // namespace phase_shifter::level
#pragma once
#include "level.hpp"
#include <functional>
#include <unordered_map>
#include <glm/vec3.hpp>
namespace mirrage::ecs {
class Entity_manager;
}
namespace mirrage::asset {
class Asset_manager;
}
namespace phase_shifter::level {
class Level_system {
public:
Level_system(mirrage::ecs::Entity_manager& entities, mirrage::asset::Asset_manager& assets);
auto load(const std::string& name) -> void;
private:
auto _spawn_function(const std::string& key)
-> std::function<auto(const Tile&, const glm::vec3&)->void>;
mirrage::ecs::Entity_manager& _entities;
mirrage::asset::Asset_manager& _assets;
Level_ptr _current_level;
std::unordered_map<std::string, std::function<auto(const Tile&, const glm::vec3&)->void>> _spawners;
};
} // namespace phase_shifter::level
......@@ -7,6 +7,7 @@
#include "gameplay/movement_system.hpp"
#include "helper/attachment_system.hpp"
#include "input/input_system.hpp"
#include "level/level_system.hpp"
#include "ui/hud_system.hpp"
#include <context.hpp>
......@@ -32,6 +33,7 @@ namespace phase_shifter {
, _input_system(std::make_unique<input::Input_system>(engine.bus(), _entities))
, _attachment_system(std::make_unique<helper::Attachment_system>(_entities))
, _hud_system(std::make_unique<ui::Hud_system>(engine.gui(), _entities, *_beat_system))
, _level_system(std::make_unique<level::Level_system>(_entities, engine.assets()))
, _camera_system(std::make_unique<gameplay::Camera_system>(_entities))
{
_entities.register_component_type<ecs::components::Transform_comp>();
......@@ -77,11 +79,6 @@ namespace phase_shifter {
// TODO: replace with level-loading / generation code
auto cam_elevation = 0.3f * glm::pi<float>();
auto cam_azimuth = 0.0f;
auto cam_dir = glm::quat(glm::vec3(
(cam_elevation - 2.f) * glm::pi<float>() / 2.f, glm::pi<float>() * cam_azimuth, 0.f));
auto sun_elevation = 0.05f * glm::pi<float>();
auto sun_azimuth = 0.7f;
auto sun_dir = glm::quat(glm::vec3(
......@@ -91,32 +88,6 @@ namespace phase_shifter {
.rotation(sun_dir)
.position(glm::rotate(sun_dir, glm::vec3(0, 0, 1)) * 40.f)
.create();
mirrage::ecs::Entity_facet player = entities().entity_builder("player").position({0, 1, 0}).create();
auto playerhandle = player.handle();
entities()
.entity_builder("camera")
.rotation(cam_dir)
.position(glm::rotate(cam_dir, glm::vec3(0, 0, -1)) * 8.f)
.post_create([=](ecs::Entity_facet entity) {
entity.process<Transform_comp>([&](auto& transform) {
transform.position = transform.direction() * -10.f;
transform.look_at({0, 0, 0});
});
entity.process(
[=](gameplay::Viewtarget_comp& viewtarget) { viewtarget.target = playerhandle; });
})
.create();
entities()
.entity_builder("cube")
.position({0, 0, 0})
.post_create([=](ecs::Entity_facet entity) {
entity.process<Transform_comp>([&](auto& transform) {
transform.scale = glm::vec3{10.f, 0.01f, 10.f};
});
})
.create();
}
Meta_system::~Meta_system()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment