Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Collision Detection and Gravity  (Read 1176 times)

0 Members and 1 Guest are viewing this topic.

internia

  • Newbie
  • *
  • Posts: 1
    • View Profile
Collision Detection and Gravity
« on: May 11, 2020, 11:44:00 am »
This is my first attempt with SFML and game development, and I'm having issues with the collision and gravity.

I'm making a 2D platformer game using a tilemap system.

Collision seems to be working(slightly) but is very choppy, the characters jumps about to random places and its just not ideal -_- I just can't seem to get gravity to work properly. I've tried a few different tutorials but I cant get anything working and I'm at a bit of a loss right now.

If someone could point out what I'm missing here it'd be greatly appreciated!!

Heres the code I'm using for these elements:

In PlayerSprite class(attempt at gravity)

layerSprite::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);

}


Collision Detection attempt in 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;
}
« Last Edit: May 11, 2020, 12:19:03 pm by internia »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Collision Detection and Gravity
« Reply #1 on: May 11, 2020, 05:54:58 pm »
Any change you make should be scaled with dt. If it's in seconds, it's usually just multiplied with that value.

By change, I mean any change really, that is based on time. Velocity and jerk (change of velocity) should be scaled with dt.

So, one place you didn't do that is here:
velocity.y += accelGravity;
whereas it should be:
velocity.y += accelGravity * dt;
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*