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

Author Topic: Lag when assigning projectiles as elements in a vector  (Read 5305 times)

0 Members and 1 Guest are viewing this topic.

URSvAir14

  • Newbie
  • *
  • Posts: 14
    • View Profile
Lag when assigning projectiles as elements in a vector
« on: March 04, 2014, 05:53:28 pm »
Hello All!
As part of my top-down shooter that I'm making I am using a vector to hold data on projectiles. Currently, when I run the game on my netbook in release mode or on my pc in debug mode my game begins to lag a lot when adding projectiles to the vector (aka shooting) and when checking for collisions between projectiles and game entities.
 
Below is the declaration of the vector in the entity.h:
std::vector<Projectile> projectiles;

Below I have the code for firing the projectiles inside a function within entity.cpp:
reloadTimer.restart();

projectiles.push_back(projectile);
// put a projectile in the back of the vector
projectiles[projectiles.size() - 1].resetProjectile(getXPosition(), getYPosition(), xtar, ytar);
// reset the projectiles position and target

And below is the code for the collision between player projectiles and enemy entities:
for(int i = 0; i < EnemyContainer.size(); i ++){
        for(int k = 0; k < player.projectiles.size(); k ++){
                if(player.projectiles[k].BBCollision(EnemyContainer[i].getSprite())){
            // if the player bullet collides with an enemy
            EnemyContainer[i].loseHealth(player.getProjDamage()); // make the enemy lose health
            player.projectiles.erase(player.projectiles.begin() + k); // "kill" the projectile
            }
        }
}

I was wondering if any of you wonderful people could help me once again and give me an idea in how to reduce lag when doing those two things? I have already used vector::reserve() in the constructor of the entity class, so I'm not sure what's the problem. Thank you very much in advance!

MadMartin

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #1 on: March 04, 2014, 08:57:51 pm »
You left out one of the most interesting parts, the declaration of Projectile. Depending on the complexity of this class there can be an overhead.
Apart from that, std::vector isn't the best for fast erase, as all elements that are located after the erased element need to be shifted to the front. An alternative would be something like std::unordered_set, which has constant complexity for erasure and access.

How much of those projectiles do you have in your std::vector?

Try running the game in release mode on the PC, too! Debug mode has a really, really bad effect on runtime, especially for the containers of the STL, since there are some test made. It will be faster in release mode.

URSvAir14

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #2 on: March 04, 2014, 09:01:44 pm »
I've tried using it in release mode and my computer has no trouble running it then, but even in release mode my slow netbook struggles to run it. Since I want to make my game accessible for as many people as I can i'm trying to run in debug mode to simulate a bad computer. And the maximum number of projectiles I have in each projectiles container is about 20

MadMartin

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #3 on: March 04, 2014, 09:21:06 pm »
20 is nothing, perhaps. We can't say. You still didn't show the code for the class Projectile...

Did you do some profiling for your netbook? I doubt the bad performance depends solely on the projectile code. How does it run without projectiles?

Be aware that most netbooks are inferior to even old PCs regarding performance!

URSvAir14

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #4 on: March 04, 2014, 09:43:54 pm »
It ran fine on the netbook without projectiles being fired, and the netbook could also handle updating the projectiles after they had been added to the vector. The projectile.h code is bellow:
class Projectile : public Drawable
{
protected:
        // game related stuff
        int damage;
        float speed;

        // math related stuff
        float xdif;
        float ydif;
        float distance;

public:
        Projectile();
        Projectile(int Damage, float speed, sf::Texture &Texture, sf::IntRect rect);
        ~Projectile(void);

        void resetProjectile(float xstart, float ystart, float xend, float yend); // reset the projectiles position and distance coords
        void update(); // update the projectile
}

I've managed to fix the problem with lag when checking for collisions by changing the projectile vector into a projectile* vector earlier this hour, but it's had no effect on the lag when creating the projectile. I've also noticed that there's no lag when erasing the projectiles. The netbook also had no lag in both of these cases
« Last Edit: March 04, 2014, 10:07:34 pm by URSvAir14 »

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #5 on: March 04, 2014, 10:09:16 pm »
I've managed to fix the problem with lag when checking for collisions by changing the projectile vector into a projectile* vector earlier this hour

