这是我第一次尝试SFML和游戏开发,我遇到了碰撞和重力的问题。
我正在使用平铺地图系统制作2D平台游戏。
碰撞似乎在工作(轻微),但非常波涛汹涌,我似乎无法让重力正常工作。我尝试了一些不同的教程,但我什么都做不了,我现在有点不知所措。
如果有人能指出我在这里错过了什么,我将不胜感激!!
以下是我为这些元素使用的代码:
在PlayerSprite类(尝试重力)
PlayerSprite::PlayerSprite(const sf::Vector2f& size) : AnimatedSprite(size)
{
playerPos = (sf::Vector2f(300.0f, 400.0f));
dead = false;
jumpHeight = 5.f;
scale = 50.f;
accelGravity = 0.5f;
maxGravity = 5.f;
velocity.x = 2.0f;
velocity.y = 2.0f;
playerTexture.loadFromFile("gfx/spritemansheet.png");
setSize(sf::Vector2f(48, 48));
setPosition(playerPos);
setTexture(&playerTexture);
}
PlayerSprite::~PlayerSprite()
{
}
void PlayerSprite::update(float dt)
{
onGround = false;
if (input->isKeyDown(sf::Keyboard::A)) {
input->setKeyUp(sf::Keyboard::A);
playerPos.x -= (dt * step) * 5;
setPosition(playerPos);
//currentAnimation = &walkBack;
}
if (input->isKeyDown(sf::Keyboard::D)) {
input->setKeyUp(sf::Keyboard::D);
playerPos.x += (dt * step) * 5;
setPosition(playerPos);
//currentAnimation = &walk;
}
if (input->isKeyDown(sf::Keyboard::W) ) {
input->setKeyUp(sf::Keyboard::Space);
playerPos.x += (dt * step) * 5;
setPosition(playerPos);
//currentAnimation = &jump;
velocity.y = -5.f * -1;
}
if (onGround == false) {
velocity.y += accelGravity;
if (velocity.y > maxGravity) {
velocity.y = maxGravity;
}
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
input->setMouseLeftUp(sf::Mouse::Left);
currentAnimation = &attack;
}
}
void PlayerSprite::setInput(Input* newInp)
{
input = newInp;
}
void PlayerSprite::collisionResponse(Sprite* sp)
{
if (velocity.x > 0) {
velocity.x = 0.f;
}
if (velocity.x < 0) {
velocity.x = 0.f;
}
if (velocity.y > 0) {
velocity.y = 0.f;
onGround = true;
}
if (velocity.y < 0) {
velocity.y = 0.f;
}
setPosition(getPosition().x, sp->getPosition().y - getSize().y);
}
Game.cpp中的碰撞检测
void Game::update(float dt)
{
player.update(dt);
manager.update(dt);
std::vector<Tile>* world = worldMap.getScene();
for (int i = 0; i < (int)world->size(); i++) {
if ((*world)[i].isAlive()) {
if (checkGroundBounding(&player, &(*world)[i])) {
player.collisionResponse(&(*world)[i]);
}
}
}
void Game::render() {
beginDraw();
window->draw(bg);
window->draw(player);
manager.render(window);
worldMap.render(window);
endDraw();
}
bool Game::checkGroundBounding(PlayerSprite* b1, Tile* b2)
{
//get radius of sprites
float r1 = b1->getSize().x / 2;
float r2 = b2->getSize().x / 2;
float xposb1 = b1->getPosition().x + r1;
float xposb2 = b2->getPosition().x + r2;
float yposb1 = b1->getPosition().y + r1;
float yposb2 = b2->getPosition().y + r2;
if (pow(xposb2 - xposb1, 2) + pow(yposb2 - yposb1, 2) < pow(r1 + r2, 2)) {
return true;
}
return false;
}
您的碰撞非常不稳定,只需将oldPos变量设置为您的玩家位置,然后执行您的移动代码,但仅限于X轴,如果检测到碰撞,请将位置设置为oldPos,然后再次将旧Pos设置为当前位置,并对Y轴重复此操作:
伪代码示例:
//X axis
oldPos = position
if(leftKey):
position.x -= speed
if(rightKey):
position.x += speed
if(collision):
position = oldPos
//Y axis
oldPos = position
if(upKey):
position.y -= speed
if(downKey):
position.y += speed
if(collision):
position = oldPos
您也可以将磁贴迭代替换为:
for(Tile t : *world){
t->doStuff();
}
我也不建议在更新函数中声明平铺向量,除非您讨厌性能
这是我的碰撞/移动代码 这是PixelPerfectTest函数(不是我的) 编辑:这就是我如何让它工作,以防将来有人需要帮助
因此,我进行了一个测试,看看碰撞是如何在SFML中操作的。我制作了以下代码片段: 正如代码所提示的,马里奥在接触地板物体时会改变位置,并且会瞬移到地板上方。 注意,“绿框”是我前面提到的地板对象。还有,忽略图片1中的“左”字,我指的是“右”。 当然,这种行为是有意的(即不是bug),但它是不想要的。 所以我的问题是:我怎样才能消除这种“副作用”呢?我的意思是,我怎样才能修改我的代码,这样马里奥就不
我目前正在业余时间用C语言和SFML 1.6编写游戏。当需要进行碰撞检测时,我遇到了一个恼人的错误,程序检测碰撞时,好像物体被移到了左上角,根据我用来测试的静止精灵的大小,移动量不同,通常是其大小的一半左右。我似乎找不到我的代码中有什么bug,但也许你能找到。我的代码列在下面,提前感谢。
我的2D平台游戏有问题。由于我刚刚开始使用c,因此我在瓷砖碰撞方面遇到了麻烦。我能够阻止玩家进入图块,并且能够远离它,但不知何故,他不能沿着图块移动。 此功能用于检查新位置是否位于实心瓷砖内: 空地图::drawColMap(播放器 } 以下是移动播放器的代码: void Player::update() { } 感谢任何帮助! //编辑1 我试着记录碰撞,它显示即使我不按任何键,玩家仍然在碰撞区
我使用libgdx为一个项目制作了一个2D游戏,我的碰撞检测技术基于。在矩形中重叠方法,效果良好。我想了解其背后的实现,如果我要将其与intersects方法并行,我知道它是如何工作的。但这是唯一的吗?我读到,在离散碰撞检测方法中,不仅需要计算实体是否发生碰撞,还需要计算它们发生碰撞的“程度”(碰撞深度),并使用轴对齐的边界盒算法将实体推回。首先,我对矩形重叠技术是否与libgdx中的AAAB相同
碰撞检测 现在你知道了如何制造种类繁多的图形对象,但是你能用他们做什么?一个有趣的事情是利用它制作一个简单的 碰撞检测系统 。你可以用一个叫做:hitTestRectangle 的自定义的函数来检测两个矩形精灵是否接触。 hitTestRectangle(spriteOne, spriteTwo) 如果它们重叠, hitTestRectangle 会返回 true。你可以用 hitTestRect