A bit of optimization to keep from generating the sorted sprite list over and over. Also tried to solve the problem of tombstone covering everything but no luck.

master
Zed A. Shaw 20 hours ago
parent 077f0e84ea
commit 9bf6926dc3
  1. 1
      constants.hpp
  2. 2
      gui/fsm.cpp
  3. 40
      gui/main_ui.cpp
  4. 2
      gui/main_ui.hpp
  5. 6
      raycaster.cpp
  6. 1
      raycaster.hpp
  7. 11
      spatialmap.cpp
  8. 2
      spatialmap.hpp
  9. 3
      tests/spatialmap.cpp

@ -18,6 +18,7 @@ constexpr const float AIMED_AT_BRIGHTNESS=0.2f;
constexpr const int MAP_TILE_DIM=64;
constexpr const int ICONGEN_MAP_TILE_DIM=64;
constexpr const int PLAYER_SPRITE_DIR_CORRECTION=270;
constexpr const int RENDER_DISTANCE=500;
constexpr const int BOSS_VIEW_WIDTH=1080;
constexpr const int BOSS_VIEW_HEIGHT=SCREEN_HEIGHT;

@ -458,7 +458,7 @@ namespace gui {
break;
case eGUI::ENTITY_SPAWN: {
auto& sprite = world.get<components::Sprite>(entity);
$main_ui.$rayview.update_sprite(entity, sprite);
$main_ui.$rayview->update_sprite(entity, sprite);
$main_ui.dirty();
run_systems();
} break;

@ -9,7 +9,7 @@ namespace gui {
MainUI::MainUI(sf::RenderWindow& window) :
$window(window),
$rayview(RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT)
$rayview(std::make_shared<Raycaster>(RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT))
{
$window.setVerticalSyncEnabled(VSYNC);
$window.setFramerateLimit(FRAME_LIMIT);
@ -23,25 +23,25 @@ namespace gui {
auto& player_position = $level.world->get<Position>($level.player);
auto player = player_position.location;
$rayview.init_shaders();
$rayview.set_position(RAY_VIEW_X, RAY_VIEW_Y);
$rayview.position_camera(player.x + 0.5, player.y + 0.5);
$rayview->init_shaders();
$rayview->set_position(RAY_VIEW_X, RAY_VIEW_Y);
$rayview->position_camera(player.x + 0.5, player.y + 0.5);
$overlay_ui.init();
}
DinkyECS::Entity MainUI::camera_aim() {
// what happens if there's two things at that spot
if($level.collision->something_there($rayview.aiming_at)) {
return $level.collision->get($rayview.aiming_at);
if($level.collision->something_there($rayview->aiming_at)) {
return $level.collision->get($rayview->aiming_at);
} else {
return 0;
}
}
void MainUI::render() {
if($needs_render) $rayview.render();
$rayview.draw($window);
if($needs_render) $rayview->render();
$rayview->draw($window);
$overlay_ui.render($window);
}
@ -51,9 +51,9 @@ namespace gui {
}
std::optional<Point> MainUI::play_rotate() {
if($rayview.play_rotate()) {
if($rayview->play_rotate()) {
$needs_render = false;
return std::make_optional<Point>($rayview.aiming_at);
return std::make_optional<Point>($rayview->aiming_at);
} else {
$needs_render = true;
return std::nullopt;
@ -61,11 +61,11 @@ namespace gui {
}
std::optional<components::Position> MainUI::play_move() {
if($rayview.play_move()) {
if($rayview->play_move()) {
$needs_render = false;
return std::make_optional<Position>(
$rayview.camera_target(),
$rayview.aiming_at);
$rayview->camera_target(),
$rayview->aiming_at);
} else {
$needs_render = true;
return std::nullopt;
@ -76,15 +76,15 @@ namespace gui {
// -1 is left, 1 is right
int extra = (amount == 0.5) * dir;
$compass_dir = ($compass_dir + dir + extra) % COMPASS.size();
$rayview.plan_rotate(dir, amount);
$rayview->plan_rotate(dir, amount);
}
Point MainUI::plan_move(int dir, bool strafe) {
return $rayview.plan_move(dir, strafe);
return $rayview->plan_move(dir, strafe);
}
void MainUI::abort_plan() {
$rayview.abort_plan();
$rayview->abort_plan();
}
void MainUI::dead_entity(DinkyECS::Entity entity) {
@ -92,7 +92,7 @@ namespace gui {
// (see System::distribute_loot) then this can be fixed or improved
if($level.world->has<components::Sprite>(entity)) {
auto &sprite = $level.world->get<components::Sprite>(entity);
$rayview.update_sprite(entity, sprite);
$rayview->update_sprite(entity, sprite);
}
}
@ -101,10 +101,10 @@ namespace gui {
auto& player_position = $level.world->get<Position>($level.player);
auto player = player_position.location;
$rayview.update_level($level);
$rayview.position_camera(player.x + 0.5, player.y + 0.5);
$rayview->update_level($level);
$rayview->position_camera(player.x + 0.5, player.y + 0.5);
player_position.aiming_at = $rayview.aiming_at;
player_position.aiming_at = $rayview->aiming_at;
$compass_dir = 0;

@ -19,7 +19,7 @@ namespace gui {
sf::RenderWindow& $window;
GameLevel $level;
OverlayUI $overlay_ui;
Raycaster $rayview;
std::shared_ptr<Raycaster> $rayview;
MainUI(sf::RenderWindow& window);

@ -101,12 +101,11 @@ void Raycaster::apply_sprite_effect(shared_ptr<sf::Shader> effect, float width,
void Raycaster::sprite_casting(sf::RenderTarget &target) {
auto& lights = $level.lights->lighting();
$level.collision->distance_sorted($sprite_order, {(size_t)$pos_x, (size_t)$pos_y}, RENDER_DISTANCE);
// sort sprites from far to close
auto sprite_order = $level.collision->distance_sorted({(size_t)$pos_x, (size_t)$pos_y}, 500);
// after sorting the sprites, do the projection
for(auto& rec : sprite_order) {
for(auto& rec : $sprite_order) {
if(!$sprites.contains(rec.entity)) continue;
auto& sprite_texture = $sprites.at(rec.entity);
@ -425,6 +424,7 @@ void Raycaster::update_sprite(DinkyECS::Entity ent, components::Sprite& sprite)
void Raycaster::update_level(GameLevel level) {
$sprites.clear();
$sprite_order.clear();
$level = level;

@ -36,6 +36,7 @@ struct Raycaster {
int $screen_pos_x = RAY_VIEW_X;
int $screen_pos_y = RAY_VIEW_Y;
std::unordered_map<DinkyECS::Entity, textures::SpriteTexture> $sprites;
SortedEntities $sprite_order;
GameLevel $level;
Matrix $tiles;

@ -98,10 +98,13 @@ inline void update_sorted(SortedEntities& sprite_distance, PointEntityMap& table
for(const auto &rec : table) {
Point sprite = rec.first;
int inside = (from.x - sprite.x) * (from.x - sprite.x) +
(from.y - sprite.y) * (from.y - sprite.y);
if(sprite == seen && from != sprite) {
if(from == sprite || rec.second.collision) {
wiggle = 0.0f;
} else if(sprite == seen) {
wiggle += 0.02f;
} else {
wiggle = 0.0f;
@ -114,14 +117,12 @@ inline void update_sorted(SortedEntities& sprite_distance, PointEntityMap& table
}
}
SortedEntities SpatialMap::distance_sorted(Point from, int max_dist) {
SortedEntities sprite_distance;
void SpatialMap::distance_sorted(SortedEntities& sprite_distance, Point from, int max_dist) {
sprite_distance.clear();
update_sorted(sprite_distance, $collision, from, max_dist);
std::sort(sprite_distance.begin(), sprite_distance.end(), [](auto &a, auto &b) {
return a.dist_square > b.dist_square;
});
return sprite_distance;
}

@ -40,6 +40,6 @@ class SpatialMap {
DinkyECS::Entity get(Point at) const;
FoundEntities neighbors(Point position, bool diag=false) const;
SortedEntities distance_sorted(Point from, int max_distance);
void distance_sorted(SortedEntities& sorted_sprites, Point from, int max_distance);
size_t size() { return $collision.size(); }
};

@ -201,7 +201,8 @@ TEST_CASE("SpatialMap::distance_sorted", "[spatialmap]") {
map.insert({4,4}, enemy1, true);
map.insert({3, 3}, item, false);
auto result = map.distance_sorted({1, 1}, 100);
SortedEntities result;
map.distance_sorted(result, {1, 1}, 100);
REQUIRE(result.size() == 3);
REQUIRE(result[0].entity == enemy1);
REQUIRE(result[1].entity == item);

Loading…
Cancel
Save