当前位置: 首页 > 知识库问答 >
问题:

C /SFML超级马里奥游戏与积木的碰撞问题

伯建安
2023-03-14

我正在用C /SFML制作一个类似超级马里奥的游戏,在试图为马里奥碰撞编写一些代码时,我遇到了一些问题:当角色在沿着水平轴移动的同时与一堆垂直的积木碰撞时,他会卡在积木的一边,就像是在一个看不见的积木上行走一样。我试图修改碰撞功能,就像让马里奥只有在他与块相关的位置包含在块坐标中时,才能与块水平碰撞。

我包含了一些运动代码(keyPree是一个返回按下的键的函数):

void Player::movement(Time& gameTime) {
    player.move(v * gameTime.asSeconds());
    view.setCenter(player.getPosition().x + 16, 590);

    if (keyPressed(up) && !jumping) {
        jumping = true;
        v.y = jumpSpeed;
    }
    if (v.y > 200) {
        jumping = true;
    }
    else {
        crouch = false;
    }
    if (keyPressed(left)) {
        if (v.x > -moveSpeed) {
            v.x -= 100;
        }
        else {
            v.x = -moveSpeed;
        }
    }
    else if (keyPressed(right)) {
        noKeyPressed = false;
        if (v.x < moveSpeed) {
            v.x += 100;
        }
        else {
            v.x = moveSpeed;
        }
    }
    else {
        if (v.x < -100) {
            v.x += 100;
        }
        else if (v.x > 100) {
            v.x -= 100;
        }
        else {
            v.x = 0;
        }
    }
    gravity();

    if (big) { //Big is a variable that tells me if mario is big or small
        heightValue = 33; //heightValue is a variable that stores the sprite height in pixels
    }
    else {
        heightValue = 16;
    }
}

void Player::gravity() {
    if (!big) {
        if (player.getPosition().y + 32 < 1100) {
            if (v.y < maxSpeed) {
                v.y += 100;
            }
        }
        if (alive) { //This is useful to check if big mario has fallen
            if (player.getPosition().y + 32 >= 1200) {
                player.setPosition(player.getPosition().x, 1200 - 32);
                jumping = false;
                alive = false;
            }
        }
    }
    else {
        if (player.getPosition().y + 64 < 1100) {
            if (v.y < maxSpeed) {
                v.y += 100;
            }
        }
        if (alive) { //This is useful to check if small mario has fallen
            if (player.getPosition().y + 64 >= 1200) {
                player.setPosition(player.getPosition().x, 1200 - 64);
                jumping = false;
                alive = false;
            }
        }
    }
}

以及碰撞函数,其中块类在块精灵周围有4个小块,可简化碰撞:

void Player::collisions(Block* block) {
    if (this->player.getGlobalBounds().intersects(block->up.getGlobalBounds())) {
        if (!big) {
            if (this->player.getPosition().y + heightValue <= block->block.getPosition().y) {
                this->player.setPosition(this->player.getPosition().x, block->up.getPosition().y - 32);
                v.y = 0;
                jumping = false;
                score = 100;    
            }
        }
        else {
            if (this->player.getPosition().y + heightValue <= block->block.getPosition().y) {
                this->player.setPosition(this->player.getPosition().x, block->up.getPosition().y - 64);
                v.y = 0;
                jumping = false;
                score = 100;            
            }
        }
    }
    if (this->player.getGlobalBounds().intersects(block->down.getGlobalBounds())) {
        this->player.setPosition(this->player.getPosition().x, block->down.getPosition().y + 1);
        v.y = 0;
    }
    if (this->player.getGlobalBounds().intersects(block->left.getGlobalBounds()) && v.x > 0) {
        this->player.setPosition(block->left.getPosition().x - 32, this->player.getPosition().y);
    }
    else if (this->player.getGlobalBounds().intersects(block->right.getGlobalBounds()) && v.x < 0) {
        this->player.setPosition(block->right.getPosition().x + 1, this->player.getPosition().y);
    }
}

我希望我准确地解释了这个问题。

共有1个答案

冀崇凛
2023-03-14

简单地一次做一个轴的碰撞检测,这允许沿着瓷砖平滑的移动

代码示例:

//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
 类似资料:
  • 我用C语言用SFML库创建了一个游戏,在实现过程中出现了贴图冲突(我从txt文件中加载贴图- 1代表平台,0代表自由空间)。https://imgur.com/a/tQZc6 我在同时处理所有四种类型的碰撞时遇到了一个问题(从下、上、左和右)。我的意思是:当没有碰撞时,玩家可以正常移动,但是如果我们撞到墙上,碰撞只出现在FIRST中写的if()语句中(在我们的示例中只发生右碰撞,其余部分被省略)。

  • 我是java游戏编程的初学者,对于游戏我有一个小小的实际上很大的问题。我试着在敌人和街区之间制造碰撞,但是不起作用,我不知道为什么。它应该工作,但它只是缓慢的游戏每秒一帧,不做任何事情。 我有一个名为Game的主类,带有这个主Init()函数 而不是LoadImageLevel函数,其中我读取级别。png逐像素和不同颜色设置每个对象的位置。 在类中,Player是两个重要的函数,其中在刻度中称为勾

  • 我目前正在业余时间用C语言和SFML 1.6编写游戏。当需要进行碰撞检测时,我遇到了一个恼人的错误,程序检测碰撞时,好像物体被移到了左上角,根据我用来测试的静止精灵的大小,移动量不同,通常是其大小的一半左右。我似乎找不到我的代码中有什么bug,但也许你能找到。我的代码列在下面,提前感谢。

  • 我的2D平台游戏有问题。由于我刚刚开始使用c,因此我在瓷砖碰撞方面遇到了麻烦。我能够阻止玩家进入图块,并且能够远离它,但不知何故,他不能沿着图块移动。 此功能用于检查新位置是否位于实心瓷砖内: 空地图::drawColMap(播放器 } 以下是移动播放器的代码: void Player::update() { } 感谢任何帮助! //编辑1 我试着记录碰撞,它显示即使我不按任何键,玩家仍然在碰撞区

  • 因此,我进行了一个测试,看看碰撞是如何在SFML中操作的。我制作了以下代码片段: 正如代码所提示的,马里奥在接触地板物体时会改变位置,并且会瞬移到地板上方。 注意,“绿框”是我前面提到的地板对象。还有,忽略图片1中的“左”字,我指的是“右”。 当然,这种行为是有意的(即不是bug),但它是不想要的。 所以我的问题是:我怎样才能消除这种“副作用”呢?我的意思是,我怎样才能修改我的代码,这样马里奥就不

  • 这是我的碰撞/移动代码 这是PixelPerfectTest函数(不是我的) 编辑:这就是我如何让它工作,以防将来有人需要帮助