Work on the hero
Losing condition : Oxygen and fuel levels
In my game, my hero's spaceship is wrecked : The oxygen leaked and the artificial gravity module (Yes that exists in my game !) is out of order. The hero must use is jetpack equipped spacesuit to travel across his spaceship and reach the safety spaceship. While traveling, the hero must take care 2 parameters :
- Oxygen level : The oxygen level decrease with the time. When it reaches 0, the hero dies.
- Fuel level : The fuel level decrease every time the hero activate his jetpack to create an impulse. When the fuel level reaches 0, the hero can no longer move.
First, we'll add some constants to the GameConstants.java :
public class GameConstants {<span class="redactor-invisible-space"> <span class="redactor-invisible-space"> ... </span></span> //Hero constants public static float HERO_HEIGHT = 1.5f * PPT * MPP / 2; public static float HERO_WIDTH = HERO_HEIGHT / 2; public static float JETPACK_IMPULSE = 100; public static float TOM_ROTATION = 5; public static float MAX_OXYGEN = 120; public static float MAX_FUEL = 100; public static float FUEL_CONSUMPTION = 5; ... }
You can see that in the Hero constants block I added 3 constants :
- MAX_OXYGEN : basically, it's the number of second you can last when the oxygen level is at 100%
- MAX_FUEL : The maximum amount of fuel
- FUEL_CONSUMPTION : The amount of fuel you burn for a 1 second impulse.
Then, we need to modify the Hero.java (I only show the difference with the previous code) :
public class Hero { ... private float oxygenLevel, fuelLevel; public Hero(World world, Camera camera, TiledMap tiledMap){ ... oxygenLevel = GameConstants.MAX_OXYGEN; fuelLevel = GameConstants.MAX_FUEL; .... } public void displacement(){ oxygenLevel -= Gdx.graphics.getDeltaTime(); if(Gdx.input.isKeyPressed(Keys.W)){ heroBody.applyForceToCenter(new Vector2(0, GameConstants.JETPACK_IMPULSE).rotate(heroBody.getAngle() * MathUtils.radiansToDegrees), true); fuelLevel -= Gdx.graphics.getDeltaTime() * GameConstants.FUEL_CONSUMPTION; } if(Gdx.input.isKeyPressed(Keys.A)) heroBody.setAngularVelocity(GameConstants.TOM_ROTATION); else if(Gdx.input.isKeyPressed(Keys.D)) heroBody.setAngularVelocity(- GameConstants.TOM_ROTATION); else heroBody.setAngularVelocity(0); System.out.println("FuelLevel = " + fuelLevel + " || OxygenLevel = " + oxygenLevel); } public float getOxygenLevel(){ return oxygenLevel; } public float getFuelLevel(){ return fuelLevel; } }
You can see that I created the 2 float oxygenLevel and fuelLevel, and I initiate them with their Max values in the creator. Then, in the displacement(), I added
oxygenLevel -= Gdx.graphics.getDeltaTime();
which makes the oxygenLevel decrease by one unit every second. I think I should rename the displacement() method, since it not only deal with the hero displacement now...
I also modify the action when we press the W key :
if(Gdx.input.isKeyPressed(Keys.W)){ heroBody.applyForceToCenter(new Vector2(0, GameConstants.JETPACK_IMPULSE).rotate(heroBody.getAngle() * MathUtils.radiansToDegrees), true); fuelLevel -= Gdx.graphics.getDeltaTime() * GameConstants.FUEL_CONSUMPTION; }
Now when we press the W key, the fuelLevel decreases by GameConstants.FUEL_CONSUMPTION units every second.
In order to monitor the oxygenLevel and the fuelLevel in the console, I also added :
System.out.println("FuelLevel = " + fuelLevel + " || OxygenLevel = " + oxygenLevel);
And here is an illustration of the oxygen and fuel consumption :
You can see in the console that the FuelLevel doesn't decrease when no impulse is applied to the hero, while the OxygenLevel decreases all along the animation.
Finally, to be able to lose, in the render() of the GameScreen we need to add some code to check the oxygenLevel and fuelLevel, and if one of these falls under 0, the player loses.
For now, we'll only print a message in the console, when the player loses. In the render() of the GameScreen I added :
if(mapReader.hero.getOxygenLevel() < 0 || mapReader.hero.getFuelLevel() < 0) System.out.println("You lose !");
Edit : I decided to change the losing condition : Now we lose only if the hero is out of oxygen. It makes more sense. Even if the hero is out of fuel for his jetpack, he still can finish the level if he reaches the exit fo the room. For example, you have just enough of fuel to create one last impulse to direct your hero towards the exit door. Once the jetpack is out of fuel, without air friction and gravity, the hero will keep going in the same direction. If he reaches the exit door before being out of oxygen, he succeeds in passing the level.
Thus, in the render() of the GameScreen I have now :
if(mapReader.hero.getOxygenLevel() < 0) System.out.println("You lose !");
In the future I'll have to create a pop-up box that asks the player if he wants to restart the level when he is out of fuel, in order to prevent the player from waiting to be out of oxygen when he has no more fuel and no hope to reach the exit.