2010-04-04 4 views
1
  • EDIT - 코드가 이상하게 보입니다. 따라서 링크에서 파일을 직접 보는 것이 좋습니다.

내 엔진에서 작업하는 동안 해결할 수없는 문제가 발생했습니다. 무거운 수정없이이 문제를 해결하기를 원한다면 코드는 아래와 같습니다.'new'를 사용하여 인스턴스를 만든 후 스택 오버플로 오류가 발생했습니다.

void Block::DoCollision(GameObject* obj){ 
obj->DoCollision(this); 
} 

여기서 스택 오버플로가 발생합니다. 이 응용 프로그램은 new 키워드를 사용하여 클래스의 두 인스턴스를 만들 때까지 완벽하게 작동합니다. 클래스의 인스턴스가 1 개 밖에 없으면 제대로 작동합니다.

Block* a = new Block(0, 0, 0, 5); 
AddGameObject(a); 
a = new Block(30, 0, 0, 5); 
AddGameObject(a); 

이러한 매개 변수는 x, y, z 및 크기입니다.

코드를 직접 확인합니다. 일치하는 Collisonflag 및 충돌 유형이있는 객체 만 DoCollision()을 트리거합니다. 기능.

((*list1)->m_collisionFlag & (*list2)->m_type) 

어쩌면 내 수표가 엉망이 될 수도 있습니다. 여기에 관련 파일을 첨부했습니다 http://celestialcoding.com/index.php?topic=1465.msg9913;topicseen#new. 가입하지 않고 다운로드 할 수 있습니다. 주요 용의자, 나는 또한 아래에 대한 코드를 붙여 넣습니다.

GameManager.cpp

에서
void GameManager::Update(float dt){ 
GameList::iterator list1; 

for(list1=m_gameObjectList.begin(); list1 != m_gameObjectList.end(); ++list1){ 
    GameObject* temp = *list1; 

    // Update logic and positions 
    if((*list1)->m_active){ 
    (*list1)->Update(dt); 
// Clip((*list1)->m_position); // Modify for bounce affect 
    } else continue; 

    // Check for collisions 
    if((*list1)->m_collisionFlag != GameObject::TYPE_NONE){ 
    GameList::iterator list2; 
    for(list2=m_gameObjectList.begin(); list2 != m_gameObjectList.end(); ++list2){ 
    if(!(*list2)->m_active) 
    continue; 
    if(list1 == list2) 
    continue; 
    if((*list2)->m_active && 
    ((*list1)->m_collisionFlag & (*list2)->m_type) && 
    (*list1)->IsColliding(*list2)){ 
     (*list1)->DoCollision((*list2)); 
    } 
    } 
    } 
    if(list1==m_gameObjectList.end()) break; 
} 
GameList::iterator end    = m_gameObjectList.end(); 
GameList::iterator newEnd = remove_if(m_gameObjectList.begin(),m_gameObjectList.end(),RemoveNotActive); 
if(newEnd != end) 
       m_gameObjectList.erase(newEnd,end); 
} 

void GameManager::LoadAllFiles(){ 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Top.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Right.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Back.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Left.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Front.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Models/Skybox/Images/Bottom.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Terrain/Textures/Terrain1.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Terrain/Textures/Terrain2.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Terrain/Details/TerrainDetails.bmp", GetNextFreeID()); 
LoadSkin(m_gameTextureList, "Terrain/Textures/Water1.bmp", GetNextFreeID()); 




Block* a = new Block(0, 0, 0, 5); 
AddGameObject(a); 
a = new Block(30, 0, 0, 5); 
AddGameObject(a); 
Player* d = new Player(0, 100,0); 
AddGameObject(d); 
} 



void Block::Draw(){ 

glPushMatrix(); 
    glTranslatef(m_position.x(), m_position.y(), m_position.z()); 
    glRotatef(m_facingAngle, 0, 1, 0); 
    glScalef(m_size, m_size, m_size); 
    glBegin(GL_LINES); 
    glColor3f(255, 255, 255); 
    glVertex3f(m_boundingRect.left, m_boundingRect.top, m_position.z()); 
    glVertex3f(m_boundingRect.right, m_boundingRect.top, m_position.z()); 
    glVertex3f(m_boundingRect.left, m_boundingRect.bottom, m_position.z()); 
    glVertex3f(m_boundingRect.right, m_boundingRect.bottom, m_position.z()); 

    glVertex3f(m_boundingRect.left, m_boundingRect.top, m_position.z()); 
    glVertex3f(m_boundingRect.left, m_boundingRect.bottom, m_position.z()); 
    glVertex3f(m_boundingRect.right, m_boundingRect.top, m_position.z()); 
    glVertex3f(m_boundingRect.right, m_boundingRect.bottom, m_position.z()); 
    glEnd(); 
// DrawBox(m_position.x(), m_position.y(), m_position.z(), m_size, m_size, m_size, 8); 
glPopMatrix(); 
} 

void Block::DoCollision(GameObject* obj){ 
GameObject* t = this;   // I modified this to see for sure that it was causing the mistake. 
// obj->DoCollision(NULL); // Just revert it back to 
/* 
void Block::DoCollision(GameObject* obj){   
      obj->DoCollision(this);   
    }   
    */ 

} 

답변

4

스택 오버 플로우는 보통 무한 재귀에서 온다. 귀하의 질문을 파싱하는 데 문제가 있습니다. 그러나 여기에 맞춰보십시오 :

void Block::DoCollision(GameObject* obj){ 
    if (this != obj) { 
    obj->DoCollision(this); 
    } 
} 
+0

그게 문제를 해결하지 못했습니다. 스택 오버 플로우가 여전히 발생합니다. "Block"클래스의 단일 인스턴스 만 만들면 내 엔진이 완벽하게 실행되고 충돌을 완벽하게 감지합니다. 그러나 "Block"인스턴스를 두 번 생성하면 코드가 스택 오버플로를 발생시킵니다. 응용 프로그램을 디버깅 할 때 obj-> DoCollision (this);에서 충돌합니다. 블록은 플레이어와 충돌 만하도록 프로그래밍했기 때문에 서로 충돌하지 않습니다. 이전에 아무 대답도하지 않으려 고 노력했습니다. 다른 제안? – Justin

+0

다른 조합을 시도한 후에 나는 두 가지 조건을 사용하여 작동하도록했습니다. if(this != obj && obj->m_type != GameObject::TYPE_OBSTACLE) 내 충돌 감지 기능을 다시 구축해야하는 것처럼 보입니다. 고마워요, 당신은 큰 도움이되었습니다! – Justin

+0

멋지다, 당신이 그것을 발견했기 때문에 기쁘다! – Stephen

관련 문제