Bullet refactor

In my last post I created a PhysicsComponent while in the process of refactoring my messy Player class. Today I decided to have a look at the rest of the Player class and see what else I could clean up.

The next biggest mess was how I was handling shooting and bullets. Basically each Player and Enemy had their own vectors of Bullets and handled them separately. The Bullet class seemed like a really good candidate for another GameObject – so the first step was to create a BulletObject. Bullets need to be drawn to the screen and also move around – so I’ve added both the SpriteComponent and PhysicsComponent to my BulletObject (as I did with the Player).

Looking at the existing code for moving the Bullet it quickly became clear that my static const friction value was going to have to become a regular member variable. My bullets don’t have constant acceleration, so really I’m just applying a force when they are shot and then never degrading their velocity. So I set the “friction” in my bullets to 1. I’ve not been able to test all this yet, so I’m going to be amazed if it all works first go.

As I predicted in my last post – I had to repeat the code where the physics and sprite components have to work together before the sprite can draw. So it definitely needs to change – I’m just not sure how (yet). Might sit on that one for a while.

Once the bullet object was out of the way I decided to make a BulletManager that would be responsible for storing all the bullets. This way the player and each of the enemies can just have references to the BulletManager. The BulletManager currently has a vector of pointers to Bullet objects – each time I call the Shoot function I create a new Bullet and add it to the vector. Not particularly cache-friendly but I will fix that when I get around to adding functionality for object pooling.

Once that was done I moved the Player’s shoot code into it’s own function and everything was looking a lot cleaner. Here’s how it looks:

void PlayerObject::shoot()
{
 if (m_fFireCoolDown <= 0) {
     m_fFireCoolDown = 0.3f;
     PhysicsComponent* physicsComponent = 
     dynamic_cast<PhysicsComponent*>(GameObject::GetComponent(PHYSICS));
     float rotationAngle = physicsComponent->GetRotation();
     glm::vec3 shootPos = physicsComponent->GetPosition();

     //calculate offset from player position in world space
     glm::vec4 offset = glm::rotate(glm::mat4(1), rotationAngle, 
     glm::vec3(0, 0, 1)) * glm::vec4(10, 0, 0, 1);

     m_pBulletManager->Shoot(rotationAngle, 
     shootPos - glm::vec3(offset.x, offset.y, offset.z));
     m_pBulletManager->Shoot(rotationAngle, 
     shootPos + glm::vec3(2*offset.x, 2*offset.y, 2*offset.z));
 }
}

I still think I’m going to store a reference to each component in each GameObject. Calling GetComponent each time I need to use it is a bit silly (and adds overhead).

The only other change I made was to add an “active” boolean to GameObject. I imagine this will be useful for all sorts of things, but for now at least it’s an easy way to mark a Bullet as no longer on screen so that it can be removed.

Next time I will probably refactor the Enemy class into an EnemyObject – but that shouldn’t take long. I’m thinking I could possibly create a HealthComponent once I’ve done that since both Player and the Enemies have health.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s