Full LibGDX Game Tutorial – Shooting

shooting mechanices

Sharing is caring!

Full LibGDX Game Tutorial – Shooting

Welcome to part 14 of our Full LibGDX Game Tutorial. This part will focus on allowing the player to start shooting enemies. If you haven’t seen the earlier parts of this tutorial I advise you to start at Full LibGDX Game Tutorial – Project setup as this tutorial continues from these earlier parts. For those of you who have come from part 13, you can continue on.

Now our game has some enemies, we can think about adding a player shooting action that will allow the player to shoot bullets that will instantly kill and enemy. The bullet and enemy will then de-spawn. Since we want to be able to tell when a bullet has hit an enemy we will need to add a collision component to out enemy so they are included in the collision system.

Shooting – Create Enemy Update

update the createEnemy method in your levelFactory so enemy now has collision component:

Shooting – Collision System Update

Now the enemy has a collision component we need to update the collisionSystem so it is able to process enemies. Previously we only cared about collisions with the player so the collisionSystem used to take the player as an argument. This is no longer the case so we have to remove the player from the constructor and only process entities with collision components. Update your collisionSystem to match this:

Here we have removed the player from the constructor and then split the processEntity into a player and enemy checking version. Currently, this is the only two objects we need to check collisions on.

Shooting – Player Component Update

Now we are checking for collisions we need the player to be able to produce bullets or we won’t have anything to make the collisions. The first thing we will do is to add a shootDelay and timeSinceLastShot to our player component. These values will be used to limit the amount of shots a player is able to shoot per second. So let’s update our player component:

Shooting – Player Control System Update

In our game, we will allow the player to shoot with the mouse button. This will allow us to see where the player wants to shoot towards by taking the mouse position when the mouse button is pressed. Luckily the mouse position and mouse click action is already taken care of in our controller. All wee need to do is check for them in our player control system. So let’s update our playerControlSystem to include this code:

Shooting – Create Bullets Method

The player can now shoot, but, we don’t have the method createBullet yet to create bullets… ooops! Let’s fix that by adding the method to create bullets:

Most of this you have seen before. The extra items are b2dbody.body.setBullet(true); which changes the body to a bullet type and bodyFactory.makeAllFixturesSensors(b2dbody.body); which changes it to a sensor. By changing the body type to a bullet, we’re telling box2d that this is a small fast moving object and it should be processed as such. This will stop the object from travelling through objects which can happen when not set as a bullet. We changed the body to a sensor too, so that it won’t push the player when it spawns inside the player and it will still respond to contacts with other bodies.

Shooting – Bullets System

Great, we have bullets and the ability to shoot them, but they won’t move unless we tell them to and we are going to tell them too with a new system called the bulletSystem. This system will control the bullets by setting their velocity and it will also update them when they die so they can be removed later.

All this system does is cycles through all the bullets and sets their velocity and updates the body to isDead when it dies.

Shooting – Main Class Update

For this system to work we need to add it to our engine in the MainClass. Remember the systems are called in the order they are added to the engine so add them in this order or you may end up with unexpected results:

Shooting – Body Component Update

In some of the previous code snippets, you may have noticed this b2body.isDead = true; but our bodyComponent doesn’t have this property. That’s because you’re going to add it now.

This has been added so we can check if a body is dead and needs to be removed from our world.

Shooting – Physics System Update

We will also want to remove the entity from our engine since its dead and no longer has a body. To do that we will update our physicsSystem’s update method.

Shooting – Testing

If you run the game now, you will be able to shot a single enemy and that enemy will die. If you, however, try to shoot again you will find that no Bullet is fired and this is due to how we have been making components. We are currently using a PooledEngine (Want to know more about pooling? Check out this LibGDX Object Pooling guide) which keeps objects we create after they are removed so they can be used again to save time recreating them. This is good as it can speed up your game and stops your memory becoming too fragmented. A problem with this is if we don’t reset our components for the re-used entity the data stored in it will still be present. In our case, we have set the bullet to dead. So every time we reuse a dead bullet it’s still dead and gets removed instantly. To stop this from happening we have to add the poolable interface to our components and override the reset method to reset all our variable in our components.

We will start by updating the BulletComponent to use the poolable interface:

As you can see we have imported the poolable interface and then overridden the reset method, resetting all the values to the original values defined above. We need to repeat this for all our components. Let’s do the CollisionComponent next:

Again we implement the poolable interface and then rest the collisionEntity. Since we didn’t define a value for the collisionEntity we are resetting it to null as it would have been if the component was brand new. Do the same for all your other components that have variables in. Some components like the WaterFloorComponent don’t have variables in and don’t need the poolable interface. Some components have final variables in and these final variables don’t need reset.

Shooting – Final Task

Our final task in the part of the tutorial is to remove bullets that travel too far from the player. This is a performance-related change to help reduce the amount of objects in the game. If we don’t remove these objects then they will be forever floating about even when not on the screen or ever going to hit an enemy. To do this we’re going to check the distance the bullet is from the player and if it’s over a certain amount we will set the bullet to dead and it will be automatically removed.

Update your bulletSystem to:

Notice we added the player to the constructor so this will have to be added in the main class. What we have done is checked if the bullet is more than 20 units away from the player on any axis. If the bullet is that far then it is probably off the screen and can be deleted. We have also added a System.out line so we can see in our console if a bullet was deleted.

If you test your program now you should be able to shoot the enemies and they will die. You will also be able to shoot off the screen and then after the bullets have gotten far enough away they will die and add a message to the console.

As usual here is a link to download the completed tutorial project from stormyvids.

In the next part( part 15 ), we will be updating our code to make some improvements to the level generation we will also add some stuff to the end screen so that when the player dies they are presented by the end screen and then back to the main menu ready for the next attempt to beat their high score.

This video shows some of the updates we will be making:

[embedyt] https://www.youtube.com/watch?v=Zo63u1Gql-k[/embedyt]

AS usual, if you notice any mistakes or have some suggestions. Please feel free to leave a comment below.

← Ashley Enemy System Contents General Improvements →

 

Sharing is caring!

9 Replies to “Full LibGDX Game Tutorial – Shooting”

  1. Caterpillar says: Reply

    Hey is the series still ongoing?

    1. Yes, I add new entries when I have the spare time to write them. I aim for at least 1 per month.

  2. Great tutorial, not really suitable for total beginners, but a lot can be learned from it anyway. It would be cool to see more of it. Keep it up!

    1. Thank you, I will.

      I would like to make it as easy as possible for beginners in this tutorial, so any suggestions on how to improve this series to make it easier for beginners is welcome.

  3. The camera isn’t following my player character. I can’t find anywhere in the code where it updates the camera position to amtch with how high the player has jumped, like in your video example. Where should this code be?

    1. Nevermind, figured it out

      1. Where did you find it? I’ve got the same problem and I’ve looked everywhere.

  4. The bullet isn’t being shot directly at my mouse. I think it’s because the angles aren’t correct, but i can’t seem to figure out what is wrong.
    I have tried copy-pasting your code directly, but it did not work either so i don’t think is a typo.
    Google couldn’t help me, do you perhaps have an idea of what could be wrong?
    Thanks in advance.

  5. I love this tutorial
    Please contact me.
    I need help with a project.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.