Enabling Jumper to jump

First of all, we only want Jumper to be able to jump when he has a solid surface under his feet. We can test this by checking if a Rectangle one pixel lower than Jumper's bounding rectangle would be blocked. If that is the case, we let him jump.

So go ahead and introduce this method in the Jumper class. Notice the "!" in front of the last line. That means not. Which means that if HasRoomForRectangle is true (Jumper is floating) then we return NOT true (we're not on firm ground) and vice versa.

because no matter whether we were falling fast when we hit the floor, we don't want our upward momentum to have any memory of our downward speed (which would be the result of using the -= operator), so we just set it to a firm negative 25 upward.

Go ahead and fiddle around with the values in AffectWithGravity and SimulateFriction until you are satisfied with how Jumper moves.

Updating debug information

Go ahead and add some additional debug information to the game, so you can see whether Jumper is on firm ground.

And since our Draw method is getting pretty long, refactor the it, so you extract the writing of debug information in a separate method.

What happens in StopMovingIfBlocked is that we get the last movement by subtracting where Jumper was before he moved from where he ended up. If there was no movement on an axis, we set that part of the current movement to zero.

We will then call StopMovingIfBlocked as the last line of Jumper's Update():

If we could get that down to about ten lines we might increase readability. So see what I do here, and if you like it, copy it. If you don't - then don't .

Wrapping multiple variables and related functionality into a wrapper

First of all we have four lines which are just initialization. We could wrap all those variables and the math up into a structure, and initialize it with the same data that WhereCanIGetTo receives. Add a new class to your SimplePlatformerGame project, name the file MovementWrapper.cs and move all this code

We use a struct instead of a class, since objects (instantiated from classes) are only cleaned out (garbage collected) at irregular intervals, which might make our game stutter. Structs (like int, float, Vector2, etc.) are garbage collected the moment you leave the "{...}" in which they were created.

The most important gotcha to remember when working with structs is that you always get a copy of it when you pass it to a method, so you can't just pass it to a method, change some values on the struct in the method, and then expect to see the changes reflected in the reference to the struct that you had outside the method (see example 2 for more info on this).

That not only made four lines into one, it also collected all the information about the move we're about to perform into one neat little package, which makes it easier to refactor further, and extract methods from whatever else we're performing, just wait and see . Now see what our WhereCanIGetTo method looks like

Basically, we just updated the references to the four variables to use the variables contained in MovementWrapper instead.

Refactor nondiagonal movement out into a separate method

Since we have all the variables for moving in the MovementWrapper struct, we can easily refactor the nondiagonal part of the movement out in a separate method. First create the method CheckPossibleNonDiagonalMovement, and move the code there.

And add a new method call CheckKeyboardAndReact to listen for keyboard input in SimplePlatformerGame.Update. In This method will react to someone pressing F5, and call a new method RestartGame() which creates a new Board and puts Jumper back in the top left corner:

There are many small changes you can make. I added some functionality which adds a shadow under our debug text, and changed the jump key to SPACE instead of UP. You go ahead and do whatever you wish - it's your code now

Here's the final result

Play around with it, expand it and have fun!

If you need help with anything in particular, or you want to give feedback on improving my tutorial feel free to leave a comment

Also a question. Any chance of making per pixel collision instead..(a tutorial maybe)
And finally i would really like to learn A* path finding, you have any expertise on that maybe do an tutorial.
Well appreciate all you work thank you very much.