玩家移动和碰撞之间的交互问题



我一直在尝试创建一个自上而下的游戏,类似于'疯狂之神之境'的游戏。我在让我的球员移动与我的球员移动一起正常运行时遇到了一些问题。

要记住的一些事情。我的播放器的每一侧都有 4 个缓冲区,厚度为 1 像素。当玩家以 1 像素的速度与墙壁碰撞时,玩家将停止并按预期行事。

这就是问题所在。我希望我的播放器移动速度超过 1 像素,但是当我将玩家速度增加到 4 像素时,播放器将移动到墙中。这是有道理的,但我已经采取措施避免这种情况,但到目前为止还没有成功。

代码示例 1 显示了移动代码。

代码示例 2 显示移动触发器代码。

我已将其余代码放在GitHub上,可以通过以下链接找到:https://github.com/Quinn-R/top-down-tech-demo

感谢我得到的任何帮助。

编辑:我的球员没有完全超过墙。播放器和墙壁都是 32 像素的盒子。

编辑 2:代码示例 3 是显示游戏循环的代码。

代码示例 1

void player::move(std::string direction, std::vector<wall> walls)
{
if(direction == "left")
{
for(int i = 0; i < walls.size(); i++)
{
if(leftBuf.getGlobalBounds().intersects(walls[i].wall1.getGlobalBounds())/* || leftBuf.getGlobalBounds().intersects(walls2[i].wall1.getGlobalBounds())*/)
{
//collideTop = 0;
//collideBottom = 0;
collideLeft = 1;
//collideRight = 0;
}
}
if(collideLeft != 1)
{
character.move(-1, 0);
collideTop = 0;
collideBottom = 0;
collideLeft = 0;
collideRight = 0;
}
}
if(direction == "right")
{
for(int i = 0; i < walls.size(); i++)
{
if(rightBuf.getGlobalBounds().intersects(walls[i].wall1.getGlobalBounds())/* || rightBuf.getGlobalBounds().intersects(walls2[i].wall1.getGlobalBounds())*/)
{
//collideTop = 0;
//collideBottom = 0;
//collideLeft = 0;
collideRight = 1;
}
}
if(collideRight != 1)
{
character.move(1, 0);
collideTop = 0;
collideBottom = 0;
collideLeft = 0;
collideRight = 0;
}
}
if(direction == "up")
{
for(int i = 0; i < walls.size(); i++)
{
if(topBuf.getGlobalBounds().intersects(walls[i].wall1.getGlobalBounds())/* || topBuf.getGlobalBounds().intersects(walls2[i].wall1.getGlobalBounds())*/)
{
collideTop = 1;
//collideBottom = 0;
//collideLeft = 0;
//collideRight = 0;
}
}
if(collideTop != 1)
{
character.move(0, -1);
collideTop = 0;
collideBottom = 0;
collideLeft = 0;
collideRight = 0;
}
}
if(direction == "down")
{
for(int i = 0; i < walls.size(); i++)
{
if(bottomBuf.getGlobalBounds().intersects(walls[i].wall1.getGlobalBounds())/* || bottomBuf.getGlobalBounds().intersects(walls2[i].wall1.getGlobalBounds()*/)
{
//collideTop = 0;
collideBottom = 1;
//collideLeft = 0;
//collideRight = 0;
}
}
if(collideBottom != 1)
{
character.move(0, 1);
collideTop = 0;
collideBottom = 0;
collideLeft = 0;
collideRight = 0;
}
}
}

代码示例 2

void sfml1::buttonPressed()
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
for(int i = 0; i < speed; i++)
{
players[0].move("left", walls);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
for(int i = 0; i < speed; i++)
{
players[0].move("right", walls);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
for(int i = 0; i < speed; i++)
{
players[0].move("up", walls);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
for(int i = 0; i < speed; i++)
{
players[0].move("down", walls);
}
}
}    

代码示例 3

void sfml1::sfmlLoop()
{
setWalls();
while(window.isOpen())
{
update();
buttonPressed();
update();
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
/*if (event.type == sf::Event::Resized)
{
// update the view to the new size of the window
//event.size.width, event.size.height);
//view1.setWidth();
//view1.setViewport(sf::FloatRect(0, 0, 1, 1.5f));
view1.scale(1, 1);
window.setView(view1);
}*/
}
draw();
}
}

在 buttonPressed(( 函数中,角色的状态由其碰撞缓冲区定义。当您进行此调用时:

for(int i = 0; i < speed; i++)
{
players[0].move("right", walls);
}

move(( 函数有可能改变玩家的状态,但这不会反映在玩家的碰撞缓冲区中。您将速度时间向右移动,同时从初始位置速度时间进行碰撞检查。

您需要做的就是在 move(( 函数结束时调用 bufUpdate((。这将确保在解决移动后,您的碰撞缓冲区将更新。

最新更新