The code that checks collision is inside a function, right?

If so, then let me ask something: before making the change to a vector of pointers of projectiles, how were you passing the vector to the function? By value or by reference?

On a side note, how do you draw the projectiles on screen? I don't see that your Projectile class has an sf::Sprite member. Just curious.
« Last Edit: March 04, 2014, 10:11:10 pm by AFS »

URSvAir14

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #6 on: March 04, 2014, 10:18:03 pm »
The Projectile class inherits the sf::sprite member along with the collision function, and I passed the vector by reference I think.

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #7 on: March 04, 2014, 10:42:18 pm »
Ooops, somehow I missed that your class is a child of Drawable, my bad :P

Let me propose a different method to handle the projectiles, then. Take this with a grain of salt, as I'm a beginner at this.

You said that you have lag when creating the projectiles. It makes sense, as every time you shoot you create a new instance of Projectile (in which you must create the sprite, apply the texture and yada yada) and add it to the vector.

So, instead of adding/deleting projectiles to the vector, you could try having a fixed number of projectiles on the vector from the very beginning (let's say, 30) and never modify the vector afterwards. With the help of a counter (starting at 0), every time you shoot you set a flag of "projectiles[counter]" to "true" to indicate that said projectile is in the air, and increment the counter. When your counter gets to 30, set it to 0 to start the cycle again.

Only update, check collision and draw projectiles that are in the air (obviously). If a projectile collides with something, set the flag back to "false".

This way you cycle through a vector of projectiles without creating/deleting them, you just update its values. You create the illusion of shooting a lot of projectiles but in reality you use the same projectiles over and over again. Of course, this means that you can only have a certain amount of projectiles in the air at the same time.

Again, take this with a grain of salt. It may work or it may not, as I don't really now the real source of your lag with the code you posted. Hopefully it helps :P

EDIT: Still, I find it very hard to believe that just creating a projectile can cause that much lag. Either something else is wrong or your netbook is very slow.
« Last Edit: March 04, 2014, 11:52:52 pm by AFS »

dabbertorres

  • Hero Member
  • *****
  • Posts: 505
    • View Profile
    • website/blog
Re: Lag when assigning projectiles as elements in a vector
« Reply #8 on: March 05, 2014, 02:42:58 am »
When creating a new Projectile, rather than use push_back(), you may be interested in emplace_back().
That way you can keep your vector as a container of Projectiles, rather than pointers to Projectiles.

That also gets rid of the need for the computer to copy the Projectile to the vector (which is my guess on where your lag is coming from).

When getting rid of a projectile, rather than erasing it in place, you could use swap() to move it to the end of the vector, and then erase it. That way the vector doesn't need to shift all the objects around.

AFS' idea would work too. That's how most older games that ran in very limited memory worked, for example, Galaga. You only ever had 3 missiles in the air at once.

URSvAir14

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Lag when assigning projectiles as elements in a vector
« Reply #9 on: March 05, 2014, 05:32:47 pm »
Okay so I came home and tried your idea of emplace_back(), and that reduced the lag by a fair bit, so thank you :D
I also had another look through my projectile class and rather than saving the projectile texture to the class before assigning it to the sprite I assigned the texture straight away. That got rid of all lag completely, so I guess it was because the computer was trying to copy the texture back into the class :')

Thank you for the help guys :D

The Terminator

  • Full Member
  • ***
  • Posts: 224
  • Windows and Mac C++ Developer
    • View Profile
Lag when assigning projectiles as elements in a vector
« Reply #10 on: March 05, 2014, 06:14:38 pm »
Also make sure that you have only one copy of a sf::Texture that you pass by reference to sprites. As stated in the tutorials, sf::Texture is a heavy class therefore you shouldn't have one sf::Texture per projectile. Have a look at Thor's resource management system as it's fairly useful.
Current Projects:
Technoport