精灵与贴图的碰撞
Sprite collision with tile map
所以,我尝试着创造自己的游戏引擎,我的第一个项目便是创造一个《吃豆人》的克隆版本。我已经知道如何创建贴图并在上面移动吃豆人。但我在创建碰撞检测器时遇到了一些问题。特别的问题是,碰撞检测到当前位置以北的任何瓷砖都很好,但它认为当前位置以下的瓷砖实际上比正常情况大1个瓷砖。在当前位置的东面和西面的贴图不存在碰撞。我很困惑,因为碰撞适用于北瓦…但是我对其他方向使用了相同的逻辑,它不起作用。
我使用的逻辑是"ok"瓷砖移动到值为0。任何其他贴图都不能移动
下面是我用于实际墙壁碰撞的代码:
//checks for a sprite colliding with a wall tile
//direction refers to 1=North, 2=South, 3=West, 4=East
bool Wall_Collision(SPRITE sprite, int direction)
{
//grab center of sprite
Posx = sprite.x + Sprite_Radius;
Posy = sprite.y + Sprite_Radius;
//create rectangle for the sprite
RECT spriteRect;
spriteRect.left = (long)sprite.x;
spriteRect.top = (long)sprite.y;
spriteRect.right = (long)sprite.x + sprite.width * sprite.scaling;
spriteRect.bottom = (long)sprite.y + sprite.height * sprite.scaling;
//recover North tile info
int N_posx, N_posy;
int N_tilex, N_tiley;
int N_tilevalue;
N_posx = Posx / TILEWIDTH;
N_posy = (Posy - TILEHEIGHT) / TILEHEIGHT;
N_tilex = N_posx * TILEWIDTH;
N_tiley = N_posy * TILEHEIGHT;
N_tilevalue = MAPDATA[(N_posy * MAPWIDTH + N_posx)];
//create rectangle for tile North of sprite center
RECT northRect;
northRect.left = N_tilex;
northRect.top = N_tiley;
northRect.right = N_tilex + TILEWIDTH;
northRect.bottom = N_tiley + TILEHEIGHT;
//recover South tile info
int S_posx, S_posy;
int S_tilex, S_tiley;
int S_tilevalue;
S_posx = Posx / TILEWIDTH;
S_posy = (Posy + TILEHEIGHT) / TILEHEIGHT;
S_tilex = S_posx * TILEWIDTH;
S_tiley = S_posy * TILEHEIGHT;
S_tilevalue = MAPDATA[(S_posy * MAPWIDTH + S_posx)];
//create rectangle for tile South of sprite center
RECT southRect;
southRect.left = S_tilex;
southRect.top = S_tiley;
southRect.right = S_tilex + TILEWIDTH;
southRect.bottom = S_tiley + TILEHEIGHT;
//recover West tile info
int W_posx, W_posy;
int W_tilex, W_tiley;
int W_tilevalue;
W_posx = (Posx - TILEWIDTH) / TILEWIDTH;
W_posy = Posy / TILEHEIGHT;
W_tilex = W_posx * TILEWIDTH;
W_tiley = W_posy * TILEHEIGHT;
W_tilevalue = MAPDATA[(W_posy * MAPWIDTH + W_posx)];
//create rectangle for tile West of sprite center
RECT westRect;
westRect.left = W_tilex;
westRect.top = W_tiley;
westRect.right = W_tilex + TILEWIDTH;
westRect.bottom = W_tiley + TILEHEIGHT;
//recover East tile info
int E_posx, E_posy;
int E_tilex, E_tiley;
int E_tilevalue;
E_posx = (Posx + TILEWIDTH) / TILEWIDTH;
E_posy = Posy / TILEHEIGHT;
E_tilex = E_posx * TILEWIDTH;
E_tiley = E_posy * TILEHEIGHT;
E_tilevalue = MAPDATA[(E_posy * MAPWIDTH + E_posx)];
//create rectangle for tile East of sprite center
RECT eastRect;
eastRect.left = E_tilex;
eastRect.top = E_tiley;
eastRect.right = E_tilex + TILEWIDTH;
eastRect.bottom = E_tiley + TILEHEIGHT;
RECT dest; //ignored
//check North collision
if (direction == 1 && N_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &northRect);
}
else return false;
//check South collision
if (direction == 2 && S_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &southRect);
}
else return false;
//check West collision
if (direction == 3 && W_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &westRect);
}
else return false;
//check East collision
if (direction == 4 && E_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &eastRect);
}
else return false;
}
然后是上下文,我使用这个函数来移动玩家精灵:
void MovePacman()
{
if (Wall_Collision(pacman, 1))
{
pacman.y -= pacman.vely;
pacman.vely = 0.0f;
}
else
{
if (Key_Down(DIK_UP))
{
pacman.vely = -0.2f;
pacman.velx = 0.0f;
}
}
if (Wall_Collision(pacman, 2))
{
pacman.y -= pacman.vely;
pacman.vely = 0.0f;
}
else
{
if (Key_Down(DIK_DOWN))
{
pacman.vely = 0.2f;
pacman.velx = 0.0f;
}
}
if (Wall_Collision(pacman, 3))
{
pacman.x -= pacman.velx;
pacman.velx = 0.0f;
}
else
{
if (Key_Down(DIK_LEFT))
{
pacman.velx = -0.2f;
pacman.vely = 0.0f;
}
}
if (Wall_Collision(pacman, 4))
{
pacman.x -= pacman.velx;
pacman.velx = 0.0f;
}
else
{
if (Key_Down(DIK_RIGHT))
{
pacman.velx = 0.2f;
pacman.vely = 0.0f;
}
else;
}
if (pacman.vely < 0)
Sprite_Animate(pacman.frame, pacman.startframe, 18, 4, pacman.starttime, 250);
else if (pacman.vely > 0)
Sprite_Animate(pacman.frame, pacman.startframe, 16, 2, pacman.starttime, 250);
else if (pacman.velx < 0)
Sprite_Animate(pacman.frame, pacman.startframe, 17, 3, pacman.starttime, 250);
else if (pacman.velx > 0)
Sprite_Animate(pacman.frame, pacman.startframe, 15, 1, pacman.starttime, 250);
pacman.y += pacman.vely;
pacman.x += pacman.velx;
}
相信我已经正确地定义了所有未粘贴和链接头的内容。知道我哪里做错了吗?
你只在一种情况下检查碰撞:
//check North collision
if (direction == 1 && N_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &northRect);
}
else return false; // <--- this
//check South collision
if (direction == 2 && S_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &southRect);
}
else return false; // <--- and this, etc...
请参阅上面突出显示的行。如果它不测试北碰撞(即,如果direction
不是1
或N_tilevalue
是0
),那么函数在所有其他情况下都返回该点。它不能继续做其他的碰撞检查
相关文章:
- 落砂模拟碰撞检测C++和SFML
- SFML 碰撞永远不会在我的系统中注册
- OpenGL 着色器不绘制任何东西 - 糟糕的精灵类
- 在均匀网格中处理碰撞
- 从精灵表在 sfml 中为精灵制作动画
- 平台游戏 - 下车时避免与平台碰撞
- AABB 碰撞使实际精灵的大小翻倍
- 如何在精灵表上的两个不同部分之间来回切换,同时用户仍使用 SFML 持有密钥
- 具有随机值的多个对象及其碰撞的 SFML
- SFML 中的重力和碰撞检测
- 我的精灵使用名为 ASGE 的C++框架卡在屏幕边缘
- 我的碰撞检测中的奇怪行为
- Box2D Contact Listener碰撞仅间歇性工作
- 如何为球形物体和三角形地形提供高效的碰撞检测和响应
- 如何为精灵编写复制构造函数
- 同时与两个片段着色器发生碰撞
- 绘制精灵会导致分割错误
- 在单独列表中的两个精灵的碰撞
- 精灵与贴图的碰撞
- 使用矢量和multimap的特定贴图和精灵之间的边界框碰撞