This commit is contained in:
aozhiwei 2021-07-01 17:55:30 +08:00
parent 2a688b5906
commit d7e1777e1e
7 changed files with 117 additions and 15 deletions

View File

@ -103,6 +103,7 @@ void Bullet::ProcBomb()
switch (entity->GetEntityType()) {
case ET_Obstacle:
case ET_Building:
case ET_Dummy:
{
if (TestCollision(room, entity)) {
objects.insert(entity);

View File

@ -1625,17 +1625,24 @@ void Creature::SummonObstacle(Buff* buff, int id, const a8::Vec2& pos)
}
bool Creature::CollisonDetection()
{
ColliderComponent* pickup_collider = nullptr;
return CollisonDetectionAndGetCollider(&pickup_collider);
}
bool Creature::CollisonDetectionAndGetCollider(ColliderComponent** pickup_collider)
{
bool through_wall = HasBuffEffect(kBET_ThroughWall) ||
HasBuffEffect(kBET_Fly);
AabbCollider aabb_box;
GetAabbBox(aabb_box);
return room->map_service->CollisionDetection
return room->map_service->CollisionDetectionAndGetCollider
(
room,
through_wall,
GetPos(),
&aabb_box
&aabb_box,
pickup_collider
);
}
@ -1949,18 +1956,25 @@ void Creature::SetInfiniteBulletMode()
inventory_[IS_RPG].num = FIGHTING_MODE_BULLET_NUM;
}
void Creature::FindLocationWithTarget(Entity* target)
void Creature::FindLocationWithTarget(Entity* target, ColliderComponent* target_collider)
{
a8::Vec2 old_pos = GetPos();
a8::Vec2 new_pos = GetPos();
AabbCollider a_collider;
GetAabbBox(a_collider);
AabbCollider target_collider;
target->GetAabbBox(target_collider);
{
bool ret = a_collider.CalcSafePoint(&target_collider, new_pos);
if (!ret) {
abort();
if (target_collider) {
bool ret = a_collider.CalcSafePoint(target_collider, new_pos);
if (!ret) {
abort();
}
} else {
AabbCollider aabb_collider;
target->GetAabbBox(aabb_collider);
bool ret = a_collider.CalcSafePoint(&aabb_collider, new_pos);
if (!ret) {
abort();
}
}
}
a8::Vec2 new_pos_dir = new_pos - old_pos;
@ -2014,16 +2028,20 @@ void Creature::FindLocationWithTarget(Entity* target)
void Creature::FindLocation()
{
Entity* target = nullptr;
ColliderComponent* target_collider = nullptr;
TraverseAllLayerEntityList
(
[this, &target] (Entity* entity, bool& stop)
[this, &target, &target_collider] (Entity* entity, bool& stop)
{
ColliderComponent* collider = nullptr;
switch (entity->GetEntityType()) {
case ET_Obstacle:
{
if (!target) {
if (TestCollision(room, entity)) {
collider = TestCollisionAndGetCollider(room, entity);
if (collider) {
target = entity;
target_collider = collider;
}
}
}
@ -2033,15 +2051,23 @@ void Creature::FindLocation()
if (!target || !target->IsEntityType(ET_Building)) {
AabbCollider aabb_box;
entity->GetAabbBox(aabb_box);
if (TestCollision(room, &aabb_box)) {
collider = TestCollisionAndGetCollider(room, &aabb_box);
if (collider) {
target = entity;
target_collider = nullptr;
}
}
}
break;
case ET_Dummy:
{
if (!target) {
collider = TestCollisionAndGetCollider(room, entity);
if (collider) {
target = entity;
target_collider = collider;
}
}
}
break;
default:
@ -2051,7 +2077,7 @@ void Creature::FindLocation()
}
});
if (target) {
FindLocationWithTarget(target);
FindLocationWithTarget(target, target_collider);
}
}
@ -2128,6 +2154,17 @@ bool Creature::CheckCollision()
}
}
break;
case ET_Dummy:
{
if (
(collider->type == CT_Aabb && aabb_box.Intersect(collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect(collider))
) {
Global::last_collider = collider;
return true;
}
}
break;
default:
{
}

View File

@ -170,6 +170,7 @@ class Creature : public MoveableEntity
void CheckSpecObject();
bool CollisonDetection();
bool CollisonDetectionAndGetCollider(ColliderComponent** pickup_collider);
void SummonObstacle(Buff* buff, int id, const a8::Vec2& pos);
void SummonHero(Buff* buff, const a8::Vec2& pos, const a8::Vec2& dir);
void FillSkillCasterState(SkillCasterState* caster_state);
@ -192,7 +193,7 @@ class Creature : public MoveableEntity
bool TryMove(const a8::Vec2& target_pos, a8::Vec2& out_pos);
void SetInfiniteBulletMode();
void FindLocation();
void FindLocationWithTarget(Entity* target);
void FindLocationWithTarget(Entity* target, ColliderComponent* target_collider);
Entity* GetLastCollisionDoor() { return last_collision_door_; }
void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; }
bool CheckCollision();

View File

@ -53,7 +53,25 @@ bool Entity::TestCollision(Room* room, Entity* b)
return false;
}
bool Entity::TestCollision(Room* room,ColliderComponent* b)
ColliderComponent* Entity::TestCollisionAndGetCollider(Room* room, Entity* b)
{
PerfMonitor::Instance()->test_times++;
if (b->IsDead(room)) {
return nullptr;
}
OnPreCollision(room);
b->OnPreCollision(room);
for (auto& a_collider : colliders_) {
for (auto& b_collider : b->colliders_) {
if (a_collider->Intersect(b_collider)) {
return b_collider;
}
}
}
return nullptr;
}
bool Entity::TestCollision(Room* room, ColliderComponent* b)
{
if (b->owner->IsDead(room)) {
return false;
@ -68,6 +86,21 @@ bool Entity::TestCollision(Room* room,ColliderComponent* b)
return false;
}
ColliderComponent* Entity::TestCollisionAndGetCollider(Room* room, ColliderComponent* b)
{
if (b->owner->IsDead(room)) {
return nullptr;
}
OnPreCollision(room);
b->owner->OnPreCollision(room);
for (auto& a_collider : colliders_) {
if (a_collider->Intersect(b)) {
return a_collider;
}
}
return nullptr;
}
bool Entity::TestCollisionEx(Room* room, const a8::Vec2& aabb_pos, AabbCollider& aabb_box)
{
OnPreCollision(room);

View File

@ -48,7 +48,9 @@ class Entity
{ return subtype == entity_subtype_;}
int GetGridId() const { return grid_id_; }
bool TestCollision(Room* room, Entity* b);
ColliderComponent* TestCollisionAndGetCollider(Room* room, Entity* b);
bool TestCollision(Room* room, ColliderComponent* b);
ColliderComponent* TestCollisionAndGetCollider(Room* room, ColliderComponent* b);
bool TestCollisionEx(Room* room, const a8::Vec2& aabb_pos, AabbCollider& aabb_box);
void BroadcastFullState(Room* room);
void BroadcastDeleteState(Room* room);

View File

@ -72,6 +72,7 @@ void MapService::UnInit()
void MapService::AddCollider(ColliderComponent* collider)
{
if (!(collider->owner->IsEntityType(ET_Obstacle) ||
collider->owner->IsEntityType(ET_Dummy) ||
collider->owner->IsEntityType(ET_Building))) {
abort();
}
@ -221,6 +222,7 @@ void MapService::GetColliders(Room* room,
}
break;
case ET_Building:
case ET_Dummy:
{
colliders.insert(node->collider);
}
@ -292,6 +294,24 @@ bool MapService::CollisionDetection(Room* room,
const a8::Vec2& pos,
ColliderComponent* a_collider)
{
ColliderComponent* pickup_collider = nullptr;
return CollisionDetectionAndGetCollider
(
room,
through_wall,
pos,
a_collider,
&pickup_collider
);
}
bool MapService::CollisionDetectionAndGetCollider(Room* room,
bool through_wall,
const a8::Vec2& pos,
ColliderComponent* a_collider,
ColliderComponent** pickup_collider)
{
*pickup_collider = nullptr;
if (room->OverBorder(pos, a_collider)){
return true;
}
@ -309,14 +329,17 @@ bool MapService::CollisionDetection(Room* room,
Obstacle* obstacle = (Obstacle*)collider->owner;
if (obstacle->meta->i->collision_hit() != kCollisionHitPass) {
if (!obstacle->IsDead(room) && collider->IntersectEx(pos, a_collider)) {
*pickup_collider = collider;
return true;
}
}
}
break;
case ET_Building:
case ET_Dummy:
{
if (collider->IntersectEx(pos, a_collider)) {
*pickup_collider = collider;
return true;
}
}

View File

@ -58,6 +58,11 @@ class MapService
bool through_wall,
const a8::Vec2& pos,
ColliderComponent* collider);
bool CollisionDetectionAndGetCollider(Room* room,
bool through_wall,
const a8::Vec2& pos,
ColliderComponent* collider,
ColliderComponent** pickup_collider);
private:
int GetGridId(float world_x, float world_y);