修复碰撞问题
This commit is contained in:
parent
11eee3ae95
commit
4e793b075a
@ -56,22 +56,6 @@ void Building::FillMFObjectFull(cs::MFObjectFull* full_data)
|
||||
p->set_building_id(meta->i->mapid());
|
||||
}
|
||||
|
||||
ColliderComponent* Building::GetBoxBound()
|
||||
{
|
||||
AabbCollider* collider = new AabbCollider();
|
||||
collider->active = true;
|
||||
collider->owner = this;
|
||||
collider->_min = Vector2D(
|
||||
-meta->i->tilewidth()/2.0,
|
||||
-meta->i->tileheight()/2.0
|
||||
);
|
||||
collider->_max = Vector2D(
|
||||
meta->i->tilewidth()/2.0,
|
||||
meta->i->tileheight()/2.0
|
||||
);
|
||||
return collider;
|
||||
}
|
||||
|
||||
void Building::GetAabbBox(AabbCollider& aabb_box)
|
||||
{
|
||||
aabb_box.active = true;
|
||||
|
@ -24,6 +24,5 @@ class Building : public Entity
|
||||
void RecalcSelfCollider();
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override;
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
|
||||
virtual ColliderComponent* GetBoxBound() override;
|
||||
virtual void GetAabbBox(AabbCollider& aabb_box) override;
|
||||
};
|
||||
|
@ -256,15 +256,6 @@ void Bullet::MapServiceUpdate()
|
||||
for (ColliderComponent* collider : colliders) {
|
||||
if (TestCollision(collider)) {
|
||||
objects.insert(collider->owner);
|
||||
#if 0
|
||||
a8::XPrintf("%d,%d collider:%d,%d \n",
|
||||
{
|
||||
pos.x,
|
||||
pos.y,
|
||||
collider->owner->pos.x,
|
||||
collider->owner->pos.y
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ bool ColliderComponent::CalcSafePoint(ColliderComponent* b, Vector2D& new_pos)
|
||||
switch (b->type) {
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* b_aabb = (AabbCollider*)this;
|
||||
AabbCollider* b_aabb = (AabbCollider*)b;
|
||||
return CalcAabbAabbSafePoint(a_aabb->owner->pos + a_aabb->_min,
|
||||
a_aabb->owner->pos + a_aabb->_max,
|
||||
b_aabb->owner->pos + b_aabb->_min,
|
||||
|
@ -143,12 +143,34 @@ bool CalcAabbAabbSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vecto
|
||||
Vector2D& new_pos)
|
||||
{
|
||||
Vector2D a_pos = a_min + (a_max - a_min)/2.0f;
|
||||
float a_rad = (a_max - a_min).Norm();
|
||||
Vector2D b_pos = b_min + (b_max - b_min)/2.0f;
|
||||
float b_rad = (b_max - b_min).Norm();
|
||||
Vector2D dir = (a_pos - b_pos);
|
||||
dir.Normalize();
|
||||
new_pos = b_pos + dir*(a_rad + b_rad) + 1;
|
||||
new_pos = a_pos;
|
||||
bool at_left = std::abs(a_pos.x - b_min.x) < std::abs(a_pos.x - b_max.x);
|
||||
bool at_down = std::abs(a_pos.y - b_min.y) < std::abs(a_pos.y - b_max.y);
|
||||
float x_len = at_left ? std::abs(a_pos.x - b_min.x) : std::abs(a_pos.x - b_max.x);
|
||||
float y_len = at_down ? std::abs(a_pos.y - b_min.y) : std::abs(a_pos.y - b_max.y);
|
||||
if (at_left) {
|
||||
if (x_len < y_len) {
|
||||
//左
|
||||
new_pos.x = b_min.x - (a_max.x - a_min.x)/2.0f - 1;
|
||||
} else {
|
||||
if (at_down) {
|
||||
new_pos.y = b_min.y - (a_max.y - a_min.y)/2.0f - 1;
|
||||
} else {
|
||||
new_pos.y = b_max.y + (a_max.y - a_min.y)/2.0f + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (x_len < y_len) {
|
||||
//右
|
||||
new_pos.x = b_max.x + (a_max.x - a_min.x)/2.0f + 1;
|
||||
} else {
|
||||
if (at_down) {
|
||||
new_pos.y = b_min.y - (a_max.y - a_min.y)/2.0f - 1;
|
||||
} else {
|
||||
new_pos.y = b_max.y + (a_max.y - a_min.y)/2.0f + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -156,9 +178,33 @@ bool CalcAabbCircleSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_pos, flo
|
||||
Vector2D& new_pos)
|
||||
{
|
||||
Vector2D a_pos = a_min + (a_max - a_min)/2.0f;
|
||||
float a_rad = (a_max - a_min).Norm();
|
||||
Vector2D dir = a_pos - b_pos;
|
||||
dir.Normalize();
|
||||
new_pos = b_pos + dir*(a_rad + b_rad) + 1;
|
||||
new_pos = a_pos;
|
||||
bool at_left = std::abs(a_min.x - b_pos.x) < std::abs(a_max.x - b_pos.x);
|
||||
bool at_down = std::abs(a_min.y - b_pos.y) < std::abs(a_max.y - b_pos.y);
|
||||
float x_len = at_left ? std::abs(a_min.x - b_pos.x) : std::abs(a_max.x - b_pos.x);
|
||||
float y_len = at_down ? std::abs(a_min.y - b_pos.y) : std::abs(a_max.y - b_pos.y);
|
||||
if (at_left) {
|
||||
if (x_len < y_len) {
|
||||
//左
|
||||
new_pos.x = b_pos.x - (a_max.x - a_min.x)/2.0f - 1;
|
||||
} else {
|
||||
if (at_down) {
|
||||
new_pos.y = b_pos.y - (a_max.y - a_min.y)/2.0f - 1;
|
||||
} else {
|
||||
new_pos.y = b_pos.y + (a_max.y - a_min.y)/2.0f + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (x_len < y_len) {
|
||||
//右
|
||||
new_pos.x = b_pos.x + (a_max.x - a_min.x)/2.0f + 1;
|
||||
} else {
|
||||
if (at_down) {
|
||||
new_pos.y = b_pos.y - (a_max.y - a_min.y)/2.0f - 1;
|
||||
} else {
|
||||
new_pos.y = b_pos.y + (a_max.y - a_min.y)/2.0f + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -135,6 +135,33 @@ enum EquipAttr_e
|
||||
EA_End
|
||||
};
|
||||
|
||||
enum EntityType_e
|
||||
{
|
||||
ET_None = 0,
|
||||
ET_Player = 1,
|
||||
ET_Obstacle = 2,
|
||||
ET_Building = 3,
|
||||
//ET_LootSpawner = 4,
|
||||
ET_Loot = 5,
|
||||
//ET_DeadBody = 6,
|
||||
//ET_Decal = 7,
|
||||
//ET_Projectile = 8,
|
||||
ET_Smoke = 9,
|
||||
ET_Hero = 10,
|
||||
|
||||
ET_Bullet = 20,
|
||||
|
||||
ET_Android = 30,
|
||||
ET_MAX
|
||||
};
|
||||
|
||||
enum EntitySubType_e
|
||||
{
|
||||
EST_None = 0,
|
||||
EST_Player = 1,
|
||||
EST_Android = 2,
|
||||
};
|
||||
|
||||
const char* const PROJ_NAME_FMT = "game%d_gameserver";
|
||||
const char* const PROJ_ROOT_FMT = "/data/logs/%s";
|
||||
|
||||
@ -172,4 +199,3 @@ const int MAX_INSTANCE_ID = 500;
|
||||
const int WALK_ZONE_WIDTH = 100;
|
||||
|
||||
const int MAX_TEAM_NUM = 4;
|
||||
|
||||
|
@ -22,14 +22,6 @@ void Entity::Initialize()
|
||||
xtimer_attacher.xtimer = &room->xtimer;
|
||||
}
|
||||
|
||||
ColliderComponent* Entity::GetBoxBound()
|
||||
{
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
collider->active = true;
|
||||
collider->owner = this;
|
||||
return collider;
|
||||
}
|
||||
|
||||
void Entity::GetAabbBox(AabbCollider& aabb_box)
|
||||
{
|
||||
aabb_box.active = true;
|
||||
@ -80,45 +72,60 @@ void Entity::ClearColliders()
|
||||
|
||||
void Entity::FindLocationWithTarget(Entity* target)
|
||||
{
|
||||
ColliderComponent* a_collider = GetBoxBound();
|
||||
Vector2D old_pos = pos;
|
||||
Vector2D new_pos = pos;
|
||||
ColliderComponent* target_collider = target->GetBoxBound();
|
||||
AabbCollider a_collider;
|
||||
GetAabbBox(a_collider);
|
||||
AabbCollider target_collider;
|
||||
target->GetAabbBox(target_collider);
|
||||
{
|
||||
bool ret = a_collider->CalcSafePoint(target_collider, new_pos);
|
||||
bool ret = a_collider.CalcSafePoint(&target_collider, new_pos);
|
||||
if (!ret) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
Vector2D new_pos_dir = new_pos - old_pos;
|
||||
float distance = (new_pos - old_pos).Norm();
|
||||
new_pos_dir.Normalize();
|
||||
for (float i = distance; i < 10000000; i += 5.0f) {
|
||||
float distance = (new_pos - old_pos).Norm();
|
||||
for (int i = distance; i < 10000000; i += 5) {
|
||||
pos = old_pos + new_pos_dir * i;
|
||||
|
||||
Entity* building = nullptr;
|
||||
std::set<GridCell*> new_grid_list;
|
||||
room->grid_service.GetAllCellsByXy(pos.x, pos.y, new_grid_list);
|
||||
|
||||
std::vector<Entity*> objects;
|
||||
for (auto& grid : new_grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Obstacle:
|
||||
case ET_Building:
|
||||
{
|
||||
if (entity != this && TestCollision(entity)){
|
||||
objects.push_back(entity);
|
||||
break;
|
||||
if (TestCollision(entity)) {
|
||||
building = entity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
if (building) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (building) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (objects.empty()) {
|
||||
break;
|
||||
|
||||
if (!building) {
|
||||
bool is_collision = false;
|
||||
std::set<ColliderComponent*> colliders;
|
||||
room->map_service.GetColliders(pos.x, pos.y, colliders);
|
||||
for (ColliderComponent* collider : colliders) {
|
||||
if (TestCollision(collider)) {
|
||||
is_collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_collision) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,9 +150,6 @@ void Entity::FindLocationWithTarget(Entity* target)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DestoryCollider(target_collider);
|
||||
DestoryCollider(a_collider);
|
||||
}
|
||||
|
||||
void Entity::BroadcastFullState()
|
||||
|
@ -8,33 +8,6 @@ namespace cs
|
||||
class MFObjectFull;
|
||||
}
|
||||
|
||||
enum EntityType_e
|
||||
{
|
||||
ET_None = 0,
|
||||
ET_Player = 1,
|
||||
ET_Obstacle = 2,
|
||||
ET_Building = 3,
|
||||
//ET_LootSpawner = 4,
|
||||
ET_Loot = 5,
|
||||
//ET_DeadBody = 6,
|
||||
//ET_Decal = 7,
|
||||
//ET_Projectile = 8,
|
||||
ET_Smoke = 9,
|
||||
ET_Hero = 10,
|
||||
|
||||
ET_Bullet = 20,
|
||||
|
||||
ET_Android = 30,
|
||||
ET_MAX
|
||||
};
|
||||
|
||||
enum EntitySubType_e
|
||||
{
|
||||
EST_None = 0,
|
||||
EST_Player = 1,
|
||||
EST_Android = 2,
|
||||
};
|
||||
|
||||
class Room;
|
||||
class Obstacle;
|
||||
class ColliderComponent;
|
||||
@ -66,7 +39,6 @@ class Entity
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) {};
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) {};
|
||||
virtual float GetSpeed() { return 1.0f;};
|
||||
virtual ColliderComponent* GetBoxBound();
|
||||
virtual void GetAabbBox(AabbCollider& aabb_box);
|
||||
virtual void GetCircleBox(CircleCollider& circle_box);
|
||||
bool TestCollision(Entity* b);
|
||||
|
@ -55,12 +55,3 @@ void Hero::FillMFObjectFull(cs::MFObjectFull* full_data)
|
||||
weapon.ToPB(p->mutable_weapon());
|
||||
p->set_energy_shield(energy_shield);
|
||||
}
|
||||
|
||||
ColliderComponent* Hero::GetBoxBound()
|
||||
{
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
collider->owner = this;
|
||||
collider->pos = Vector2D();
|
||||
collider->rad = master->GetRadius();
|
||||
return collider;
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ class Hero : public Entity
|
||||
void RecalcSelfCollider();
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override;
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
|
||||
virtual ColliderComponent* GetBoxBound() override;
|
||||
|
||||
private:
|
||||
CircleCollider* self_collider_ = nullptr;
|
||||
|
@ -142,15 +142,6 @@ void Human::FillMFObjectFull(cs::MFObjectFull* full_data)
|
||||
FillBodyState(p->mutable_states());
|
||||
}
|
||||
|
||||
ColliderComponent* Human::GetBoxBound()
|
||||
{
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
collider->owner = this;
|
||||
collider->pos = Vector2D();
|
||||
collider->rad = GetRadius();
|
||||
return collider;
|
||||
}
|
||||
|
||||
void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb)
|
||||
{
|
||||
stats_pb->set_player_id(entity_uniid);
|
||||
@ -180,6 +171,19 @@ void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb)
|
||||
stats_pb->set_account_id(account_id);
|
||||
}
|
||||
|
||||
void Human::GetAabbBox(AabbCollider& aabb_box)
|
||||
{
|
||||
if (!meta) {
|
||||
abort();
|
||||
}
|
||||
aabb_box.active = true;
|
||||
aabb_box.owner = this;
|
||||
aabb_box._min.x = -meta->i->radius();
|
||||
aabb_box._min.y = -meta->i->radius();
|
||||
aabb_box._max.x = meta->i->radius();
|
||||
aabb_box._max.y = meta->i->radius();
|
||||
}
|
||||
|
||||
void Human::FillMFTeamData(cs::MFTeamData* team_data)
|
||||
{
|
||||
team_data->set_player_id(entity_uniid);
|
||||
@ -1138,70 +1142,34 @@ void Human::DoSkill()
|
||||
|
||||
void Human::FindLocation()
|
||||
{
|
||||
{
|
||||
std::vector<Entity*> objects;
|
||||
room->BuildingBoxBoundCollisionDetection(this, objects);
|
||||
if (objects.size() > 1) {
|
||||
#if 0
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
if (!objects.empty()) {
|
||||
Building* building = (Building*)objects[0];
|
||||
Vector2D b_min = Vector2D(
|
||||
building->pos.x - building->meta->i->tilewidth()/2.0,
|
||||
building->pos.y - building->meta->i->tileheight()/2.0
|
||||
);
|
||||
Vector2D b_max = Vector2D(
|
||||
building->pos.x + building->meta->i->tilewidth()/2.0,
|
||||
building->pos.y + building->meta->i->tileheight()/2.0
|
||||
);
|
||||
Vector2D new_pos;
|
||||
bool ret = CalcCircleAabbSafePoint(
|
||||
pos,
|
||||
GetRadius(),
|
||||
b_min,
|
||||
b_max,
|
||||
new_pos
|
||||
);
|
||||
if (!ret) {
|
||||
abort();
|
||||
}
|
||||
if (ret) {
|
||||
pos = new_pos;
|
||||
room->grid_service.MoveHuman(this);
|
||||
return;
|
||||
Entity* target = nullptr;
|
||||
for (auto& grid : grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Obstacle:
|
||||
{
|
||||
if (!target) {
|
||||
if (TestCollision(entity)) {
|
||||
target = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ET_Building:
|
||||
{
|
||||
if (!target || target->entity_type != ET_Building) {
|
||||
AabbCollider aabb_box;
|
||||
entity->GetAabbBox(aabb_box);
|
||||
if (TestCollision(&aabb_box)) {
|
||||
target = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<Entity*> objects;
|
||||
for (auto& grid : grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Obstacle:
|
||||
{
|
||||
if (TestCollision(entity)){
|
||||
objects.push_back(entity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objects.empty()) {
|
||||
return;
|
||||
}
|
||||
std::sort(objects.begin(), objects.end(),
|
||||
[this] (Entity* a, Entity *b) -> bool
|
||||
{
|
||||
return (this->pos - a->pos).Norm() < (this->pos - b->pos).Norm();
|
||||
});
|
||||
Entity* target = objects[0];
|
||||
if (target) {
|
||||
FindLocationWithTarget(target);
|
||||
}
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ class Human : public Entity
|
||||
virtual float GetSpeed4();
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override;
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
|
||||
virtual ColliderComponent* GetBoxBound() override;
|
||||
virtual void FillMFPlayerStats(cs::MFPlayerStats* stats);
|
||||
virtual void GetAabbBox(AabbCollider& aabb_box);
|
||||
void FillMFTeamData(cs::MFTeamData* team_data);
|
||||
void Shot(Vector2D& target_dir);
|
||||
void RecalcSelfCollider();
|
||||
|
@ -132,21 +132,6 @@ void Obstacle::FillMFObjectFull(cs::MFObjectFull* full_data)
|
||||
}
|
||||
}
|
||||
|
||||
ColliderComponent* Obstacle::GetBoxBound()
|
||||
{
|
||||
if (self_collider_) {
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
*collider = *self_collider_;
|
||||
return collider;
|
||||
}
|
||||
if (self_collider2_) {
|
||||
AabbCollider* collider = new AabbCollider();
|
||||
*collider = *self_collider2_;
|
||||
return collider;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Obstacle::GetAabbBox(AabbCollider& aabb_box)
|
||||
{
|
||||
if (self_collider2_) {
|
||||
|
@ -41,7 +41,6 @@ class Obstacle : public Entity
|
||||
void RecalcSelfCollider();
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override;
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
|
||||
virtual ColliderComponent* GetBoxBound() override;
|
||||
virtual void GetAabbBox(AabbCollider& aabb_box) override;
|
||||
virtual void GetCircleBox(CircleCollider& circle_box) override;
|
||||
void Explosion(Bullet* bullet);
|
||||
|
@ -324,21 +324,6 @@ Human* Room::FindEnemy(Human* hum)
|
||||
return !enemys.empty() ? enemys[0] : nullptr;
|
||||
}
|
||||
|
||||
void Room::BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects)
|
||||
{
|
||||
ColliderComponent* a_collider = sender->GetBoxBound();
|
||||
for (auto& pair : uniid_hash_) {
|
||||
if (pair.second->entity_type == ET_Building) {
|
||||
ColliderComponent* target_collider = pair.second->GetBoxBound();
|
||||
if (a_collider->Intersect(target_collider)) {
|
||||
objects.push_back(pair.second);
|
||||
}
|
||||
DestoryCollider(target_collider);
|
||||
}
|
||||
}
|
||||
DestoryCollider(a_collider);
|
||||
}
|
||||
|
||||
void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg)
|
||||
{
|
||||
msg.set_team_mode(msg.team_mode());
|
||||
@ -873,9 +858,9 @@ void Room::UpdateGas()
|
||||
{
|
||||
if (a8::HasBitFlag(hum->status, HS_Fly)) {
|
||||
hum->DoJump();
|
||||
if (hum->entity_subtype == EST_Player) {
|
||||
GameLog::Instance()->GameStart((Player*)hum);
|
||||
}
|
||||
}
|
||||
if (hum->entity_subtype == EST_Player) {
|
||||
GameLog::Instance()->GameStart((Player*)hum);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
@ -62,7 +62,6 @@ public:
|
||||
void AddPlayer(Player* hum);
|
||||
Human* FindEnemy(Human* hum);
|
||||
|
||||
void BuildingBoxBoundCollisionDetection(Entity* sender, std::vector<Entity*>& objects);
|
||||
void RemoveObjectLater(Entity* entity);
|
||||
|
||||
void FetchBuilding(Human* hum);
|
||||
|
Loading…
x
Reference in New Issue
Block a user