This commit is contained in:
aozhiwei 2019-06-11 17:55:16 +08:00
parent 570b3e3b3e
commit e288dc09b5
2 changed files with 79 additions and 77 deletions

View File

@ -8,93 +8,65 @@
#include "collider.h" #include "collider.h"
#include "collision.h" #include "collision.h"
#include "app.h" #include "app.h"
#include "obstacle.h"
void MovementComponent::RayDetection() void MovementComponent::RayDetection()
{ {
App::Instance()->perf.ray_times++;
long long tick = a8::XGetTickCount();
Clear(); Clear();
App::Instance()->perf.ray_times++;
long long tick = a8::XGetTickCount();
Vector2D left_p0;
Vector2D left_p1;
Vector2D right_p0;
Vector2D right_p1;
if (owner->entity_type == ET_Bullet) { if (owner->entity_type == ET_Bullet) {
Bullet* bullet = (Bullet*)owner; Bullet* bullet = (Bullet*)owner;
Init(bullet->pos, bullet->born_dir, bullet->gun_meta->i->bullet_rad(), MAP_CELL_WIDTH - MAP_GRID_WIDTH * 3,
left_p0, left_p1, right_p0, right_p1);
} else if (owner->entity_type == ET_Player) { } else if (owner->entity_type == ET_Player) {
Human* hum = (Human*)owner; Human* hum = (Human*)owner;
start_point = hum->pos; Init(hum->pos, hum->move_dir, hum->meta->i->radius(), MAP_CELL_WIDTH - MAP_GRID_WIDTH * 3,
target_point = hum->pos + hum->move_dir * (MAP_CELL_WIDTH - MAP_GRID_WIDTH); left_p0, left_p1, right_p0, right_p1);
target_distance = (target_point - start_point).Norm(); }
{ int count = 0;
long long tick1 = a8::XGetTickCount(); for (auto& grid : owner->grid_list) {
Vector2D left_dir = hum->move_dir; for (Entity* entity : grid->entity_list) {
left_dir.Rotate(-90); count++;
left_dir.Normalize(); switch (entity->entity_type) {
Vector2D right_dir = hum->move_dir; case ET_Building:
right_dir.Rotate(+90); case ET_Obstacle:
right_dir.Normalize(); {
App::Instance()->perf.params[1] += a8::XGetTickCount() - tick1; if (entity->entity_type == ET_Obstacle && ((Obstacle*)entity)->is_door) {
//门直接加入检查列表
Vector2D left_p0 = hum->pos + left_dir * (hum->meta->i->radius() + 1); detection_objects.insert(entity);
Vector2D left_p1 = left_p0 + hum->move_dir * (MAP_CELL_WIDTH - MAP_GRID_WIDTH * 3); } else {
Vector2D right_p0 = hum->pos + right_dir * (hum->meta->i->radius() + 1); AabbCollider aabb_box;
Vector2D right_p1 = right_p0 + hum->move_dir * (MAP_CELL_WIDTH - MAP_GRID_WIDTH * 3); entity->GetAabbBox(aabb_box);
if (IntersectSegmentAabb(left_p0, left_p1,
int count = 0; aabb_box.owner->pos + aabb_box._min,
for (auto& grid : hum->grid_list) { aabb_box.owner->pos + aabb_box._max) ||
for (Entity* entity : grid->entity_list) { IntersectSegmentAabb(right_p0, right_p1,
count++; aabb_box.owner->pos + aabb_box._min,
switch (entity->entity_type) { aabb_box.owner->pos + aabb_box._max)
case ET_Obstacle: ) {
{ detection_objects.insert(entity);
if (
(hum->last_collision_door == nullptr || hum->last_collision_door != entity)
){
long long tick2 = a8::XGetTickCount();
AabbCollider aabb_box;
entity->GetAabbBox(aabb_box);
if (IntersectSegmentAabb(left_p0, left_p1,
aabb_box.owner->pos + aabb_box._min,
aabb_box.owner->pos + aabb_box._max) ||
IntersectSegmentAabb(right_p0, right_p1,
aabb_box.owner->pos + aabb_box._min,
aabb_box.owner->pos + aabb_box._max)
) {
detection_objects.insert(entity);
}
App::Instance()->perf.params[3] += a8::XGetTickCount() - tick2;
App::Instance()->perf.params[4]++;
}
} }
break;
case ET_Building:
{
long long tick2 = a8::XGetTickCount();
AabbCollider aabb_box;
entity->GetAabbBox(aabb_box);
if (IntersectSegmentAabb(left_p0, left_p1,
aabb_box.owner->pos + aabb_box._min,
aabb_box.owner->pos + aabb_box._max) ||
IntersectSegmentAabb(right_p0, right_p1,
aabb_box.owner->pos + aabb_box._min,
aabb_box.owner->pos + aabb_box._max)
) {
detection_objects.insert(entity);
}
App::Instance()->perf.params[3] += a8::XGetTickCount() - tick2;
App::Instance()->perf.params[4]++;
}
break;
default:
{
}
break;
} }
App::Instance()->perf.params[4]++;
} }
}//end for break;
if (App::Instance()->perf.params[2] < count) { default:
App::Instance()->perf.params[2] = count; {
}
break;
} }
if (App::Instance()->perf.params[6] < detection_objects.size()) { }//end for entity_list
App::Instance()->perf.params[6] = detection_objects.size(); }//end for grid
} if (App::Instance()->perf.params[2] < count) {
} App::Instance()->perf.params[2] = count;
}
if (App::Instance()->perf.params[6] < detection_objects.size()) {
App::Instance()->perf.params[6] = detection_objects.size();
} }
App::Instance()->perf.ray_time += a8::XGetTickCount() - tick; App::Instance()->perf.ray_time += a8::XGetTickCount() - tick;
} }
@ -117,7 +89,7 @@ void MovementComponent::GetCollisionObjects(std::set<Entity*>& objects)
case ET_Obstacle: case ET_Obstacle:
case ET_Building: case ET_Building:
{ {
if (bullet->TestCollision(entity)) { if (!entity->dead && bullet->TestCollision(entity)) {
objects.insert(entity); objects.insert(entity);
} }
} }
@ -135,12 +107,16 @@ bool MovementComponent::TestCollision()
{ {
if (owner->entity_type == ET_Bullet) { if (owner->entity_type == ET_Bullet) {
Bullet* bullet = (Bullet*)owner; Bullet* bullet = (Bullet*)owner;
if (bullet->room->OverBorder(bullet->pos, bullet->gun_meta->i->bullet_rad())){
return true;
}
for (Entity* entity : detection_objects) { for (Entity* entity : detection_objects) {
switch (entity->entity_type) { switch (entity->entity_type) {
case ET_Obstacle: case ET_Obstacle:
case ET_Building: case ET_Building:
{ {
if (bullet->TestCollision(entity)) { if (!entity->dead && bullet->TestCollision(entity)) {
return true; return true;
} }
} }
@ -181,3 +157,24 @@ bool MovementComponent::TestCollision()
} }
return false; return false;
} }
void MovementComponent::Init(Vector2D pos, Vector2D dir, float rad, float distance,
Vector2D& left_p0, Vector2D& left_p1, Vector2D& right_p0, Vector2D& right_p1)
{
start_point = pos;
target_point = pos + dir * (MAP_CELL_WIDTH - MAP_GRID_WIDTH);
target_distance = (target_point - start_point).Norm();
Vector2D left_dir = dir;
left_dir.Rotate(-90);
left_dir.Normalize();
Vector2D right_dir = dir;
right_dir.Rotate(+90);
right_dir.Normalize();
left_p0 = pos + left_dir * (rad + 1);
left_p1 = left_p0 + dir * distance;
right_p0 = pos + right_dir * (rad + 1);
right_p1 = right_p0 + dir * distance;
}

View File

@ -15,4 +15,9 @@ class MovementComponent
void Clear(); void Clear();
void GetCollisionObjects(std::set<Entity*>& objects); void GetCollisionObjects(std::set<Entity*>& objects);
bool TestCollision(); bool TestCollision();
private:
void Init(Vector2D pos, Vector2D dir, float rad, float distance,
Vector2D& left_p0, Vector2D& left_p1, Vector2D& right_p0, Vector2D& right_p1);
}; };