Making a LibGDX Roguelike Survival Game Part 9 – Screen Shake & Inventory #gamedev

In the last tutorial trees could be removed from the map by interacting (pressing ‘E’) on them, as the trees are being cut down lets add in a small screen shake. On a tree being cut down we will add it the the Hero inventory (we will need to create a basic inventory).

[ Full source code for this tutorial ]

Rumble allows us to return a Vector allowing us to move the camera relevant to a shake size for a given time in seconds. The variables and methods in this class are all static, so we will be able to use the class without creating an instance of it. Rumble.rumble(1,10) will set the power to 1 and the length of the shake to 10 seconds, the current time is reset to 0.

We have to call the tick method to update the x and y values of the Vector3 to new random values taking into account the size of the shake and update the current time. When current time is greater than time (shake was lasted 10 seconds) we reset the time to 0.


import java.util.Random;
import com.badlogic.gdx.math.Vector3;

public class Rumble {
    private static float time = 0;
    private static float currentTime = 0;
    private static float power = 0;
    private static float currentPower = 0;
    private static Random random;
    private static Vector3 pos = new Vector3();

    public static void rumble(float rumblePower, float rumbleLength) {
        random = new Random();
        power = rumblePower;
        time = rumbleLength;
        currentTime = 0;

    public static Vector3 tick(float delta) {
        if (currentTime <= time) {
            currentPower = power * ((time - currentTime) / time);

            pos.x = (random.nextFloat() - 0.5f) * 2 * currentPower;
            pos.y = (random.nextFloat() - 0.5f) * 2 * currentPower;

            currentTime += delta;
        } else {
            time = 0;
        return pos;

    public static float getRumbleTimeLeft() {
        return time;

    public static Vector3 getPos() {
        return pos;
The interact method is changed to accept Entity as a parameter:

public void interact(Entity entity){}
When the Hero Entity interacts with another Entity we pass itself, this will give us access to the Hero in the Tree interact method:

// If interact key pressed and interactEntities present interact with first in list.
if(control.interact && interactEntities.size() > 0){
When a tree is removed we can use Rumble to change the power and time, 1 is a small shake and .2 of a second is a short period:

public void interact(Entity entity){
    remove = true;
    Rumble.rumble(1, .2f);
We update the render section of gameclass where previously there was only “camera.position.lerp(hero.pos, .2f);”, we now check if there is a shake/rumble to process, if there is then the camera is taken over by the rumble. When the rumble is complete the camera lerps back the the hero.

// Hero Position
if (Rumble.getRumbleTimeLeft() > 0){
 } else {
     camera.position.lerp(hero.pos, .2f);

Before we look at how we implement a basic inventory lets try out a larger shake just for fun:

Rumble.rumble(3, 5) :big_shake
Setup the “I” key to turn on inventory, we can use this to print out the current inventory when ever I is pressed:

public boolean inventory;
// Key up 
case Keys.I:
    inventory = true;
This is just a basic class to hold an array of inventory entities and will change in future tutorials. To future proof the idea of the inventory it is better to create a new class rather than testing some inline solution. The class uses a HashMap but any array type would be fine at the moment, we need methods to initialise the array, add to it, return its size and print to console our current inventory:


import java.util.HashMap;

public class Inventory {
    HashMap&amp;amp;lt;Integer, Entity&amp;amp;gt; entities;

    public Inventory(){

    public int getInventorySize(){
        return entities.size();

    public void addEntity(Entity entity) {
        entities.put(getInventorySize(), entity);

    public HashMap<Integer, Entity> getInventory(){
        return entities;

    public void print() {
        System.out.println("*** Inventory ***");
        for(int i = 0 ; i < entities.size(); i++){
            Entity e = entities.get(i);
            System.out.println("* ["+i+"] " + e.type.toString());

    public void reset() {
        entities = new HashMap<Integer, Entity>();
Add a new Inventory variable to the Entity class:

public Inventory inventory;
Inventory is initialised within Hero and not in the base class, not every Entity will require one:

public Hero(Vector3 pos, Box2DWorld box2d){
   type = EntityType.HERO;
   width = 8;
   height = 8;
   texture = Media.hero;
   speed = 30;
   inventory = new Inventory(); // Init Inventory
   reset(box2d, pos);
When an Entity interacts with a Tree we check if that entity has an inventory, at present only our Hero has an inventory, given this is true we add the Tree to the inventory array of entities, flag the tree for removal from the map and trigger some screen shake, more logic will be applied here later:

public void interact(Entity entity){
    if(entity.inventory != null){
        remove = true;
        Rumble.rumble(1, .2f);
Checking if inventory key has been pressed we can call the method/function that prints out the entities in the current inventory array and then set inventory boolean to false:

// Render method
    control.inventory = false;

Running the application and hitting down some trees our inventory will contain some entities, pressing “I” will print out the current inventory to the console:

*** Inventory ***
* [0] TREE
* [1] TREE
* [2] TREE












Leave a Reply

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

You are commenting using your 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 )

Connecting to %s