不久之后,碰撞停止工作并且物体A夹住物体B

问题描述 投票:0回答:1

开发一个基本的比武(一种古老的街机游戏)克隆,达到碰撞检测,一开始似乎可以工作。 但我发现,当我在平台上保持静止时,或者即使我在平台上移动时,经过短暂时间(~5sc)后,我会夹住平台

我首先进行了一些清理、测试、移动、测试和小型重构,以简化检测和测试,并使其整体更干净,但检测似乎还可以;毕竟它可以工作〜5sc。 之后,我想到了重力;因为即使在地面上,它也会影响玩家并可能迫使拍摄对象发生剪辑。所以我可能是一个 isGrounded 变量。所以操作顺序应该是:(玩家稍微在空中开始) handleCollision 说确定没有碰撞 -> isGrounded=false 使用有效重力更新玩家 玩家摔倒
然后玩家与平台相撞 handleCollision 说哦,你在平台上 -> isGrounded=true 玩家更新应该不受重力影响

#include "game.h"

Game::Game() : window(sf::VideoMode(windowWidth, windowHeight), "App")
{
    // stuff //

    isGrounded = true;
}
void Game::handleCollision(sf::RectangleShape &A, const sf::RectangleShape &B)
{
    sf::FloatRect BoxA = A.getGlobalBounds();
    sf::FloatRect BoxB = B.getGlobalBounds();

    // Check collision from above
    if (BoxA.intersects(BoxB) && BoxA.top + BoxA.height < BoxB.top + BoxB.height)
    {
        A.setPosition(A.getPosition().x, B.getPosition().y - BoxA.height); // A.getSize().y);
        isGrounded = true;
        std::cout << "Grounded: " << std::endl;
    }
    else
    {
        isGrounded = false;
        std::cout << "In The Air: " << std::endl;
    }
}

void Game::handleCollisions()
{
    handleCollision(player1, platformGround);
}

void Game::update()
{
    float deltaTime = frameTime.asSeconds();

    // Player 1 movement control using keyboard input
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
    {
        player1.move(-playerSpeed * deltaTime, 0);
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
    {
        player1.move(playerSpeed * deltaTime, 0);
    }

    // Player 1 flapping control using spacebar
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
    {
        player1Velocity = flapVelocity;
    }

    // Apply gravity only when player is not grounded
    if (!isGrounded)
    {
        player1Velocity += gravity * deltaTime;
    }
    else
    {
        player1Velocity = 0.0f;
    }

    // Update position
    player1.move(0, player1Velocity * deltaTime);

    handleCollisions();
}

这确实是一件愚蠢而明显的事情,它(几乎)总是这样;但预先感谢您提供任何形式的帮助。

c++ collision-detection sfml gravity
1个回答
0
投票

好的

一周后,我找到了解决方案。问题是,这段代码只适用于两个对象,这就是问题所在,因为我进行了 6 次碰撞检查:当接触地面时,标志 isGrounded 被正确设置为 true,但在下一次检查中立即重置(因为当时条件为 false,所以去到 else 部分并将 isGrounded 设置回 false)

所以在我这边做了其他最小的例子之后,我开始用以下内容替换原始支票:

if (BoxA.intersects(BoxB) && player1Velocity >= 0.0f)
{
    // isGrounded = true;
    A.setPosition(A.getPosition().x, BoxB.top - BoxA.height);
    player1Velocity = 0.0f;
    std::cout << "Grounded: " << BoxA.height << std::endl;
}
else
{
    isGrounded = false;
    std::cout << "In The Air: " << std::endl;
}

现在可以与其他碰撞检查一起使用,即使现在我不知道为什么,因为 isGrounded 仍然设置为 false,因此应该在更新函数中激活重力效果。

但那是另一回事,不再链接到最初的问题。

© www.soinside.com 2019 - 2024. All rights reserved.