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);
if (enemy) {
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);
if (enemy) {
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()
{
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)

View File

@ -28,8 +28,13 @@ void Bullet::Update(int delta_time)
{
movement->Update(delta_time);
std::vector<Entity*> objects;
room->CollisionDetection(this, 0, objects);
if (objects.empty()) {
int detection_flags = 0;
{
a8::SetBitFlag(detection_flags, ET_Obstacle);
a8::SetBitFlag(detection_flags, ET_Player);
}
room->CollisionDetection(this, detection_flags, objects);
if (!objects.empty()) {
deleted = true;
room->AddDeletedObject(objects[0]->entity_uniid);
}
@ -39,8 +44,9 @@ void Bullet::RecalcSelfCollider()
{
if (!self_collider_) {
self_collider_ = new CircleCollider();
self_collider_->owner = this;
colliders.push_back(self_collider_);
}
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:
{
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;
case CT_Circle:
{
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;
}
@ -39,19 +45,19 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
case CT_Aabb:
{
AabbCollider* b_aabb = (AabbCollider*)b;
return IntersectAabbAabb(a_aabb->_min,
a_aabb->_max,
b_aabb->_min,
b_aabb->_max
return IntersectAabbAabb(a_aabb->owner->pos + a_aabb->_min,
a_aabb->owner->pos + a_aabb->_max,
b_aabb->owner->pos + b_aabb->_min,
b_aabb->owner->pos + b_aabb->_max
);
}
break;
case CT_Circle:
{
CircleCollider* b_circle = (CircleCollider*)b;
return IntersectAabbCircle(a_aabb->_min,
a_aabb->_max,
b_circle->pos,
return IntersectAabbCircle(a_aabb->owner->pos + a_aabb->_min,
a_aabb->owner->pos + a_aabb->_max,
b_circle->owner->pos + b_circle->pos,
b_circle->rad);
}
break;
@ -67,9 +73,9 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
case CT_Aabb:
{
AabbCollider* b_aabb = (AabbCollider*)b;
return IntersectAabbCircle(b_aabb->_min,
b_aabb->_max,
a_circle->pos,
return IntersectAabbCircle(b_aabb->owner->pos + b_aabb->_min,
b_aabb->owner->pos + b_aabb->_max,
a_circle->owner->pos + a_circle->pos,
a_circle->rad);
}
break;
@ -77,9 +83,9 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
{
CircleCollider* b_circle = (CircleCollider*)b;
return IntersectCircleCircle(
a_circle->pos,
a_circle->owner->pos + a_circle->pos,
a_circle->rad,
b_circle->pos,
b_circle->owner->pos + b_circle->pos,
b_circle->rad);
}
break;

View File

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

View File

@ -3,7 +3,7 @@
#include <algorithm>
#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;
float d = std::max(t.Norm(), 0.0001f);
@ -25,7 +25,7 @@ bool IntersectSegmentCircle(Vector2D& p0, Vector2D& p1, Vector2D& pos, float rad
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 d = FLT_MAX;
@ -63,7 +63,7 @@ bool IntersectSegmentAabb(Vector2D& p0, Vector2D& p1, Vector2D& _min, Vector2D&
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 &&
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;
}
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_center = a_min + a_v;
@ -87,7 +87,7 @@ bool IntersectAabbAabb(Vector2D& a_min, Vector2D& a_max, Vector2D& b_min, Vector
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;
Vector2D d = b_pos - a_pos;

View File

@ -1,7 +1,7 @@
#pragma once
bool IntersectSegmentCircle(Vector2D& p0, Vector2D& p1, Vector2D& pos, float rad);
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 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 IntersectSegmentCircle(Vector2D p0, Vector2D p1, Vector2D pos, float rad);
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 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);

View File

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

View File

@ -22,13 +22,6 @@ Human::~Human()
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()
@ -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_weapon_id(weapon_meta->i->id());
shot->set_offhand(true);
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_bullet_id(weapon_meta->i->use_bullet());
pos.ToPB(bullet->mutable_pos());
@ -94,6 +87,7 @@ void Human::Shot(Vector2D& target_dir)
{
Bullet* bullet = new Bullet();
bullet->player = this;
bullet->room = room;
bullet->gun_meta = weapon_meta;
bullet->meta = MetaMgr::Instance()->GetEquip(weapon_meta->i->use_bullet());
bullet->pos = pos;
@ -101,6 +95,7 @@ void Human::Shot(Vector2D& target_dir)
bullet->born_pos = pos;
bullet->born_dir = target_dir;
bullet->entity_uniid = bullet->room->AllocUniid();
bullet->Initialize();
room->AddBullet(bullet);
}
}
@ -109,6 +104,7 @@ void Human::RecalcSelfCollider()
{
if (!self_collider_) {
self_collider_ = new CircleCollider();
self_collider_->owner = this;
colliders.push_back(self_collider_);
}
self_collider_->pos = Vector2D();

View File

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

View File

@ -39,6 +39,13 @@ Player::~Player()
void Player::Initialize()
{
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)
@ -94,21 +101,25 @@ void Player::MakeUpdateMsg()
}
for (auto& itr : new_players) {
itr->FillMFObjectFull(update_msg->add_full_objects());
#if 0
if (itr->frame_data.bullets.size() > 0) {
update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets);
}
if (itr->frame_data.shots.size() > 0) {
update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots);
}
#endif
}
for (auto& itr : part_players) {
itr->FillMFObjectPart(update_msg->add_part_objects());
#if 0
if (itr->frame_data.bullets.size() > 0) {
update_msg->mutable_bullets()->MergeFrom(itr->frame_data.bullets);
}
if (itr->frame_data.shots.size() > 0) {
update_msg->mutable_shots()->MergeFrom(itr->frame_data.shots);
}
#endif
}
if (updated_times == 0) {
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) {
Bullet* bullet = (Bullet*)sender;
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)) {
objects.push_back(hum);
}
@ -223,6 +223,8 @@ void Room::ResetFrameData()
frame_data.deleted_objects.clear();
frame_data.explosions.Clear();
frame_data.emotes.Clear();
frame_data.bullets.Clear();
frame_data.shots.Clear();
}
void Room::ClearDeletedObjects()

View File

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