There is a bug in the collision code that is easy to address, a mover can get stuck on the border of the window if it’s gone far enough past the edge before getting tested, to address this, we can move the object away from the edge to prevent it getting stuck.
[pastacode lang=”markup” manual=”void%20mover%3A%3AedgeCollision()%0A%7B%0A%20%20%20%20if%20(%20(position.getX()%20%2B%20width%20%3E%3D%20SCREEN_WIDTH)%20)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20position.setX(SCREEN_WIDTH%20-%20width)%3B%0A%20%20%20%20%20%20%20%20velocity.setX(velocity.getX()%20*%20-1)%3B%0A%20%20%20%20%7D%0A%20%20%20%20else%20if(position.getX()%20%3C%3D%200)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20position.setX(0)%3B%0A%20%20%20%20%20%20%20%20velocity.setX(velocity.getX()%20*%20-1)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20(%20(position.getY()%20%2B%20height%20%3E%3D%20SCREEN_HEIGHT)%20)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20position.setY(SCREEN_HEIGHT%20-%20height)%3B%0A%20%20%20%20%20%20%20%20velocity.setY(velocity.getY()%20*%20-1)%3B%0A%20%20%20%20%7D%0A%20%20%20%20else%20if(position.getY()%20%3C%3D%200)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20position.setY(0)%3B%0A%20%20%20%20%20%20%20%20velocity.setY(velocity.getY()%20*%20-1)%3B%0A%20%20%20%20%7D%0A%0A%7D” message=”” highlight=”” provider=”manual”/]
Because the image is being drawn from it’s top left corner, we need to offset the positioning by the width and height of the image respectively so that it stays within the window.
Just for a bit of fun, I was wondering what would happen if I added a ball that follows the mouse and, when it strikes another ball, it imparts a force equal to it’s previous position minus it’s last position on the ball that it struck.
To do that we would need to add a function that checks for collisions for all the objects in the world, this would be easier if we had all the objects in a nice list that where could them from the constructor of the mover class and remove them from the list via the destructor. A std::vector would probably be a good container object for this and I think making it a static member of the class would allow us to update it on each creation.
[pastacode lang=”cpp” manual=”%7BAdded%20to%20mover.h%7D%0A%0Astatic%20std%3A%3Avector%3Cmover*%3E%20moverList%3B%0Aint%20id%3B%0A%0A%0A%0A%7BAdded%20to%20mover.cpp%7D%0A%0Amover%3A%3Amover(float%20posX%2C%20float%20posY%2C%20float%20velX%2C%20float%20velY%2C%20float%20accX%2C%20float%20accY%2C%20float%20maxS%2C%20float%20_mass)%0A%7B%0A%20%20%20%20mover%3A%3AmoverList.push_back(this)%3B%0A%20%20%20%20id%20%3D%20mover%3A%3AmoverList.size()%3B%0A%7B…%7D%0A%7D%0A%0A%0Amover%3A%3A~mover()%0A%7B%0A%20%20%20%20SDL_DestroyTexture(image)%3B%0A%20%20%20%20mover%3A%3AmoverList.begin()%2Bid%3B%0A%7D%0A%0A%0A%0Astd%3A%3Avector%3Cmover*%3E%20mover%3A%3AmoverList%3B%0A%0A” message=”” highlight=”” provider=”manual”/]
This code simply declares a static vector of mover pointers called moverList in the header, adds a variable called id which takes the current size of moverList as it’s value, adds a function call that adds the current address of the object to the vector, adds a function call in the destructor that removes the current id from the vector and has a section that defines the vector below the class definition, upon testing this works exactly as intended. Now we can iterate through the objects in the list via this moverList instead of the array we created earlier. Not using an array has many benefits, the most notable being that we don’t declare the size of the vector at compile time, meaning we can add an arbitrary number of movers to our scene and out code will handle them all just fine!
To iterate through our new list we can use a for loop as before with new parameters:
[pastacode lang=”cpp” manual=”for(int%20i%3D0%3B%20i%3Cmover%3A%3AmoverList.size()%3Bi%2B%2B)%0A%7B%0A%20%20%20%20mover%3A%3AmoverList%5Bi%5D-%3Emass%20%3D%20rand()%20%25%20100%2B1%3B%0A%20%20%20%20mover%3A%3AmoverList%5Bi%5D-%3EloadImage(%22Images%2Fball.png%22%2C%20renderer)%3B%0A%20%20%20%20mover%3A%3AmoverList%5Bi%5D-%3EsetHeight(mover%3A%3AmoverList%5Bi%5D-%3Emass%2B25)%3B%0A%20%20%20%20mover%3A%3AmoverList%5Bi%5D-%3EsetWidth(mover%3A%3AmoverList%5Bi%5D-%3Eheight)%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
And to instantiate our objects on the heap we can use:
[pastacode lang=”cpp” manual=”for(int%20i%3D0%3B%20i%3C50%3B%20i%2B%2B)%0A%7B%0A%20%20%20%20new%20mover()%3B%0A%7D” message=”” highlight=”” provider=”manual”/]
This works for our case here, but is not really proper as it doesn’t give use a way to run the corresponding delete that is required to prevent memory leaks.
That’s all for today, we didn’t get to much of what we set out to do today, but we did learn a fair bit about std::vectors and static member variables!