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

发布于 2024-12-09 07:24:17 字数 2390 浏览 0 评论 0原文

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

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,包括角色。

so I'm making a really simple program in which I want one sprite to collide with another.
I made a 'level' by making a grid with images, using a two-dimensional array.
How would I implement simple collision? I would appreciate coding examples, so I can actually see
what's going on. Thanks. Here's the code:

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


}

That doesn't work, the character can't move at all now. For your information, every sprite is
32x32, including the character.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

栖迟 2024-12-16 07:24:18

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

如果你遇到任何障碍请告诉我

编辑

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

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

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

如果碰撞为真,那么您在距离您的位置向上一像素的地方发生碰撞,这就是-1计算中的colPosY为。

编辑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];
}

if you calculate the position of the pacman to correspond to the landTitle array by dividing the pacmanPosX and pacmanPosY with the size of each square (32) and then cast it to an int. then you could simply check if the position in front of you is set to 1 or 0 in the landTile and in that way you can get a very simple and fast collision.

Tell me if you get into any hindrance

EDIT

What I mean is that you an array that explains where all the walls should be in your map. Because of that you don't have to do any sprite collision, instead you can do a simple collision check based on where you are supposed to be in the array. Lets consider the case where you are supposed to move up on the map:

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

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

if collision is true then you have a collision one pixel upwards from your position, thats what the -1 in the calculation of colPosY is for.

Edit 2

If i should edit your code then I would do it more like this

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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文