修复房间行走阻挡问题
This commit is contained in:
parent
03099c0e7c
commit
2fe179077b
@ -27,6 +27,9 @@ void Building::Initialize()
|
||||
|
||||
void Building::RecalcSelfCollider()
|
||||
{
|
||||
std::vector<AabbCollider*> collider_list;
|
||||
collider_list.reserve(meta->i->staticobj_size());
|
||||
|
||||
for (auto& obj : meta->i->staticobj()) {
|
||||
AabbCollider* collider = new AabbCollider();
|
||||
collider->owner = this;
|
||||
@ -35,8 +38,11 @@ void Building::RecalcSelfCollider()
|
||||
collider->_max = a8::Vec2(obj.x() + obj.width()/2.0 - meta->i->tilewidth()/2.0,
|
||||
obj.y() + obj.height()/2.0 - meta->i->tileheight()/2.0);
|
||||
AddCollider(collider);
|
||||
collider_list.push_back(collider);
|
||||
room->map_service.AddCollider(collider);
|
||||
}
|
||||
|
||||
AutoAdjust(collider_list);
|
||||
}
|
||||
|
||||
void Building::FillMFObjectPart(cs::MFObjectPart* part_data)
|
||||
@ -66,3 +72,46 @@ void Building::GetAabbBox(AabbCollider& aabb_box)
|
||||
aabb_box._max.x = meta->i->tilewidth()/2.0;
|
||||
aabb_box._max.y = meta->i->tileheight()/2.0;
|
||||
}
|
||||
|
||||
void Building::AutoAdjust(std::vector<AabbCollider*>& collider_list)
|
||||
{
|
||||
for (int dir = 0; dir < 4; ++dir) {
|
||||
for (size_t i = 0; i < collider_list.size(); ++i) {
|
||||
AabbCollider* a_collider = collider_list[i];
|
||||
for (size_t ii = i + 1; ii < collider_list.size(); ++ii) {
|
||||
AabbCollider* b_collider = collider_list[ii];
|
||||
|
||||
switch (dir) {
|
||||
case 0:
|
||||
{
|
||||
if (std::fabs(a_collider->_min.x - b_collider->_min.x) < 2.0f) {
|
||||
b_collider->_min.x = a_collider->_min.x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if (std::fabs(a_collider->_min.y - b_collider->_min.y) < 2.0f) {
|
||||
b_collider->_min.y = a_collider->_min.y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
if (std::fabs(a_collider->_max.x - b_collider->_max.x) < 2.0f) {
|
||||
b_collider->_max.x = a_collider->_max.x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
if (std::fabs(a_collider->_max.y - b_collider->_max.y) < 2.0f) {
|
||||
b_collider->_max.y = a_collider->_max.y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,4 +25,7 @@ class Building : public Entity
|
||||
virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override;
|
||||
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
|
||||
virtual void GetAabbBox(AabbCollider& aabb_box) override;
|
||||
|
||||
private:
|
||||
void AutoAdjust(std::vector<AabbCollider*>& collider_list);
|
||||
};
|
||||
|
@ -439,11 +439,22 @@ bool Human::IsCollisionInMapService()
|
||||
std::set<ColliderComponent*> colliders;
|
||||
room->map_service.GetColliders(GetX(), GetY(), colliders);
|
||||
|
||||
AabbCollider aabb_box;
|
||||
GetAabbBox(aabb_box);
|
||||
for (ColliderComponent* collider : colliders) {
|
||||
switch (collider->owner->entity_type) {
|
||||
case ET_Obstacle:
|
||||
{
|
||||
#if 1
|
||||
if (!collider->owner->dead &&
|
||||
(
|
||||
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) ||
|
||||
(collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider))
|
||||
)
|
||||
) {
|
||||
#else
|
||||
if (!collider->owner->dead && TestCollision((ColliderComponent*)collider)) {
|
||||
#endif
|
||||
if (last_collision_door != collider->owner) {
|
||||
Obstacle* obstacle = (Obstacle*)collider->owner;
|
||||
if (!obstacle->dead &&
|
||||
@ -476,7 +487,16 @@ bool Human::IsCollisionInMapService()
|
||||
break;
|
||||
case ET_Building:
|
||||
{
|
||||
#if 1
|
||||
if (!collider->owner->dead &&
|
||||
(
|
||||
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) ||
|
||||
(collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider))
|
||||
)
|
||||
) {
|
||||
#else
|
||||
if (!collider->owner->dead && TestCollision((ColliderComponent*)collider)) {
|
||||
#endif
|
||||
if (last_collision_door != collider->owner) {
|
||||
Global::last_collider = collider;
|
||||
return true;
|
||||
@ -572,61 +592,6 @@ void Human::FindPathInMapService()
|
||||
}
|
||||
}
|
||||
SetPos(old_pos);
|
||||
if (entity_subtype == EST_Player && last_collider && last_collider->type == CT_Aabb) {
|
||||
#if 0
|
||||
AabbCollider* aabb_collider = (AabbCollider*)last_collider;
|
||||
#endif
|
||||
if (GetPos().x > last_collider->owner->GetPos().x) {
|
||||
//在右边
|
||||
if (GetPos().y > last_collider->owner->GetPos().y) {
|
||||
//右上
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("右上\n", {});
|
||||
#endif
|
||||
if (move_dir.Dot(a8::Vec2(1, -1)) > 0.000002f) {
|
||||
SetPos(old_pos + a8::Vec2(2, 0));
|
||||
} else {
|
||||
SetPos(old_pos + a8::Vec2(0, 2));
|
||||
}
|
||||
} else {
|
||||
//右下
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("右下\n", {});
|
||||
#endif
|
||||
if (move_dir.Dot(a8::Vec2(-1, 1)) > 0.000002f) {
|
||||
SetPos(old_pos + a8::Vec2(2, 0));
|
||||
} else {
|
||||
SetPos(old_pos + a8::Vec2(0, -2));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//左边
|
||||
if (GetPos().y > last_collider->owner->GetPos().y) {
|
||||
//左上
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("左上\n", {});
|
||||
#endif
|
||||
if (move_dir.Dot(a8::Vec2(-1, -1)) > 0.000001f) {
|
||||
SetPos(old_pos + a8::Vec2(-2, 0));
|
||||
} else {
|
||||
SetPos(old_pos + a8::Vec2(0, 2));
|
||||
}
|
||||
} else {
|
||||
//左下
|
||||
#ifdef DEBUG
|
||||
a8::XPrintf("左下\n", {});
|
||||
#endif
|
||||
if (move_dir.Dot(a8::Vec2(1, -1)) > 0.000001f) {
|
||||
SetPos(old_pos + a8::Vec2(-2, 0));
|
||||
} else {
|
||||
SetPos(old_pos + a8::Vec2(0, -2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsCollisionInMapService()) {
|
||||
SetPos(old_pos);
|
||||
}
|
||||
}
|
||||
|
||||
float Human::GetRadius()
|
||||
@ -2003,6 +1968,49 @@ void Human::CheckSkinTank()
|
||||
|
||||
void Human::_UpdateMove(int speed)
|
||||
{
|
||||
#if 1
|
||||
float nx = move_dir.x * speed;
|
||||
float ny = move_dir.y * speed;
|
||||
a8::Vec2 old_pos = GetPos();
|
||||
|
||||
#if 1
|
||||
SetPos(old_pos + a8::Vec2(nx, ny));
|
||||
if (!IsCollisionInMapService()) {
|
||||
room->grid_service.MoveHuman(this);
|
||||
return;
|
||||
} else {
|
||||
if (Global::last_collider && Global::last_collider->type == CT_Circle) {
|
||||
SetPos(old_pos + a8::Vec2(nx, ny));
|
||||
if (self_collider_->Intersect(Global::last_collider)) {
|
||||
CircleCollider* circle_collider = (CircleCollider*)Global::last_collider;
|
||||
a8::Vec2 tmp_dir = GetPos() - (circle_collider->owner->GetPos() + circle_collider->pos);
|
||||
float len = circle_collider->rad + self_collider_->rad + 1;
|
||||
float rate = len - tmp_dir.Norm();
|
||||
tmp_dir.Normalize();
|
||||
a8::Vec2 new_dir = tmp_dir * rate;
|
||||
SetPos(GetPos() + new_dir);
|
||||
}
|
||||
if (!IsCollisionInMapService()) {
|
||||
room->grid_service.MoveHuman(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SetPos(old_pos + a8::Vec2(nx, 0));
|
||||
if (IsCollisionInMapService()) {
|
||||
nx = 0;
|
||||
}
|
||||
|
||||
SetPos(old_pos + a8::Vec2(nx, ny));
|
||||
if (IsCollisionInMapService()) {
|
||||
ny = 0;
|
||||
}
|
||||
|
||||
SetPos(old_pos + a8::Vec2(nx, ny));
|
||||
room->grid_service.MoveHuman(this);
|
||||
#else
|
||||
for (int i = 0; i < speed; ++i) {
|
||||
a8::Vec2 old_pos = GetPos();
|
||||
SetPos(GetPos() + move_dir);
|
||||
@ -2017,6 +2025,7 @@ void Human::_UpdateMove(int speed)
|
||||
}
|
||||
room->grid_service.MoveHuman(this);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Human::ClearFrameData()
|
||||
|
2
third_party/a8engine
vendored
2
third_party/a8engine
vendored
@ -1 +1 @@
|
||||
Subproject commit a369c484113b240f042c62cba80afd26df91e4ca
|
||||
Subproject commit 62cad93ca276670dc7280425df58916bacbe20e5
|
Loading…
x
Reference in New Issue
Block a user