collider重构

This commit is contained in:
aozhiwei 2019-03-20 19:58:28 +08:00
parent f161f2b744
commit c87691e5bc
13 changed files with 78 additions and 42 deletions

View File

@ -102,7 +102,9 @@ void AndroidAI::DoAttack()
Human* enemy = owner->room->FindEnemy((Human*)owner); Human* enemy = owner->room->FindEnemy((Human*)owner);
if (enemy) { if (enemy) {
Human* sender = (Human*)owner; Human* sender = (Human*)owner;
sender->Shot(enemy->pos); Vector2D shot_dir = enemy->pos;
shot_dir.Normalize();
sender->Shot(shot_dir);
} }
} }
} }
@ -122,7 +124,9 @@ void AndroidAI::DoMoveAndAttack()
Human* enemy = owner->room->FindEnemy((Human*)owner); Human* enemy = owner->room->FindEnemy((Human*)owner);
if (enemy) { if (enemy) {
Human* sender = (Human*)owner; Human* sender = (Human*)owner;
sender->Shot(enemy->pos); Vector2D shot_dir = enemy->pos;
shot_dir.Normalize();
sender->Shot(shot_dir);
} }
} }
} }

View File

@ -22,6 +22,13 @@ Android::~Android()
void Android::Initialize() void Android::Initialize()
{ {
health = meta->i->health(); health = meta->i->health();
helmet = DEF_HELMET_ID;
chest = DEF_CHEST_ID;
weapon = DEF_WEAPON_ID;
helmet_meta = MetaMgr::Instance()->GetEquip(helmet);
chest_meta = MetaMgr::Instance()->GetEquip(chest);
weapon_meta = MetaMgr::Instance()->GetEquip(weapon);
RecalcSelfCollider();
} }
void Android::Update(int delta_time) void Android::Update(int delta_time)

View File

@ -28,8 +28,13 @@ void Bullet::Update(int delta_time)
{ {
movement->Update(delta_time); movement->Update(delta_time);
std::vector<Entity*> objects; std::vector<Entity*> objects;
room->CollisionDetection(this, 0, objects); int detection_flags = 0;
if (objects.empty()) { {
a8::SetBitFlag(detection_flags, ET_Obstacle);
a8::SetBitFlag(detection_flags, ET_Player);
}
room->CollisionDetection(this, detection_flags, objects);
if (!objects.empty()) {
deleted = true; deleted = true;
room->AddDeletedObject(objects[0]->entity_uniid); room->AddDeletedObject(objects[0]->entity_uniid);
} }
@ -39,8 +44,9 @@ void Bullet::RecalcSelfCollider()
{ {
if (!self_collider_) { if (!self_collider_) {
self_collider_ = new CircleCollider(); self_collider_ = new CircleCollider();
self_collider_->owner = this;
colliders.push_back(self_collider_); colliders.push_back(self_collider_);
} }
self_collider_->pos = Vector2D(); self_collider_->pos = Vector2D();
self_collider_->rad = meta->i->bullet_rad(); self_collider_->rad = gun_meta->i->bullet_rad();
} }

View File

@ -12,13 +12,19 @@ bool ColliderComponent::IntersectSegment(Vector2D& p0, Vector2D& p1)
case CT_Aabb: case CT_Aabb:
{ {
AabbCollider* a_aabb = (AabbCollider*)this; AabbCollider* a_aabb = (AabbCollider*)this;
return IntersectSegmentAabb(p0, p1, a_aabb->_min, a_aabb->_max); return IntersectSegmentAabb(p0,
p1,
a_aabb->owner->pos + a_aabb->_min,
a_aabb->owner->pos + a_aabb->_max);
} }
break; break;
case CT_Circle: case CT_Circle:
{ {
CircleCollider* a_circle = (CircleCollider*)this; CircleCollider* a_circle = (CircleCollider*)this;
return IntersectSegmentCircle(p0, p1, a_circle->pos, a_circle->rad); return IntersectSegmentCircle(p0,
p1,
a_circle->owner->pos + a_circle->pos,
a_circle->rad);
} }
break; break;
} }
@ -39,19 +45,19 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
case CT_Aabb: case CT_Aabb:
{ {
AabbCollider* b_aabb = (AabbCollider*)b; AabbCollider* b_aabb = (AabbCollider*)b;
return IntersectAabbAabb(a_aabb->_min, return IntersectAabbAabb(a_aabb->owner->pos + a_aabb->_min,
a_aabb->_max, a_aabb->owner->pos + a_aabb->_max,
b_aabb->_min, b_aabb->owner->pos + b_aabb->_min,
b_aabb->_max b_aabb->owner->pos + b_aabb->_max
); );
} }
break; break;
case CT_Circle: case CT_Circle:
{ {
CircleCollider* b_circle = (CircleCollider*)b; CircleCollider* b_circle = (CircleCollider*)b;
return IntersectAabbCircle(a_aabb->_min, return IntersectAabbCircle(a_aabb->owner->pos + a_aabb->_min,
a_aabb->_max, a_aabb->owner->pos + a_aabb->_max,
b_circle->pos, b_circle->owner->pos + b_circle->pos,
b_circle->rad); b_circle->rad);
} }
break; break;
@ -67,9 +73,9 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
case CT_Aabb: case CT_Aabb:
{ {
AabbCollider* b_aabb = (AabbCollider*)b; AabbCollider* b_aabb = (AabbCollider*)b;
return IntersectAabbCircle(b_aabb->_min, return IntersectAabbCircle(b_aabb->owner->pos + b_aabb->_min,
b_aabb->_max, b_aabb->owner->pos + b_aabb->_max,
a_circle->pos, a_circle->owner->pos + a_circle->pos,
a_circle->rad); a_circle->rad);
} }
break; break;
@ -77,9 +83,9 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
{ {
CircleCollider* b_circle = (CircleCollider*)b; CircleCollider* b_circle = (CircleCollider*)b;
return IntersectCircleCircle( return IntersectCircleCircle(
a_circle->pos, a_circle->owner->pos + a_circle->pos,
a_circle->rad, a_circle->rad,
b_circle->pos, b_circle->owner->pos + b_circle->pos,
b_circle->rad); b_circle->rad);
} }
break; break;

