Нестыковки обнаружение столкновений


Мне вот интересно о простом столкновении в C++ для некоторое время теперь, и я пытался сделать мой собственный код.

Код ниже работает, когда стены находятся в идеальном прямоугольник вокруг игрока. Однако, как только вы случайно разместить их в массиве, как в коде, странные нестыковки происходят. Иногда игрок попадается, иногда игрок не.

Если кто будет так добр, как указать, что ошибка, Я был бы очень признателен. В ясный шаг за шагом образом, если вы хотели: я очень новой для этого и шансы малы, что я могу сделать логические шаги, мысли, необходимые для успешной реализации Вашего предложения.

#include "string.h" 
#include "surface.h" 
#include "stdlib.h" 
#include "template.h" 
#include "game.h" 

using namespace Tmpl8; 

int pacmanPosX = 32; 
int pacmanPosY = 32; 
int indexX; 
int indexY; 

bool colR; 
bool colL; 
bool colU; 
bool colD; 


Sprite pacman (new Surface( "assets/pacmanLeft.png"), 1);  

Surface* tileSet[3];  

int levelMap[8][8] =  
{{1,1,1,1,1,1,1,1}, 
 {1,0,0,0,0,0,0,1}, 
 {1,0,0,0,0,1,0,1}, 
 {1,0,0,1,0,0,0,1}, 
 {1,0,0,0,1,0,0,1},  
 {1,1,0,0,1,1,1,1}, 
 {1,0,0,0,0,0,1,1}, 
 {1,1,1,1,1,1,1,1}}; 

void Game::Init()  
{  
   // put your initialization code here; will be executed once  
   tileSet[0] = new Surface( "assets/pacmanFloor.png" ); // Sets up data for tileSet  
   tileSet[1] = new Surface( "assets/pacmanWall.bmp" );  
   tileSet[2] = new Surface( "assets/pacmanCookie.png" ); 

}  

void Game::Tick( float a_DT )  
{  
    m_Screen->Clear( 0 );  

     for (indexX = 0; indexX < 8; indexX++) 
    { 
        for (indexY = 0; indexY < 8; indexY++) 
        { 
            int tile = levelMap[indexY][indexX]; 
            tileSet[tile]->CopyTo( m_Screen, indexX * 32, indexY * 32 ); 
        } 
    } 



    pacman.Draw(pacmanPosX, pacmanPosY, m_Screen); 


    //Defining collision requirements for walls// 

    if(levelMap[(pacmanPosX+32)/32][pacmanPosY/32] == 1) //Right collision 
    { 
        colR = true; 
    }else colR = false; 

    if(levelMap[(pacmanPosX-2)/32][pacmanPosY/32] == 1) //Left collision 
    { 
        colL = true; 
    }else colL = false; 

    if(levelMap[pacmanPosX/32][(pacmanPosY-2)/32] == 1) //Upward collision 
    { 
        colU = true; 
    }else colU = false; 

    if(levelMap[pacmanPosX/32][(pacmanPosY+32)/32] == 1) //Downward collision 
    { 
        colD = true; 
    }else colD = false; 


    //Setting Up Controls// 

    if (GetAsyncKeyState(VK_RIGHT) && colR == false){pacmanPosX += 2;} 
    if (GetAsyncKeyState(VK_LEFT) && colL == false){pacmanPosX -= 2;} 
    if (GetAsyncKeyState(VK_UP) && colU == false){pacmanPosY -= 2;} 
    if (GetAsyncKeyState(VK_DOWN) && colD == false){pacmanPosY += 2;} 

    Sleep( 10 );  
}  


376
2
задан 17 октября 2011 в 01:10 Источник Поделиться
Комментарии
1 ответ

Ошибка в коде

Здесь вы обращаетесь к levelMap по " Y "затем " х"

        int tile = levelMap[indexY][indexX]; 

Во всех остальных местах вы обращаетесь к levelMap на 'Х' потом 'y'

if(levelMap[(pacmanPosX+32)/32][pacmanPosY/32] == 1) //Right collision 

Так это выглядит, как вы работаете вокруг лабиринта, который был неправильно напечатан на экране. и таким образом, похоже, что обнаружение столкновений не работает (наверное), но обнаружения не соответствует визуальные подсказки.

Просмотрев ваш код:

Эти выражения

if(levelMap[(pacmanPosX+32)/32][pacmanPosY/32] == 1) //Right collision 
{
colR = true;
}else colR = false;

Может быть слишком упрощает:

colR = (levelMap[(pacmanPosX+32)/32][pacmanPosY/32] == 1); //Right collision 

Хотя эти

if (GetAsyncKeyState(VK_RIGHT) && colR == false){pacmanPosX += 2;} 

может быть упрощен до:

if (GetAsyncKeyState(VK_RIGHT) && !colR)
{ pacmanPosX += 2;
}

Положив заявление на той же строке, что тест делает его более трудным для отладки (Когда шагая через отладчик), как можно не увидеть, когда инструкции выполняются. Поставив его на своей строке пошагово с де-педераст станет легче, как вы увидите его пропустить оператор, когда условие не выполняется.

Глобальное состояние-это простой способ сделать вещи.

int pacmanPosX = 32; 
int pacmanPosY = 32;
int indexX;
int indexY;

bool colR;
bool colL;
bool colU;
bool colD;

Но в долгосрочной перспективе делает ваш код более хрупким и труднее обновить. Передать вещи в качестве параметров, чтобы сделать его легче поддерживать и расширять свой код (или создать объект, который обертывает информации).

Также похоже, что некоторые из этих свойств будут лучше проходить в массивы, а не отдельных переменных.

Редактирование базы на комментарии:

Это обнаруживает только столкновение, если в верхнем правом углу натыкаешься на стену.

colR = (levelMap[(pacmanPosX+32)/32][pacmanPosY/32] == 1); //Right collision 

Тоже меняются:

colR =    (levelMap[(pacmanPosX+33)/32][(pacmanPosY+00)/32] == 1)  // Top right
|| (levelMap[(pacmanPosY+33)/32][(pacmanPosY+31)/32] == 1); // bottom right

// Use +33 because moving left you use -2
// When you move right +32 puts you in the first pixel of the next block
// +33 puts you in the second pixel just like move left detection

// Use +31 on the Y access because this is still inside the current sprite.

Если у вас есть отверстие в стене это только один блок в ширину нужно будет ударить его мертвой точке, чтобы пройти через щель. Чтобы дать вам пространство для маневра вы можете перемещать углы в слегка.

colR =    (levelMap[(pacmanPosX+33)/32][(pacmanPosY+02)/32] == 1)  // Top right
|| (levelMap[(pacmanPosY+33)/32][(pacmanPosY+29)/32] == 1); // bottom right

Здесь вам не нужно попасть в дырку в стене, мертвой точкой и вы получите некоторое пространство для маневра, проходящей через.

1
ответ дан 17 октября 2011 в 01:10 Источник Поделиться