Commit b3ab6f84 authored by Tim Scheiber's avatar Tim Scheiber
Browse files

still broken collision

parent f10aebf5
Pipeline #3332 failed with stage
in 2 minutes and 55 seconds
......@@ -4,13 +4,13 @@
#include "combat_system.hpp"
#include "movement_comp.hpp"
#include "rigid_body_comp.hpp"
#include "player_comp.hpp"
#include "rigid_body_comp.hpp"
#include <mirrage/ecs/components/transform_comp.hpp>
namespace phase_shifter::gameplay {
using namespace mirrage::ecs;
Enemy_system::Enemy_system(mirrage::util::Message_bus& bus,
......@@ -35,13 +35,15 @@ namespace phase_shifter::gameplay {
do_bullet_hit_detection();
}
void Enemy_system::do_movement(Beat_state& beat) {
void Enemy_system::do_movement(Beat_state& beat)
{
do_fixed_path_movement(beat);
do_cont_path_movement(beat);
do_hunting_movement(beat);
}
void Enemy_system::do_fixed_path_movement(Beat_state& beat) {
void Enemy_system::do_fixed_path_movement(Beat_state& beat)
{
for(auto&& [movement, fixed_path] : _entity_manager.list<Movement_comp, Fixed_path_comp>()) {
if(beat.beat) {
if(fixed_path.wait_beats == 0 && !movement.move) {
......@@ -60,7 +62,8 @@ namespace phase_shifter::gameplay {
}
}
void Enemy_system::do_cont_path_movement(Beat_state& beat) {
void Enemy_system::do_cont_path_movement(Beat_state& beat)
{
for(auto&& [movement, cont_path] : _entity_manager.list<Movement_comp, Continuous_path_comp>()) {
if(beat.beat) {
if(cont_path.wait_beats == 0 && !movement.move) {
......@@ -76,7 +79,8 @@ namespace phase_shifter::gameplay {
}
}
void Enemy_system::do_hunting_movement(Beat_state& beat) {
void Enemy_system::do_hunting_movement(Beat_state& beat)
{
for(auto&& [movement, follow_target, transform] :
_entity_manager.list<Movement_comp, Follow_target_comp, components::Transform_comp>()) {
if(beat.beat) {
......@@ -102,7 +106,8 @@ namespace phase_shifter::gameplay {
}
}
void Enemy_system::do_shooting(Beat_state& beat) {
void Enemy_system::do_shooting(Beat_state& beat)
{
for(auto&& [shooting, transform] :
_entity_manager.list<Shooting_comp, components::Transform_comp>()) {
auto my_position = transform.position;
......@@ -121,7 +126,7 @@ namespace phase_shifter::gameplay {
}
}
glm::vec2 t_direction(closest_target_pos.x - my_position.x, closest_target_pos.z - my_position.z);
glm::vec2 t_direction{closest_target_pos.x - my_position.x, closest_target_pos.z - my_position.z};
shooting.target_direction =
std::acos(-t_direction.y / glm::length(t_direction)) * 180.f / mirrage::util::PI;
if(t_direction.x < 0) {
......@@ -184,17 +189,85 @@ namespace phase_shifter::gameplay {
void Enemy_system::do_bullet_hit_detection()
{
for(auto&& [bullet_handle, bullet, bullet_transform, bullet_body] :
_entity_manager.list<Entity_handle, Bullet_comp, components::Transform_comp, Rigid_body_comp>()) {
for(auto&& [player_handle, player, player_transform, player_body] :
_entity_manager.list<Entity_handle, Player_comp, components::Transform_comp, Rigid_body_comp>()) {
for(auto&& [bullet_handle, bullet, bullet_transform, bullet_body, bullet_movement] :
_entity_manager.list<Entity_handle,
Bullet_comp,
components::Transform_comp,
Rigid_body_comp,
Movement_comp>()) {
for(auto&& [player_handle, player, player_transform, player_body, player_movement] :
_entity_manager.list<Entity_handle,
Player_comp,
components::Transform_comp,
Rigid_body_comp,
Movement_comp>()) {
glm::vec2 bullet_pos{bullet_transform.position.x, bullet_transform.position.z};
glm::vec2 last_bullet_pos = bullet_movement.last_position;
glm::vec2 player_pos{player_transform.position.x, player_transform.position.z};
if (glm::length(player_pos - bullet_pos) < bullet_body.radius + player_body.radius) {
glm::vec2 last_player_pos = player_movement.last_position;
if (!bullet_movement.moved) {
last_bullet_pos = bullet_pos;
}
if (!player_movement.moved) {
last_player_pos = player_pos;
}
if(intersect(Stadium{last_bullet_pos, bullet_pos, bullet_body.radius}, Stadium{last_player_pos, player_pos, player_body.radius})) {
_entity_manager.erase(bullet_handle);
_bus.send<Damaged_msg>(player_handle);
}
}
}
}
}
\ No newline at end of file
bool Enemy_system::intersect(Stadium& stad1, Stadium& stad2)
{
glm::vec2 direction1 = stad1.point2 - stad1.point1;
glm::vec2 direction2 = stad2.point2 - stad2.point1;
glm::vec2 eliminator{-direction1.y, direction1.x};
float temp = glm::dot(direction2, eliminator);
if(temp != 0) {
float lambda = glm::dot((stad1.point1 - stad2.point1), eliminator) / temp;
if (lambda >= 0 && lambda <= 1) {
return true;
}
}
float comb_radius = stad1.radius + stad2.radius;
float length2 = glm::length2(direction1);
if (length2 <= 0.001f) {
if (glm::distance(stad2.point1, stad1.point1) < comb_radius || glm::distance(stad2.point2, stad1.point1) < comb_radius) {
return true;
}
}
float lambda = std::clamp(dot(stad2.point1 - stad1.point1, direction1), 0.f, 1.f);
if(glm::distance(stad2.point1, stad1.point1 + lambda * direction1) < comb_radius) {
return true;
}
lambda = std::clamp(dot(stad2.point2 - stad1.point1, direction1), 0.f, 1.f);
if(glm::distance(stad2.point2, stad1.point1 + lambda * direction1) < comb_radius) {
return true;
}
length2 = glm::length2(direction2);
if(length2 <= 0.001f) {
if(glm::distance(stad1.point1, stad2.point1) < comb_radius || glm::distance(stad1.point2, stad2.point1) < comb_radius) {
return true;
}
}
lambda = std::clamp(dot(stad1.point1 - stad2.point1, direction2), 0.f, 1.f);
if(glm::distance(stad1.point1, stad2.point1 + lambda * direction2) < comb_radius) {
return true;
}
lambda = std::clamp(dot(stad1.point2 - stad2.point1, direction2), 0.f, 1.f);
if(glm::distance(stad1.point2, stad2.point1 + lambda * direction2) < comb_radius) {
return true;
}
return false;
}
float Enemy_system::dot(glm::vec2& a, glm::vec2& b) { return a.x * b.x + a.y * b.y; }
} // namespace phase_shifter::gameplay
\ No newline at end of file
......@@ -14,6 +14,12 @@
namespace phase_shifter::gameplay {
struct Stadium {
glm::vec2 point1;
glm::vec2 point2;
float radius;
};
class Enemy_system {
public:
Enemy_system(mirrage::util::Message_bus& bus,
......@@ -32,5 +38,8 @@ namespace phase_shifter::gameplay {
void do_hunting_movement(Beat_state& beat);
void do_shooting(Beat_state& beat);
void do_bullet_hit_detection();
bool intersect(Stadium& stad1, Stadium& stad2);
float dot(glm::vec2& a, glm::vec2& b);
};
}
\ No newline at end of file
......@@ -24,6 +24,8 @@ namespace phase_shifter::gameplay {
float step_time = 0;
glm::vec2 last_step;
glm::vec2 last_aim;
glm::vec2 last_position; // position of the entity during the last frame
bool moved = false;
};
sf2_structDef(Movement_comp,
......
......@@ -45,6 +45,10 @@ namespace phase_shifter::gameplay {
auto beat = _beat_system.beat_state();
for(auto&& [entity, transform, move] : _ecs.list<Entity_facet, Transform_comp, Movement_comp>()) {
//save last position
move.last_position = {transform.position.x, transform.position.z};
move.moved = true;
if(beat.beat) {
move.beats_since_move++;
}
......@@ -104,6 +108,7 @@ namespace phase_shifter::gameplay {
look_dir = offset;
}
transform.position.x = pos.x + offset.x;
transform.position.z = pos.y + offset.y;
}
......
......@@ -93,7 +93,7 @@ namespace phase_shifter {
.entity_builder("basic_enemy")
.position({20, 0, 15})
.post_create([=](auto entity) {
entity.process([&](gameplay::Fixed_path_comp& fixed_path) { fixed_path.update_path({180}); });
entity.process([&](gameplay::Fixed_path_comp& fixed_path) { fixed_path.update_path({}); });
entity.process([&](gameplay::Shooting_comp& shooting) {
shooting.set_patterns({gameplay::Bulletpattern({{0, 0}})});
});
......
......@@ -71,7 +71,6 @@ namespace phase_shifter::util {
return {false, {}};
}
auto intersect(const Aabb& aabb, const Circle& circle) -> std::pair<bool, Contact>
{
const auto n = aabb.origin - circle.origin;
......
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