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

Author Topic: Collision detection, makes sprite move in opposite direction.  (Read 851 times)

0 Members and 1 Guest are viewing this topic.

noct27

  • Newbie
  • *
  • Posts: 3
    • View Profile
Collision detection, makes sprite move in opposite direction.
« on: August 28, 2022, 10:06:45 pm »
Hello,


I'm working on collision detection when a sprite hits a wall.


In my Zone.cpp class, where tilemaps are handled I have this block in the update function:


Code: [Select]

    for (auto& tileMap : renderAfterPlayerTM) {
        tileMap->tileMap->update(player, &movement, &this->frameItem, &zoneInfo, deltaTime);
        playerUpdate = movement.ghostMove(deltaTime, currentPlayerPosition, *tileMap->tileMap->getTilesGroupVector());
    }
    player->update(deltaTime, playerUpdate.newPosition, playerUpdate.playerPosition);
    for (auto& tileMap : renderBeforePlayerTM) {
        tileMap->tileMap->update(player, &movement, &this->frameItem, &zoneInfo, deltaTime);
        playerUpdate = movement.ghostMove(deltaTime, currentPlayerPosition, *tileMap->tileMap->getTilesGroupVector());


    }
 player->update(deltaTime, playerUpdate.newPosition, playerUpdate.playerPosition);


I have multiple tilemaps that render different type of objects, like things that should render/update before and after the player is.
The ghostMove function is where the sprites new position is formed:


Code: [Select]

MovePlayerResponse Movement::ghostMove(sf::Time deltaTime, sf::Vector2f playerPosition, std::vector<TileGroup*> tileGroupsVector) {
    MovePlayerResponse mpr;
    AnimatedSprite ghost;
    ghost.setPosition(playerPosition);
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
        ghost.move(sf::Vector2f((-1 * speed), 0.0f));
        LL::MapUpdateResponseObject collideResponse = LL::Collision::collide(ghost.getPosition(), tileGroupsVector);
        mpr.playerPosition = LL::PlayerPosition::Left;
        if (collideResponse.collided) {
            mpr.newPosition = sf::Vector2f(speed, 0.0f);
            mpr.tileNumber = collideResponse.tileNumber;
            return mpr;
        }
        mpr.newPosition = sf::Vector2f((-1 * speed), 0.0f);
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) {
        ghost.move(sf::Vector2f((speed), 0.0f));
        LL::MapUpdateResponseObject collideResponse = LL::Collision::collide(sf::Vector2f(ghost.getPosition().x, ghost.getPosition().y), tileGroupsVector);
        mpr.playerPosition = LL::PlayerPosition::Right;
        if (collideResponse.collided) {
            mpr.newPosition = sf::Vector2f(-1 * (speed), 0.0f);
            mpr.tileNumber = collideResponse.tileNumber;
            return mpr;
        }
      mpr.newPosition = sf::Vector2f((speed), 0.0f);
    }
    mpr.tileNumber = -1;
    return mpr;
}


On every movement, I move the position to the desired position and if a collision occurs I move it back. The problem occurs when I hold down S (which goes down on the screen) and the sprite continues to collide with  the wall, and if I were to press D the sprite would move as if i'm pressing A because it's stuck in that collide block or the sprite would just not move at all, or continuously bounce off and on the wall.


Image for an idea of when this occurs, collision on a wall:


Any ideas on why this behavior occurs, or if I have some fundamental flaw in my design?

« Last Edit: August 28, 2022, 10:10:31 pm by noct27 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10815
    • View Profile
    • development blog
    • Email
Re: Collision detection, makes sprite move in opposite direction.
« Reply #1 on: September 01, 2022, 09:40:16 pm »
It's quite tricky to understand such code snippets in isolation when one doesn't know the code base.

My guess is that your handling code for the down movement is also (wrongly) resetting the X position.

Depending on what type of game it is, you may want to have a flag that tells, whether you're on the ground or not, with that you could then only allow left/right movements. But that of course doesn't work for every game type.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

firet

  • Newbie
  • *
  • Posts: 15
  • Gamedev, web dev and C++ programmer.
    • View Profile
    • Future Games official site
    • Email
Re: Collision detection, makes sprite move in opposite direction.
« Reply #2 on: September 05, 2022, 06:36:22 pm »
A way I found to fix this: rather than detecting whether it's currently colliding, before a movement, check if after the movement the object will be colliding, and only do the move if it wont be colliding. e.g. if the move is 50, 50 do a collision check on position + movement and only move if it wont collide.
Online I am: firet; flesheatindragon; Future Games.

 

anything