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

Author Topic: How to handle collision for multiple objects efficiently ?  (Read 4454 times)

0 Members and 2 Guests are viewing this topic.

Shamlei

  • Newbie
  • *
  • Posts: 1
    • View Profile
How to handle collision for multiple objects efficiently ?
« on: August 21, 2017, 01:45:35 am »
Hey I'm currently making an arkanoid clone, I'm not very experienced with C++ and just started with SFML so I think I'm not doing the right thing here.

My ball is checking for collision in it's update function (that handles movement and collisions.)

I've excluded the movement, here's the collision with the paddle bit :
void Ball::update(float deltaTime, Paddle &paddle)
{
        sf::FloatRect playerBox(paddle.getBoundingBox()); // Paddle bounding box
        m_boundingBox = m_shape.getGlobalBounds(); // ball bounding box

        // Collision check with paddle
        if (m_boundingBox.intersects(playerBox))
        {
                std::cout << "Colliding" << std::endl;
        }
}
 


Now this works but the problem is that I have to give the player's bounding box to the function, It's not a problem as of right now but since there's dozens of boxes in Arkanoid I'll have to feed dozens of boxes to the function.

My thought was to store every box in a vector and iterate over it to check if the ball is colliding with a box inside the vector.

That's a fix but it doesn't look very efficient, is there a way to make it better ?

Thanks to those who will help.
« Last Edit: August 21, 2017, 02:21:51 am by Shamlei »

Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: How to handle collision for multiple objects efficiently ?
« Reply #1 on: September 01, 2017, 03:18:24 am »
hi Shamlei

I give you my ideas of how make your 'arkanoid' simpler and more efficient ...

You have these objects:
1) player's paddle, 2) ball, 3) boxes, 4) list<> or 'vector' that contains all boxes, 5) game board

What of these objects is who interacts with all of others? The ball
Then it would be better to pass the ball reference to all other objects, instead of passing all other objects' references to the ball

At the main loop, you need to draw the board, the alive boxes, the paddle, and the ball

The 'vector' should check, iterating, if the ball hits any of its boxes and destroy it. If so, then it should make the ball bounce, mark himself as destroyed, and break the iteration (cos maybe the ball hits 2 boxes, and I suppose it should not destroy 2 boxes at a same time) ... after this, if there is a marked box, it should be removed from the 'vector'. If the 'vector' is empty, then you pass the level.

Also, the paddle should check if the ball bounce on it. If so, it should calculate, depending on what part of it the ball bounced, the new direction (angle) of the ball (this alghoritm may be a bit sophisticated).

The board should check if the ball collides against its borders. If so, it should bounce (if I'm not wrong the new angle would be : angle = 90 - angle ... if needed then I try to confirm). If the ball reaches the board's bottom, then you lose a life (the paddle explodes or whatever you want).

Additionally, you may want to have some ways to load levels, such as int (or short) bidimensional vectors or arrays to store the boxes in memory. Also you can have boxes with different attributes, as color, hits to destroy it, bonus it throws down when destroyed, ...

Please let me know your project's progress and if you need any help


smilesprower

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: How to handle collision for multiple objects efficiently ?
« Reply #2 on: September 01, 2017, 06:23:17 pm »
There is nothing wrong with iterating over a vector to check for collisions with a simple game like arkanoid.

Don't waste your time trying to build the perfect and most efficient code. Get the collisions up and running and see if its a problem first.

If you find its an issue then maybe look into splitting your level up into multiple parts or use a tile based approach.

Feel free to message if you have any issues.



Tigre Pablito

  • Full Member
  • ***
  • Posts: 226
    • View Profile
    • Email
Re: How to handle collision for multiple objects efficiently ?
« Reply #3 on: September 02, 2017, 02:09:37 am »
Hello, smilesprower, Shamlei

It seems you have some opinion about making Shamlei's arkanoid coding easier different than what I gave him

Would you like to explain a bit more detailed how you would organize the code?, that is, in what concerns to OOP, some objects that interact between them

As far as I understood of what you sugested, the easier way is to pass to the ball object all other objects' references and make it do almost all stuff instead of distribute the game work between all its objects proportionally (and just passing the ball object reference to all of them). Really you believe that that way to program will be easier?

Well, any opinion is respectable, but maybe if you explain how you would organize the code, a bit more detailed, I can see it and could be I realise that I was wrong and you were right.

I agree on the idea of the tile based aproach, but explaining that here would be very long. For that it is not needed any complement nor extra library, just a very simple alghoritm that draws the boxes or tiles over the board, each one on its predefined space (all of them are equal size and contiguous rectangles). Actually, what I sugested about the bidimensional int arrays or vectors is to load the levels from them. Actually, my Super Mario games' Level Editor uses that technique to allocate the famous bricks (that Mario can break) in the same way that the arkanoid boxes or tiles are displayed, and there may be spaces where there are not any tile or box.

Shamlei, you can message if you think I can help you
 

smilesprower

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: How to handle collision for multiple objects efficiently ?
« Reply #4 on: September 02, 2017, 11:50:56 am »
Hey Tigre,

Your solution is perfectly valid and a good one, and I believe I may have read the topic incorrectly.
I would take a similar approach also.

Game Class {

// Vars
Ball object
Paddle object
Array of block objects

//Functions
ball.update()
paddle.update(Ball &m_ball)
handleCollisions() {
    for(const auto &itr : blocks) {
        // Check block and ball for collisions and update on collision
    }
}

If you don't like having the collision check here you could
for(const auto &itr : blocks) {
        itr.checkCollision(Ball &m_ball);
}