I am creating various objects and pushing them all in objects vector and iterating trough them to update, render and destroy them easier.
Problem occurs when I want to create more then 250 or so objects.
Game starts lagging and eventually if I doesn't stop creating new objects it freezes until program in the back doesn't destroy few objects(in my case it does it automatically since objects are snowflakes for example)
Where is the problem: - Iterating trough 250 objects 60 times in a second 2 or eventually 3 times? or vector cant hold that much memory or something?
and how to fix this?
std::vector<GameObject *> objects; std::vector<GameObject *>::iterator iter; std::vector<GameObject *>::iterator iter2; // example of creating a snowflake: Snow *snow = new Snow(player->GetX(), player->GetY()); object.push_back(snow); // example of render: for(iter = objects.begin(); iter != objects.end(); ++iter) (*iter)->Render();
It's not the iteration at issue, it is what you are doing on each iteration, like rendering. You need to profile your code. But it may be that you're not drawing from the same source texture and using al_hold_bitmap_drawing calls.
Snow is actually al_draw_circle, so I think it has nothing to do with textures loading.
I have 4 iterations, render, destroy and this two down below, update and collisions.
Maybe vector just cant hold that much objects of this size?
I have 4 iterations, render, destroy and this two down below, update and collisions.
If by "destroy" you mean erase then don't, since it has linear time complexity. Instead you should swap the current element with the last element and pop_back, unless the order really matters.
There's also the fact that you check for collisions between all pairs of objects, so those are 250*250 = 62500 collision checks per frame, which could also be slowing you down.
This has nothing to do with vectors. They are your best choice in this situation, since they have contiguous memory.
The problem is that you are doing (n^2 + n)/2 CheckCollisions calls where n is the number of objects in your vector.
I told you, profile your code. MinGW has gprof, MSVC probably has their own profiler.
MSVC probably has their own profiler
The Express edition famously does not.
This is how it looks like, I will try your suggestion !
//delete dead for(iter = objects.begin(); iter != objects.end(); ) { if(! (*iter)->GetAlive()) { delete (*iter); iter = objects.erase(iter); } else iter++; }
I tryed to comment out collision checking and as it turns out thats what makes my game lagg. I was able to creat 2k objects without it( didint try more ). Should I set collision chechks only if objects are close to player?
Conclusion, I disabled collision but left in main to still iterate trough 62500 checks, and I got lagg back again, so the problem is in iterating trough 62500 objects basicly.I need to shrink that down.
Should I set collision chechks only if objects are close to player
Depends on what your collision code looks like. If it's just meant to check for collision between circles, checking distance and checking for circles collision is pretty much the same thing.
Anyway, you don't need to check everything for collision every frame, like 60 times per second, right? You could only check some objects. Here is an idea: set a maximum time collision code can take per frame, and if it takes more, then stop it, remember the position, and then start from this position when you return to collision checking next frame.
Iterating through 62500 objects shouldn't be a problem.
Should I set collision chechks only if objects are close to player?
Only if you update objects close to the player, otherwise weird things might happen. Only check collisions with objects that are close to each other.
You could for example divide the board using an imaginary grid. Add objects to cells that they are inside of. Then while doing a collision check, only check collisions with objects in the same cell. Do keep your current vector as well, for keeping updating, rendering and deletion simple.
You can keep track of objects that can collide and objects that can't in 2 seperate vectors. You'll get rid of the if (foo->Collidable()) check completely or almost completely, which can improve performance a lot if your program is suffering from many branch mispredictions.
All those virtual calls and dereferencing pointers, pointing to objects made by new that might be located all over the place (causing cache misses), might be a problem.
Perhaps try a design like this, this is assuming snow is a very common object, expected to be on the screen in great quantities. If it isn't, don't bother with the following code, but do keep it in mind.
You know, collision checks shouldn't be all that time consuming... it's making me wonder if perhaps you're calling something like sqrt() for bounding circles, since sqrt() can cause huge performance hits if overused. (Typically, with bounding circles, you want to calculate based on the squared values of everything so you never have to call the square root function.)
It also helps to flag things appropriately. Not every kind of object needs to intersect every kind of object so you don't want to run collisions on two objects which will never interact with each other.
Maybe the performance hit is due to 250 calls to al_draw_circle?
I sort of remember that it winds up in al_draw_prim and 250 calls per frame may hit performance?
Not sure but still...
Maybe the performance hit is due to 250 calls to al_draw_circle?
I sort of remember that it winds up in al_draw_prim and 250 calls per frame may hit performance?
Not sure but still...
Definitly not, I removed collision betwen blocks and now I can have 3000 al_draw_circles at the same time without seeing any lagg
You know, collision checks shouldn't be all that time consuming... it's making me wonder if perhaps you're calling something like sqrt() for bounding circles, since sqrt() can cause huge performance hits if overused. (Typically, with bounding circles, you want to calculate based on the squared values of everything so you never have to call the square root function.)
I dont use anything like that
It also helps to flag things appropriately. Not every kind of object needs to intersect every kind of object so you don't want to run collisions on two objects which will never interact with each other.
This is what acctualy helped me, I was runnig collision chechk betwen cubes, even though cubes never move...