View File

@ -24,6 +24,8 @@ class AabbCollider : public ColliderComponent
public: public:
Vector2D _min; Vector2D _min;
Vector2D _max; Vector2D _max;
AabbCollider() { type = CT_Aabb; };
}; };
class CircleCollider : public ColliderComponent class CircleCollider : public ColliderComponent
@ -31,4 +33,6 @@ class CircleCollider : public ColliderComponent
public: public:
Vector2D pos; Vector2D pos;
float rad = 0.0f; float rad = 0.0f;
CircleCollider() { type = CT_Circle; };
}; };

View File

@ -3,7 +3,7 @@
#include <algorithm> #include <algorithm>
#include<cfloat> #include<cfloat>
bool IntersectSegmentCircle(Vector2D& p0, Vector2D& p1, Vector2D& pos, float rad) bool IntersectSegmentCircle(Vector2D p0, Vector2D p1, Vector2D pos, float rad)
{ {
Vector2D t = p1 - p0; Vector2D t = p1 - p0;
float d = std::max(t.Norm(), 0.0001f); float d = std::max(t.Norm(), 0.0001f);
@ -25,7 +25,7 @@ bool IntersectSegmentCircle(Vector2D& p0, Vector2D& p1, Vector2D& pos, float rad
return false; return false;
} }
bool IntersectSegmentAabb(Vector2D& p0, Vector2D& p1, Vector2D& _min, Vector2D& _max) bool IntersectSegmentAabb(Vector2D p0, Vector2D p1, Vector2D _min, Vector2D _max)
{ {
float t = 0.0f; float t = 0.0f;
float d = FLT_MAX; float d = FLT_MAX;
@ -63,7 +63,7 @@ bool IntersectSegmentAabb(Vector2D& p0, Vector2D& p1, Vector2D& _min, Vector2D&
return true; return true;
} }
bool IntersectAabbCircle(Vector2D& a_min, Vector2D& a_max, Vector2D& b_pos, float& b_rad) bool IntersectAabbCircle(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad)
{ {
if (b_pos.x >= a_min.x && b_pos.x <= a_max.x && if (b_pos.x >= a_min.x && b_pos.x <= a_max.x &&
b_pos.y >= a_min.y && b_pos.y <= a_max.y) { b_pos.y >= a_min.y && b_pos.y <= a_max.y) {
@ -76,7 +76,7 @@ bool IntersectAabbCircle(Vector2D& a_min, Vector2D& a_max, Vector2D& b_pos, floa
return n < b_rad*b_rad; return n < b_rad*b_rad;
} }
bool IntersectAabbAabb(Vector2D& a_min, Vector2D& a_max, Vector2D& b_min, Vector2D& b_max) bool IntersectAabbAabb(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vector2D b_max)
{ {
Vector2D a_v = (a_max - a_min) * 0.5f; Vector2D a_v = (a_max - a_min) * 0.5f;
Vector2D a_center = a_min + a_v; Vector2D a_center = a_min + a_v;
@ -87,7 +87,7 @@ bool IntersectAabbAabb(Vector2D& a_min, Vector2D& a_max, Vector2D& b_min, Vector
return u > 0; return u > 0;
} }
bool IntersectCircleCircle(Vector2D& a_pos, float& a_rad, Vector2D& b_pos, float& b_rad) bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad)
{ {
float t = a_rad + b_rad; float t = a_rad + b_rad;
Vector2D d = b_pos - a_pos; Vector2D d = b_pos - a_pos;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
bool IntersectSegmentCircle(Vector2D& p0, Vector2D& p1, Vector2D& pos, float rad); bool IntersectSegmentCircle(Vector2D p0, Vector2D p1, Vector2D pos, float rad);
bool IntersectSegmentAabb(Vector2D& p0, Vector2D& p1, Vector2D& _min, Vector2D& _max); bool IntersectSegmentAabb(Vector2D p0, Vector2D p1, Vector2D _min, Vector2D _max);
bool IntersectAabbCircle(Vector2D& a_min, Vector2D& a_max, Vector2D& b_pos, float& b_rad); bool IntersectAabbCircle(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad);
bool IntersectAabbAabb(Vector2D& a_min, Vector2D& a_max, Vector2D& b_min, Vector2D& b_max); bool IntersectAabbAabb(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vector2D b_max);
bool IntersectCircleCircle(Vector2D& a_pos, float& a_rad, Vector2D& b_pos, float& b_rad); bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad);

View File

@ -30,7 +30,7 @@ Entity::~Entity()
bool Entity::TestCollision(Entity* b) bool Entity::TestCollision(Entity* b)
{ {
for (auto& a_collider : b->colliders) { for (auto& a_collider : colliders) {
for (auto& b_collider : b->colliders) { for (auto& b_collider : b->colliders) {
if (a_collider->Intersect(b_collider)) { if (a_collider->Intersect(b_collider)) {
return false; return false;

View File

@ -22,13 +22,6 @@ Human::~Human()
void Human::Initialize() void Human::Initialize()
{ {
helmet = DEF_HELMET_ID;
chest = DEF_CHEST_ID;
weapon = DEF_WEAPON_ID;
helmet_meta = MetaMgr::Instance()->GetEquip(helmet);
chest_meta = MetaMgr::Instance()->GetEquip(chest);
weapon_meta = MetaMgr::Instance()->GetEquip(weapon);
RecalcSelfCollider();
} }
float Human::GetSpeed() float Human::GetSpeed()
@ -77,14 +70,14 @@ void Human::Shot(Vector2D& target_dir)
} }
{ {
cs::MFShot* shot = frame_data.shots.Add(); cs::MFShot* shot = room->frame_data.shots.Add();
shot->set_player_id(entity_uniid); shot->set_player_id(entity_uniid);
shot->set_weapon_id(weapon_meta->i->id()); shot->set_weapon_id(weapon_meta->i->id());
shot->set_offhand(true); shot->set_offhand(true);
shot->set_bullskin(10001); shot->set_bullskin(10001);
} }
{ {
cs::MFBullet* bullet = frame_data.bullets.Add(); cs::MFBullet* bullet = room->frame_data.bullets.Add();
bullet->set_player_id(entity_uniid); bullet->set_player_id(entity_uniid);
bullet->set_bullet_id(weapon_meta->i->use_bullet()); bullet->set_bullet_id(weapon_meta->i->use_bullet());
pos.ToPB(bullet->mutable_pos()); pos.ToPB(bullet->mutable_pos());
@ -94,6 +87,7 @@ void Human::Shot(Vector2D& target_dir)
{ {
Bullet* bullet = new Bullet(); Bullet* bullet = new Bullet();
bullet->player = this; bullet->player = this;
bullet->room = room;
bullet->gun_meta = weapon_meta; bullet->gun_meta = weapon_meta;
bullet->meta = MetaMgr::Instance()->GetEquip(weapon_meta->i->use_bullet()); bullet->meta = MetaMgr::Instance()->GetEquip(weapon_meta->i->use_bullet());
bullet->pos = pos; bullet->pos = pos;
@ -101,6 +95,7 @@ void Human::Shot(Vector2D& target_dir)
bullet->born_pos = pos; bullet->born_pos = pos;
bullet->born_dir = target_dir; bullet->born_dir = target_dir;
bullet->entity_uniid = bullet->room->AllocUniid(); bullet->entity_uniid = bullet->room->AllocUniid();
bullet->Initialize();
room->AddBullet(bullet); room->AddBullet(bullet);
} }
} }
@ -109,6 +104,7 @@ void Human::RecalcSelfCollider()
{ {
if (!self_collider_) { if (!self_collider_) {
self_collider_ = new CircleCollider(); self_collider_ = new CircleCollider();
self_collider_->owner = this;
colliders.push_back(self_collider_); colliders.push_back(self_collider_);
} }
self_collider_->pos = Vector2D(); self_collider_->pos = Vector2D();

View File

@ -11,8 +11,6 @@ namespace MetaData
struct HumanFrameData struct HumanFrameData
{ {
::google::protobuf::RepeatedPtrField<::cs::MFBullet> bullets;
::google::protobuf::RepeatedPtrField<::cs::MFShot> shots;
}; };
class CircleCollider; class CircleCollider;

View File

@ -39,6 +39,13 @@ Player::~Player()
void Player::Initialize() void Player::Initialize()
{ {
health = meta->i->health(); health = meta->i->health();
helmet = DEF_HELMET_ID;
chest = DEF_CHEST_ID;
weapon = DEF_WEAPON_ID;
helmet_meta = MetaMgr::Instance()->GetEquip(helmet);
chest_meta = MetaMgr::Instance()->GetEquip(chest);
weapon_meta = MetaMgr::Instance()->GetEquip(weapon);
RecalcSelfCollider();
} }
void Player::Update(int delta_time) void Player::Update(int delta_time)
@ -94,21 +101,25 @@ void Player::MakeUpdateMsg()
} }
for (auto& itr : new_players) { for (auto& itr : new_players) {
itr->FillMFObjectFull(update_msg->add_full_objects()); itr->FillMFObjectFull(update_msg->add_full_objects());
#if 0
if (itr->frame_data.bullets.size() > 0) { if (itr->frame_data.bullets.size() > 0) {
update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets); update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets);
} }
if (itr->frame_data.shots.size() > 0) { if (itr->frame_data.shots.size() > 0) {
update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots); update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots);
} }
#endif
} }
for (auto& itr : part_players) { for (auto& itr : part_players) {
itr->FillMFObjectPart(update_msg->add_part_objects()); itr->FillMFObjectPart(update_msg->add_part_objects());
#if 0
if (itr->frame_data.bullets.size() > 0) { if (itr->frame_data.bullets.size() > 0) {
update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets); update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets);
} }
if (itr->frame_data.shots.size() > 0) { if (itr->frame_data.shots.size() > 0) {
update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots); update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots);
} }
#endif
} }
if (updated_times == 0) { if (updated_times == 0) {
update_msg->set_active_player_id(entity_uniid); update_msg->set_active_player_id(entity_uniid);

View File

@ -180,7 +180,7 @@ void Room::CollisionDetection(Entity* sender, int detection_flags, std::vector<E
if (sender->entity_type == ET_Bullet) { if (sender->entity_type == ET_Bullet) {
Bullet* bullet = (Bullet*)sender; Bullet* bullet = (Bullet*)sender;
Human* hum = (Human*)pair.second; Human* hum = (Human*)pair.second;
if (bullet->player->team_id != hum->team_id) { if (hum->team_id == 0 || bullet->player->team_id != hum->team_id) {
if (bullet->TestCollision(hum)) { if (bullet->TestCollision(hum)) {
objects.push_back(hum); objects.push_back(hum);
} }
@ -223,6 +223,8 @@ void Room::ResetFrameData()
frame_data.deleted_objects.clear(); frame_data.deleted_objects.clear();
frame_data.explosions.Clear(); frame_data.explosions.Clear();
frame_data.emotes.Clear(); frame_data.emotes.Clear();
frame_data.bullets.Clear();
frame_data.shots.Clear();
} }
void Room::ClearDeletedObjects() void Room::ClearDeletedObjects()

View File

@ -19,6 +19,8 @@ struct RoomFrameData
std::set<unsigned short> deleted_objects; std::set<unsigned short> deleted_objects;
::google::protobuf::RepeatedPtrField<::cs::MFExplosion> explosions; ::google::protobuf::RepeatedPtrField<::cs::MFExplosion> explosions;
::google::protobuf::RepeatedPtrField<::cs::MFEmote> emotes; ::google::protobuf::RepeatedPtrField<::cs::MFEmote> emotes;
::google::protobuf::RepeatedPtrField<::cs::MFBullet> bullets;
::google::protobuf::RepeatedPtrField<::cs::MFShot> shots;
}; };
class Entity; class Entity;