Now the spatialmap determines the 'wiggle factor' when there's multiple entities in a cell, which staggers them visually. Closes #78.
This commit is contained in:
parent
694ee210d6
commit
9c02fb846b
4 changed files with 35 additions and 21 deletions
|
@ -107,19 +107,19 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
|
|
||||||
// after sorting the sprites, do the projection
|
// after sorting the sprites, do the projection
|
||||||
for(auto& rec : sprite_order) {
|
for(auto& rec : sprite_order) {
|
||||||
if(!$sprites.contains(rec.second)) continue;
|
if(!$sprites.contains(rec.entity)) continue;
|
||||||
|
|
||||||
auto& sprite_texture = $sprites.at(rec.second);
|
auto& sprite_texture = $sprites.at(rec.entity);
|
||||||
|
|
||||||
int texture_width = (float)sprite_texture.frame_size.x;
|
int texture_width = (float)sprite_texture.frame_size.x;
|
||||||
int texture_height =(float)sprite_texture.frame_size.y;
|
int texture_height =(float)sprite_texture.frame_size.y;
|
||||||
int half_height = texture_height / 2;
|
int half_height = texture_height / 2;
|
||||||
|
|
||||||
auto& sf_sprite = sprite_texture.sprite;
|
auto& sf_sprite = sprite_texture.sprite;
|
||||||
auto sprite_pos = $level.world->get<components::Position>(rec.second);
|
auto sprite_pos = $level.world->get<components::Position>(rec.entity);
|
||||||
|
|
||||||
double sprite_x = double(sprite_pos.location.x) - $pos_x + 0.5;
|
double sprite_x = double(sprite_pos.location.x) - rec.wiggle - $pos_x + 0.5;
|
||||||
double sprite_y = double(sprite_pos.location.y) - $pos_y + 0.5;
|
double sprite_y = double(sprite_pos.location.y) - rec.wiggle - $pos_y + 0.5;
|
||||||
|
|
||||||
double inv_det = 1.0 / ($plane_x * $dir_y - $dir_x * $plane_y); // required for correct matrix multiplication
|
double inv_det = 1.0 / ($plane_x * $dir_y - $dir_x * $plane_y); // required for correct matrix multiplication
|
||||||
|
|
||||||
|
@ -185,8 +185,8 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
sf::Vector2f position{x + origin.x * scale.x, y + origin.y * scale.y};
|
sf::Vector2f position{x + origin.x * scale.x, y + origin.y * scale.y};
|
||||||
sf::IntRect in_texture{ {tex_x, tex_y}, {tex_render_width, texture_height}};
|
sf::IntRect in_texture{ {tex_x, tex_y}, {tex_render_width, texture_height}};
|
||||||
|
|
||||||
if($level.world->has<components::Animation>(rec.second)) {
|
if($level.world->has<components::Animation>(rec.entity)) {
|
||||||
auto& animation = $level.world->get<components::Animation>(rec.second);
|
auto& animation = $level.world->get<components::Animation>(rec.entity);
|
||||||
if(animation.playing) animation.step(scale, position, in_texture);
|
if(animation.playing) animation.step(scale, position, in_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,13 +195,9 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
||||||
sf_sprite->setTextureRect(in_texture);
|
sf_sprite->setTextureRect(in_texture);
|
||||||
sf_sprite->setPosition(position);
|
sf_sprite->setPosition(position);
|
||||||
|
|
||||||
// the SpatialMap.distance_sorted only calculates the
|
|
||||||
// (x1-x2)^2 + (y1-y2)^2 portion of distance, so to get
|
|
||||||
// the actual distance we need to sqrt that.
|
|
||||||
// float level = sqrt(rec.first);
|
|
||||||
float level = lights[sprite_pos.location.y][sprite_pos.location.x] * PERCENT;
|
float level = lights[sprite_pos.location.y][sprite_pos.location.x] * PERCENT;
|
||||||
|
|
||||||
shared_ptr<sf::Shader> effect = System::sprite_effect($level, rec.second);
|
shared_ptr<sf::Shader> effect = System::sprite_effect($level, rec.entity);
|
||||||
|
|
||||||
if(effect) {
|
if(effect) {
|
||||||
apply_sprite_effect(effect, sprite_width, sprite_height);
|
apply_sprite_effect(effect, sprite_width, sprite_height);
|
||||||
|
|
|
@ -93,13 +93,23 @@ FoundEntities SpatialMap::neighbors(Point cell, bool diag) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void update_sorted(SortedEntities& sprite_distance, PointEntityMap& table, Point from, int max_dist) {
|
inline void update_sorted(SortedEntities& sprite_distance, PointEntityMap& table, Point from, int max_dist) {
|
||||||
|
Point seen{0,0};
|
||||||
|
float wiggle = 0.0f;
|
||||||
|
|
||||||
for(const auto &rec : table) {
|
for(const auto &rec : table) {
|
||||||
Point sprite = rec.first;
|
Point sprite = rec.first;
|
||||||
int inside = (from.x - sprite.x) * (from.x - sprite.x) +
|
int inside = (from.x - sprite.x) * (from.x - sprite.x) +
|
||||||
(from.y - sprite.y) * (from.y - sprite.y);
|
(from.y - sprite.y) * (from.y - sprite.y);
|
||||||
|
|
||||||
|
if(sprite == seen) {
|
||||||
|
wiggle += 0.02f;
|
||||||
|
} else {
|
||||||
|
wiggle = 0.0f;
|
||||||
|
seen = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
if(inside < max_dist) {
|
if(inside < max_dist) {
|
||||||
sprite_distance.push_back({inside, rec.second.entity});
|
sprite_distance.push_back({inside, rec.second.entity, wiggle});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +119,9 @@ SortedEntities SpatialMap::distance_sorted(Point from, int max_dist) {
|
||||||
|
|
||||||
update_sorted(sprite_distance, $collision, from, max_dist);
|
update_sorted(sprite_distance, $collision, from, max_dist);
|
||||||
|
|
||||||
std::sort(sprite_distance.begin(), sprite_distance.end(), std::greater<>());
|
std::sort(sprite_distance.begin(), sprite_distance.end(), [](auto &a, auto &b) {
|
||||||
|
return a.dist_square > b.dist_square;
|
||||||
|
});
|
||||||
|
|
||||||
return sprite_distance;
|
return sprite_distance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,16 @@ struct CollisionData {
|
||||||
bool collision = false;
|
bool collision = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EntityDistance {
|
||||||
|
int dist_square=0;
|
||||||
|
DinkyECS::Entity entity=DinkyECS::NONE;
|
||||||
|
float wiggle=0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
// Point's has is in point.hpp
|
// Point's has is in point.hpp
|
||||||
using EntityList = std::vector<DinkyECS::Entity>;
|
using EntityList = std::vector<DinkyECS::Entity>;
|
||||||
using PointEntityMap = std::unordered_multimap<Point, CollisionData>;
|
using PointEntityMap = std::unordered_multimap<Point, CollisionData>;
|
||||||
using SortedEntities = std::vector<std::pair<int, DinkyECS::Entity>>;
|
using SortedEntities = std::vector<EntityDistance>;
|
||||||
|
|
||||||
struct FoundEntities {
|
struct FoundEntities {
|
||||||
bool found;
|
bool found;
|
||||||
|
|
|
@ -203,13 +203,13 @@ TEST_CASE("SpatialMap::distance_sorted", "[spatialmap]") {
|
||||||
|
|
||||||
auto result = map.distance_sorted({1, 1}, 100);
|
auto result = map.distance_sorted({1, 1}, 100);
|
||||||
REQUIRE(result.size() == 3);
|
REQUIRE(result.size() == 3);
|
||||||
REQUIRE(result[0].second == enemy1);
|
REQUIRE(result[0].entity == enemy1);
|
||||||
REQUIRE(result[1].second == item);
|
REQUIRE(result[1].entity == item);
|
||||||
REQUIRE(result[2].second == player);
|
REQUIRE(result[2].entity == player);
|
||||||
|
|
||||||
int prev_dist = std::numeric_limits<int>::max();
|
int prev_dist = std::numeric_limits<int>::max();
|
||||||
for(auto [dist, entity] : result) {
|
for(auto rec : result) {
|
||||||
REQUIRE(dist < prev_dist);
|
REQUIRE(rec.dist_square < prev_dist);
|
||||||
prev_dist = dist;
|
prev_dist = rec.dist_square;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue