C++ 水平碰撞不工作AABB C++;

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”

更新

再次更改了碰撞代码,并为AABB制作了一个组件,现在看来问题只出现在水平碰撞上,它不会按它认为的那样推动对象,而是与Y轴相同的代码,因此不应该是问题

(它确实检测到水平碰撞,但分辨率是个问题)

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;
        }
    }
}