All change is not growth, as all movement is not forward.. [Ellen Glasgow]
How are the background images being drawn? We need 2 loops in order to draw a proper grid of background images (think of them like tiles).
But what are the values tilesX, tilesY, repeatX, and repeatY?
tilesX and tilesY need to be calculated based on the character's position, this will change the values of our loop variables "i" and "j" so that the background images will be repositioned under the character as it moves around.
The reason we use the negative value of the player's position divided by the width and height of the screen is because the player is constantly moving against the background, so we move the background against the player in the opposite direction.
The values repeatX and repeatY are how many times the background should be tiled so we don't see any edges around our background. These values may change depending on how large your background images are.
Notice the background uses a speed variable, this will control the speed which the background moves against the player's position. Smaller speeds (fractions < 1) will result in a scrolling effect called "Parallax".
This is our classic Character example with a few additions, first let's look at the character class:
The block class has 2 methods, one to check if the Character (who landed on the block) is still on it, the other will check if the Character collides with the block (basic box collision)
Finally in our main draw loop we only need to worry about calling the methods in the correct order and ensure our logic is sound.
Notice if the player is jumping it cannot jump again, if it has a block it will be checked to see if it's still on, if the player is jumping the gravity force is applied and all other blocks are checked. Optionally, the velocity is checked and if the player is rising, the fall method will be called to push the player back down.
Two methods are important in the Tile class: collision and inWindow
This is the same as the typical box collision, but notice how we use PVector.sub(first, second) to get the difference between the two vectors, and then store that information for later. Why? Because we will need it for the inWindow method and it's much better to calculate once and store it temporarily.
Also notice how we resolve the collision a little bit, and push the player away from the block. This is sort of a "magic number" solution that will probably need to be adjusted in your games. Otherwise the character's will stick to the tiles that are blocking tiles.
The inWindow method simply checks the stored values of absDiff to make sure they are within the tileBounds (how far tiles should be visible). This enables us to have large game worlds without having to draw every single game tile all the time. You should know already why this is important for performance.