Boolean Logic and States
Posted: February 17, 2011 Filed under: programming Leave a comment »I’ve been fighting with an issue with the Physics Engine. Not really an issue with it persay, but perhaps I how I am using it. Basically, if you apply an amount of force on the X-axis while you jump and you hit a wall, you will effectively be stopped. Likewise if falling, you can stop falling by applying a force on the X-axis and you will stop on the wall. Now, in games like Super Meat Boy, you can wall slide, that is, apply a force against the wall and you will slowly slide down it however; You cannot completely stop while doing this. You can however jump off the wall.
This functionality, while fun in many games that take advantage of it, doesn’t currently have a place in my game concept. It just doesn’t feel good and actually looks more like a bug the way it was anyways. So I tried to fix it. I’ve messed with the friction, gravity, amount of force applied and none of it fixed the problem. Just now I considered a solution that I haven’t really used for a long time, in this fashion anyways. I use Booleans all the time for keeping track of things/states, but I rarely have a triangle relationship between three booleans.
I was already keeping track of when the player landed with bLanded. A player lands when their velocity is between 0 and 0.3. This is due to the accuracy of floats. Using a velocity of just 0 does work 99% of the time however, but when the game gets more intense, I’m sure that accuracy will drop. Now, my player input system uses the regular input system to create two outputs that range from -1 to 1. These outputs are called fLeft and fUp (there is also fForward but since the engine is using 2D physics, it is useless ATM). If fLeft is negative, the player is supposed to go left, if fLeft is 1 the player is going right. fUp is 1 for up and -1 for down. Yes, they should probably be renamed to something that represents more clearly what each value is called, but for now it works.
When the players velocity is within the range of 0.0 to 0.3 and bJump false, bLanded is set to true. Following that a check is made to see if Force.y is greater than 0 (Force.y is calculated by fJumpAmount*fUp, so Force.y will be a positive force in the Y direction and -Force.y will be a negative force in the Y direction). If Force.y is greater than 0.0, an impulse is applied on the Y-axis with a force of Force.y. In this case, the jump amount is 6000 because only Impulses will be used to work with thY-axis. In the grand scheme of things, the Velocity gets limited though, so I could probably just use a really high force value as well and apply a force instead. If an impulse is applied, bLanded is immediately set to false and bJump is set to true. This isn’t entirely true though, as for the time being, bJump is set to true whenever the velocity in the Y-direction is greater than 0 and bLanded is false.
Note: Eventually, I want to implement a function that will accept an offset location and calculate the force required to reach that offset. This way, I can use variables like “fJumpHeight” and “fGroundSpeed” to describe how the objects will move.
bFalling is set when the velocity is less than 0.0 and bJump is true, at which point bJump is set to false and bFalling is set to true, otherwise it is false.
So, bLanded is only true if bFalling is false and bJump is false. bFalling can only be true if bJump (but will set to to false after, so basically only if bJump is false – both of them can never be true at the same time). bJump can only be true if bFalling is false and bLanding is false. States. Simple, boolean logic at its best.
Now… one slight problem remains and that is air control. Games have had air control for ages and it is annoying when a game doesn’t have it. I disable forces in the X-axis until landing so…