在二维数组中与.bmp的简单碰撞?

时间:2011-10-12 10:58:15

标签: c++ collision

所以我制作了一个非常简单的程序,其中我希望一个精灵与另一个精灵碰撞。 我通过使用二维数组制作带图像的网格来制作“关卡”。 我该如何实现简单的碰撞?我很感激编码示例,所以我实际上可以看到 这是怎么回事。谢谢。这是代码:

int pacmanPosX = 32;
int pacmanPosY = 32;

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

Surface* tileSet[2];
int landTile[14][16] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 1, 1, 1, 1, 1, 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/tiles/void.bmp" ); // Sets up data for tileSet
   tileSet[1] = new Surface( "assets/tiles/wall.bmp" );

}

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

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

    pacman.Draw(pacmanPosX, pacmanPosY, m_Screen);



    Sleep( 10 );

int colPosX =  pacmanPosX    / 32; 
int colPosY = (pacmanPosY-1) / 32; 

bool collision = (bool)landTile[colPosX][colPosY]; 


int direction;

if(collision = false)
{
    if (GetAsyncKeyState( VK_UP )) pacmanPosY -=2;
    if (GetAsyncKeyState( VK_DOWN ))  pacmanPosY += 2;
    if (GetAsyncKeyState( VK_RIGHT )) pacmanPosX += 2;
    if (GetAsyncKeyState( VK_LEFT ))  pacmanPosX -= 2;
}


}

这不起作用,角色现在根本无法移动。每个精灵都是为了您的信息 32x32,包括角色。

1 个答案:

答案 0 :(得分:1)

如果你通过将pacmanPosX和pacmanPosY除以每个方块的大小(32)来计算pacman对应于landTitle数组的位置,然后将其转换为int。然后你可以简单地检查你前面的位置是否在landTile中设置为1或0,这样你就可以得到一个非常简单和快速的碰撞。

告诉我你是否遇到任何障碍

修改

我的意思是你是一个数组,解释地图中所有墙应该在哪里。因此,您不必进行任何精灵碰撞,而是可以根据您应该在阵列中的位置进行简单的碰撞检查。让我们考虑你应该在地图上向上移动的情况:

int colPosX =  pacmanPosX    / 32;
int colPosY = (pacmanPosY-1) / 32;

bool collision = (bool)landTitle[colPosX][colPosY];

如果碰撞为真,那么你的位置向上有一个像素的碰撞,那就是 colPosY 计算中的 -1 是为了。

修改2

如果我应该编辑你的代码,那么我会更喜欢这样做

int blockSize = 32;
int pacmanPosX = blockSize * 1;
int pacmanPosY = blockSize * 1;

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

Surface* tileSet[2];
int landTile[14][16] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,},
                        {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,},
                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,},
                        {1, 1, 1, 1, 1, 1, 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/tiles/void.bmp" ); // Sets up data for tileSet
   tileSet[1] = new Surface( "assets/tiles/wall.bmp" );

}

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

    for (int indexX = 0; indexX <= 14; indexX++)
    {
        for (int indexY = 0; indexY <= 16; indexY++)
        {
            int tile = landTile[indexY][indexX];
            tileSet[tile]->CopyTo( m_Screen, indexX * blockSize, indexY * blockSize );
        }
    }

    if (GetAsyncKeyState( VK_UP )    && CheckCollision(0,-1)) pacmanPosY -=2;
    if (GetAsyncKeyState( VK_DOWN )  && CheckCollision(0, 1)) pacmanPosY += 2;
    if (GetAsyncKeyState( VK_RIGHT ) && CheckCollision(1, 0)) pacmanPosX += 2;
    if (GetAsyncKeyState( VK_LEFT )  && CheckCollision(-1,0)) pacmanPosX -= 2;

    Sleep( 10 );
}

bool Game::CheckCollision(int dirX, int dirY){
    return (bool)landTile[(pacmanPosX+dirX)/blockSize][(pacmanPosY+dirY)/blockSize];
}