C++ 水平碰撞不工作AABB C++;
更新 再次更改了碰撞代码,并为AABB制作了一个组件,现在看来问题只出现在水平碰撞上,它不会按它认为的那样推动对象,而是与Y轴相同的代码,因此不应该是问题 (它确实检测到水平碰撞,但分辨率是个问题)C++ 水平碰撞不工作AABB C++;,c++,aabb,C++,Aabb,更新 再次更改了碰撞代码,并为AABB制作了一个组件,现在看来问题只出现在水平碰撞上,它不会按它认为的那样推动对象,而是与Y轴相同的代码,因此不应该是问题 (它确实检测到水平碰撞,但分辨率是个问题) void Hermes\u玩家::碰撞(游戏对象*其他) { 如果(其他->GetTag()=“墙”){ AABB*myAABB=dynamic_cast(此->获取组件(“AABB”); AABB*otherAABB=dynamic_cast(other->GetComponent(“AABB”
void Hermes\u玩家::碰撞(游戏对象*其他)
{
如果(其他->GetTag()=“墙”){
AABB*myAABB=dynamic_cast(此->获取组件(“AABB”);
AABB*otherAABB=dynamic_cast(other->GetComponent(“AABB”);
如果(abs(myAABB->lastCenter.x-otherAABB->lastCenter.x)halfCenter.x+otherAABB->halfCenter.x){
标准::cout center.y){
整数距离=(myAABB->halfCenter.y+otherAABB->halfCenter.y)-(otherAABB->center.y-myAABB->center.y);
此->位置.y-=距离;
myAABB->center.y=(myAABB->center.y-距离);
}
如果(myAABB->center.y>其他aabb->center.y){
整数距离=(myAABB->halfCenter.y+otherAABB->halfCenter.y)-(myAABB->center.y-otherAABB->center.y);
此->位置.y+=距离;
myAABB->center.y=(myAABB->center.y+距离);
}
}
其他的
{
标准::cout half center.x;
intdif=(这个->大小.x+其他->大小.x)/2-abs(距离);
如果(myAABB->center.xcenter.x){
int distance=(myAABB->halfCenter.x+otherAABB->halfCenter.x)-(otherAABB->center.x-myAABB->center.x);
此->位置.x-=距离;
myAABB->center.x=(myAABB->center.x-距离);
}
如果(myAABB->center.x>otherAABB->center.x){
int distance=(myAABB->halfCenter.x+otherAABB->halfCenter.x)-(myAABB->center.x-otherAABB->center.x);
此->位置.x+=距离;
myAABB->center.x=(myAABB->center.x+距离);
}
std::cout Position.x我没有调试/阅读整个代码,但这看起来像是一个典型的问题。一旦检测到碰撞,就可以通过单一方向和穿透来解决
发生的情况是,在移动和碰撞之后,在一个轴上进行解析可能会使另一个轴上仍然存在碰撞。然后,所有这些都会崩溃
或者,可能是您与两个对象发生碰撞,解析第二个对象会使您回到已经调整过的对象
至少,在调整回位置后,您需要检查所有对象是否都已清除。这可能不是您要查找的,但同时尝试解析X轴和Y轴可能相当复杂
一种解决方案可能是独立步进每个轴,并分别解决它们的碰撞
您必须执行两次碰撞检测,但这会使分辨率更简单,即不必检查碰撞分辨率是否会导致更多碰撞,只需停止沿第一个碰撞对象的边缘移动即可
这篇文章在我开发自己的2D平台时帮助了我,它推荐了这种做法:
与问题无关,但GetComponent::DoCollision()
正在使用相同的输入对象多次调用Collider->DoCollision()
。您应该只调用一次,并将结果缓存到局部变量中,以便根据需要使用,例如:CollisionData cd=Collider->DoCollision(*object1,*object2);…std::get(cd)…std::get(cd)…std::get(cd)…
和您的if
语句可以简化一点:if(std::get(cd)){if(object2->Solid){…return Solid;}else{return TRIGGER;}else{return NO_COLLISION;}}
void Hermes_Player::Collision(GameObject * other)
{
if (other->GetTag() == "wall") {
AABB* myAABB = dynamic_cast<AABB*>(this->GetComponent("aabb"));
AABB* otherAABB = dynamic_cast<AABB*>(other->GetComponent("aabb"));
if (abs(myAABB->lastCenter.x - otherAABB->lastCenter.x) < myAABB->halfCenter.x + otherAABB->halfCenter.x) {
std::cout << "y" << std::endl;
if (myAABB->center.y < otherAABB->center.y) {
int distance = (myAABB->halfCenter.y + otherAABB->halfCenter.y) - (otherAABB->center.y - myAABB->center.y);
this->Position.y -= distance;
myAABB->center.y = (myAABB->center.y - distance);
}
if (myAABB->center.y > otherAABB->center.y) {
int distance = (myAABB->halfCenter.y + otherAABB->halfCenter.y) - (myAABB->center.y - otherAABB->center.y);
this->Position.y += distance;
myAABB->center.y = (myAABB->center.y + distance);
}
}
else
{
std::cout << "x" << std::endl;
int dist = myAABB->halfCenter.x + otherAABB->halfCenter.x;
int dif = (this->Size.x + other->Size.x) /2- abs(dist);
if (myAABB->center.x < otherAABB->center.x) {
int distance = (myAABB->halfCenter.x + otherAABB->halfCenter.x) - (otherAABB->center.x - myAABB->center.x);
this->Position.x -= distance;
myAABB->center.x = (myAABB->center.x - distance);
}
if (myAABB->center.x > otherAABB->center.x) {
int distance = (myAABB->halfCenter.x + otherAABB->halfCenter.x) - (myAABB->center.x - otherAABB->center.x);
this->Position.x += distance;
myAABB->center.x = (myAABB->center.x + distance);
}
std::cout << this->Position.x << std::endl;
}
}
}