Handling bullets

Most objects in the game fire bullets and they all pretty much need to be checked for collisions against bullets as well; the bottom line—bullets are important in Alien Attack. The game has a dedicated BulletHandler class that handles the creation, destruction, updating, and rendering of bullets.

Two types of bullets

There are two types of bullets in the game, PlayerBullet and EnemyBullet, both of which are handled in the same BulletManager class. Both of the bullet classes are declared and defined in Bullet.h:

class PlayerBullet : public ShooterObject
{
public:

  PlayerBullet() : ShooterObject()
  {
  }

  virtual ~PlayerBullet() {}

  virtual std::string type() { return "PlayerBullet"; }

  virtual void load(std::unique_ptr<LoaderParams> pParams, Vector2D 
  heading)
  {
    ShooterObject::load(std::move(pParams));
    m_heading = heading;
  }

  virtual void draw()
  {
    ShooterObject::draw();
  }

  virtual void collision()
  {
    m_bDead = true;
  }

  virtual void update()
  {
    m_velocity.setX(m_heading.getX());
    m_velocity.setY(m_heading.getY());

    ShooterObject::update();
  }

  virtual void clean()
  {
    ShooterObject::clean();
  }

private:

  Vector2D m_heading;
};

// Enemy Bullet is just a Player Bullet with a different typename
class EnemyBullet : public PlayerBullet
{
public:

  EnemyBullet() : PlayerBullet()
  {
  }

  virtual ~EnemyBullet() {}

  virtual std::string type() { return "EnemyBullet"; }
};

Bullets are very simple, they just move in one direction and at a certain speed.

The BulletHandler class

The BulletHandler class uses two public functions to add bullets:

void addPlayerBullet(int x, int y, int width, int height, std::string textureID, int numFrames, Vector2D heading);
void addEnemyBullet(int x, int y, int width, int height, std::string textureID, int numFrames, Vector2D heading);

The BulletHandler class is also a singleton. So, if an object wants to add a bullet to the game, it can do so using one of the above functions. Here is an example from the ShotGlider class:

TheBulletHandler::Instance()->addEnemyBullet(m_position.getX(), m_position.getY() + 15, 16, 16, "bullet2", 1, Vector2D(-10, 0));

This will add a bullet at the current location of ShotGlider, with a heading vector of V(-10,0).

Both add functions are very similar; they create a new instance of PlayerBullet or EnemyBullet and then push it into the correct vector. Here are their definitions:

void BulletHandler::addPlayerBullet(int x, int y, int width, int 
  height, std::string textureID, int numFrames, Vector2D heading)
{
  PlayerBullet* pPlayerBullet = newPlayerBullet();
  pPlayerBullet->load(std::unique_ptr<LoaderParams>(new 
  LoaderParams(x, y, width, height, textureID, numFrames)), 
  heading);

  m_playerBullets.push_back(pPlayerBullet);
}

void BulletHandler::addEnemyBullet(int x, int y, int width, int 
height, std::string textureID, int numFrames, Vector2D heading)
{
  EnemyBullet* pEnemyBullet = new EnemyBullet();
  pEnemyBullet->load(std::unique_ptr<LoaderParams>(new 
  LoaderParams(x, y, width, height, textureID, numFrames)), 
  heading);

  m_enemyBullets.push_back(pEnemyBullet);
}

A big advantage of having a separate place to store bullets like this, rather than have objects themselves manage their own bullets, is that there is no need to pass objects around just to get their bullets to check collisions against. This BulletHandler class gives us a centralized location that we can then easily pass to the collision handler.

The update and draw functions are essentially just loops that call each bullet's respective functions, however the update function will also destroy any bullets that have gone off the screen:

for (std::vector<PlayerBullet*>::iterator p_it = 
m_playerBullets.begin(); p_it != m_playerBullets.end();)
{
  if((*p_it)->getPosition().getX() < 0 || (*p_it)
  ->getPosition().getX() >TheGame::Instance()->getGameWidth()
  || (*p_it)->getPosition().getY() < 0 || (*p_it)->
  getPosition().getY() >TheGame::Instance()->getGameHeight() || 
  (*p_it)->dead())// if off screen or dead
  {
    delete * p_it; // delete the bullet
    p_it = m_playerBullets.erase(p_it); //remove
  }
  else// continue to update and loop
  {
    (*p_it)->update();
    ++p_it;
  }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.150.231