This week we’ll continue working on our projectile system. By the end of this tutorial we will have:
- Changed the arrows initial position so that it aligns with the player’s bow.
- Made the projectiles move through the environment.
- Made the projectiles collide with the environment.
Similarly to the textureDirectionBindings I’ve made this map static for the same reasons I outlined in the previous tutorial: it reduces memory usage.
If you don’t recognise the EnumClassHash then you probably don’t need it to compile, see the previous tutorial where I created and discussed the need for the hash class. If you didn’t need it last week then you don’t need it now and you can just remove it so the declaration looks like this:
We’ll insert the four offsets in the Start function. I’ve chosen the following offsets:
- Up = 0, 0
- Left = -8, 3
- Down = -3, 15
- Right = 8, 3
We’ll populate the map in the Start function (again). Each direction will be stored along with the normalised velocity for that direction:
- Up = 0, -1
- Left = -1, 0
- Down = 0, 1
- Right = 1, 0
You’ll notice that the arrows do not collide with the environment and will fly off into the abyss. To fix this we’ll move onto task number three: enabling the projectiles to collide with the environment. Luckily we have already written a collision system that we can use by adding a C_BoxCollider component to each new arrow we spawn.
Before we add the component we need to add a new collision layer for the projectiles. Collision layers are used to control which objects collide. For example, we can add an object to the collision layer of ‘Projectile’ and set that to collide with another collision layer called ‘Tile’. Using layers we can minimise the number of collision checks we perform. For more information check out the previous tutorial where we wrote the layer system. To add a new collision layer we need to first add a new entry to the CollisionLayer enum in C_Collider.hpp
We assign the Projectile layer the number 4. For each layer, we create a bitmask (link) that sets bits at specific locations to determine whether a layer collides with another. For example, if we assign a layer a bitmask with the bits at position 1 and 3 set then we know that layer collides with the ‘Default’ and ‘Tile’ layer. For more information on why we assign the entries in the enum specific numbers have a look at the tutorial where we created the Collision system. We initialise the layer with it’s associated bitmask in the constructor of S_Collidable.
After the C_BoxCollider is added to the projectile, the colliders size is set to 32 * 32 pixels, which is larger than the arrow image but will help show the collision using the debug drawing system. As the name suggests a C_BoxCollider uses a box to check for collisions. We’re using a box collider for the arrow because it is relatively quick to check a collision between two squares (i.e. a tile and the box around the projectile).