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

Author Topic: [SOLVED] Collision accuracy issues  (Read 1820 times)

0 Members and 1 Guest are viewing this topic.

R_oot42O

  • Newbie
  • *
  • Posts: 5
    • View Profile
[SOLVED] Collision accuracy issues
« on: April 07, 2020, 07:34:20 pm »
Hello everyone, I am currently creating a "Bubble Shooter" like (see https://bubble-shooter.co/) only with RectangleShapes but I am facing a problem with collision accuracy. In fact, the collision is well detected, but not accurate.

See these images :

https://ibb.co/F0sckGd

https://ibb.co/MPYMWw5

As you can see, collision isn't accurate.

What i've found so far :

    Increasing Framerate limit (setFramerateLimit) to something like 600 and decreasing the move speed to 1 fix this issue.
    I'm quite new to game development, but I guess that running a game at 600 fps isn't a good idea right ?

It looks like the issue is related to the speed and the direction vector, but cannot find out what's wrong.

Here's some part of my source code.

void Game::processEvent(sf::Event e)
{
   if(e.type == sf::Event::MouseButtonPressed && canShoot == true)
   {
      float mouseX = sf::Mouse::getPosition(gameWindow).x; //Getting mouse position
      float mouseY = sf::Mouse::getPosition(gameWindow).y;

      if(mouseY < gameSize.y - blockSize.y)
      {
         blockDirection.x += mouseX - (gameSize.x / 2); //Calculating direction vector (gameSize.x / 2) is the x origin of the projectile.
         blockDirection.y += mouseY - (gameSize.y - blockSize.y); //gameSize.y - blockSize.y is the y origin of the projectile
         canShoot = false;
      }
   }
}
void Game::gameUpdate()
{
   int id = isGameBlockColliding();
   if(id == -1 && canShoot == false)
   {
      blockDirection = normalizeDirection() * blockSpeed; //When blockSpeed is set to 1, there's no collision issue, but the game is much too slow.
      gameBlock.moveBlock(blockDirection);
   }
   else if(id == -2) //In case we collide with screen borders (only x axis for now)
   {
      blockDirection.x = -blockDirection.x;
      gameBlock.moveBlock(blockDirection);
   }
   else
   {
      if(canShoot == false)
      {
         canShoot = true;
         staticGameBlocks.push_back(gameBlock);
         if(gameBlock.getBlockColorID() == staticGameBlocks[id].getBlockColorID())
         {
            staticGameBlocks.erase(staticGameBlocks.begin() + id);
            staticGameBlocks.pop_back();  
         }
         spawnRandomBlock();
      }
   }
}
sf::Vector2f Game::normalizeDirection() //found this method somewhere in the forums
{
   float modulus = sqrt((blockDirection.x * blockDirection.x) + (blockDirection.y * blockDirection.y));
   if(modulus != 0)
   {
      return sf::Vector2f(blockDirection.x / modulus, blockDirection.y / modulus);
   }
   else
   {
      return blockDirection;
   }
}
int Game::isGameBlockColliding()
{
   if(!(gameBlock.getBlockPosition().left + gameBlock.getBlockPosition().width < gameSize.x && gameBlock.getBlockPosition().left > 0))
   {
      return -2;
   }
   for(int i = 0; i < staticGameBlocks.size(); i++)
   {
      sf::FloatRect staticRect = staticGameBlocks[i].getBlockPosition();
      sf::FloatRect gameBlockRect = gameBlock.getBlockPosition();
      if(staticRect.intersects(gameBlockRect))
      {
         return i;
      }
   }
   return -1;
}
 

Please let me know if you need more informations in order to help me.
Thank you in advance for any response.

(Sorry if my english was bad.)






     
     
« Last Edit: April 08, 2020, 01:04:47 am by R_oot42O »

SpaceKotik

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Collision accuracy questions
« Reply #1 on: April 07, 2020, 08:50:51 pm »
As I can see, the problem is that when a block moves at high speed, the collision detected after the block has already moved too far. You probably have to manually set the correct postion for it after collision.
« Last Edit: April 07, 2020, 08:52:43 pm by SpaceKotik »

R_oot42O

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Collision accuracy issues
« Reply #2 on: April 07, 2020, 11:20:38 pm »
Thank you for you answer.

I followed your advice, and moved the blockDirection vector's y component down after collision is detected.

Here's what i've added to my code :

Code: [Select]

//After collision has been checked
gameBlock.moveBlock(sf::Vector2f(blockDirection.x, -blockDirection.y));

The result is illustrated in the picture below :




So now, the projectile isn't going too far, but not far enough, it is stoped before "real" collision.
This means I have to find the right value to move down the block.

I keep searching for it.




« Last Edit: April 07, 2020, 11:22:17 pm by R_oot42O »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Collision accuracy questions
« Reply #3 on: April 07, 2020, 11:27:43 pm »
Since these are basic geometric shapes (rectangles), often the best solution is to work geometrically.
That is, work out which rectangle is colliding the most, project the moving rectangle from its previoius position to the current one and figure out where it intersects with the static rectangle. If this is enough, just move it back to this position.
However, if it needs accurate and consistent movement, you should also calculate how much of the movement was lost by moving it back and the project it forwards on the reflection angle.

Another thing, though, is running the logic updates faster than the display updates. This way, you can update the screen at a framerate of something normal (e.g. 60 FPS) while running the game loop at 1000 FPS if required.

This article - https://gafferongames.com/post/fix_your_timestep/ - will explain how timesteps can be improved and also how to 'decouple' the logic framerate from the display framerate. See the "Free the physics" part but make sure you understand the article up to that point first.

If you choose this route, Timestep and Timestep Lite (part of my Kairos timing library) should help automating this approach ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

R_oot42O

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Collision accuracy issues
« Reply #4 on: April 08, 2020, 01:03:32 am »
Thank you for your detailed answer.

Running the update loop faster than the frame rate and multiplying the direction vector by delta time finally solved my problem.

Have a nice day/night !
« Last Edit: April 08, 2020, 01:09:56 am by R_oot42O »