Catch the apple

In this mini project, you will delve a bit deeper into programming. You will create a small game where our valiant hero, the famous scientist Isaac Newton, tries to get the apple to fall on his head. The aim is for Newton to collect points by getting bumped on the head by as many apples as possible in half a minute. Again, we’ll go step-by-step as we explain.

  1. Create an apple and a scientist

    Create a game screen. For now, apples will be represented by circles which fall from the sky. Newton will be represented by a square at the bottom of the screen.

    
    

    New commands:

    • rect(x, y, width, height): Draws a rectangle. x and y sets the location of the upper left corner, width and height sets the size.

    Newton (the square) is stationary so we need to implement controls to move him.

  2. Take control of Newton with the keyboard

    Make Newton move with the arrow keys. To access the keyboard from Processing, we must use a keyCode which is used to identify individual keys. The keyCode is an internal system variable which can be used to detect which key has been pressed. To see what key was pressed we need a function called keyPressed(). We will also need a variable to store the squares X-axis (horizontal) coordinate so we can adjust it each time the key is pressed.

    
    

    New commands:

    • keyPressed(): this function is run every time a key is pressed. This means that whatever code you have written inside this function will be executed when you’ve pressed a key.
    • keyCode: returns the value of the key you have pressed.

    The variable nX is used to set the x position of Newton. Every time the right arrow key is pressed, nX increases by 3 units and every time the left arrow key is pressed nX decreases with 3 units. So now you can move the square around the screen from left to right, but be careful because the square can move off the game screen.

  3. Limit the movement of the square

    So that Newton doesn’t fall of the screen, we need to limit his movement to within boundaries of the window. For this, you will use the conditional function if-else to limit the X-coordinate to always stay within the program window, i.e., it must be greater than 0 but less than the width of the window or width .

    
    

    In the above program, the only difference is that the square will no longer be able to move off the screen.

  4. Falling Apples

    Modify the program to make the apple (circle) fall from the top of the screen. For this, you need a variable to hold the Y-coordinate of the circle. Once the apple hits the ground, it will disappear and another will appear at the top.

    
    

    We created the variable mY to store the Y-coordinate of the apple. Each time draw() runs mY increases by 1. The apple is redrawn closer and closer to the bottom of the window. Once the apple reaches the bottom of the screen, that is if mY is more than height, it should magically reappear at the top of the window.

  5. A little random

    The apples always fall from the same position at the top of the screen, so it is quite predictable. Changing the X-coordinate of the apple changes its source. There is a function called random() that we can use to generate random numbers. You will need a new variable to store the X-coordinates of the apple. Note that the X-coordinate will be changed only when the apple reaches the ground – otherwise, the apple would shift during its fall.

    
    

    New commands:

    • random(high): generates a random number between 0 and the number high. You can also use random(low, high) to get a random number between low and high.

    With this change in the program, you will see that apples come from random points on at the top of the screen.

  6. Collision Detection

    Detect when the apple lands on Newton’s head to count the points. Detecting when two objects collide on the screen is called collision detection. It employs the conditional if-else to see if the circle is on the square. If true, both objects will become red. To make the program easier, we will create a variable to store the square’s Y- coordinate so we can make comparisons easier.

    
    

    New commands:

    • if( test1 && test2){ statements }: this is used when several tests are made in one if() statement.  && means that both statements must be true – if test1 and test2 are true, then the code inside the curly brackets is executed.

    The collision detection consists of two if() statements; the first checks if the circle is at the same height as the square. If it is, the second if() statement is executed. That one checks if circle is on top of the square. If it is the fill() color is set to red. A collision would look similar to the image below:

    In addition, if you enable the following lines in the program:

    // lines of code to understand how collision works
    // erase the comment in order to see the code
    line(0,mY-10,width,mY-10);
    line(mX-10,0,mX-10,height);
    line(0,mY+10,width,mY+10);
    line(mX+10,0,mX+10,height);

    You will see a series of lines on the screen framing the movement of the objects. You can use this to better test and visualize the collision.

  7. Faster

    Do you want to make the apples fall faster? To do this, we will make a float variable mV which stores the fall speed of the apple. You can change the speed by changing the value of mV.

    To better control the movement in the Y-axis of the apple, we will change the variable type of mY from int to float. A variable with of the data type float can store decimal numbers.

    
    

    Instead of increasing mY by 1, we increase it with mV. Aside from changing the speed, nothing else has changed in the program.

  8. Newton likes gravity, so give him more

    Modify the program so that the apples accelerate due to gravity. The apples will go faster and faster the further they fall. As you know, the speed is calculated using acceleration and distance travelled. To make these operations as simple as possible, we will use a float variable that holds the rate of acceleration.

    
    

    mA increases mV a little each time, which increases mY. Thus, the velocity will increased a little more each time. Aside from the acceleration, nothing has changed in the program.

  9. Count the points

    We will use a function called text() to display the points. We will also need a variable to keep score.

    Note: As you start having a lot of variables in your program, it is recommended that you add comments to remind you of their purpose
    
    

    New commands:

    • text( text, x, y): draws a text on the screen on the coordinates x and y.

    We’ve declared a new variable p that increases by 1 each time a collision is detected. Next we display the point counter in the upper right corner.

  10. Oops, Error

    You may have noticed that your program is posting incorrect points. Each time the apple falling on Newton’s head … eh … when the circle touches the square, your counter goes up about 5 points. This is because the counter keeps on counting as long as the apple overlaps Newton. To correct this you have a couple of options:

    • Make the apple relaunch once collision is detected.
    • Stop counting when the initial collision is detected and restart counting when a new apple is released.

    To try any of these options, you need a variable of type boolean to store the apple’s state. Remember what a boolean is? It’s a variable that can either be true or false. Using it, we can tell the program whether or not to count points.

    
    

    New commands:

    • if( boolean ) : checks if a boolean variable is true. You can also check if it’s false by writing if( !boolean ).  ! means “not”.

    Now the program will only add a single point per apple. This is because we only add a point when the boolean variable pCount is true. It’s set to false right after the point is added. When the apple is relaunched pCount is again set to true.

  11. And time begins

    The objective is to get as many apples as possible within a limited span of time. We need a timer that is also displayed on the screen so that players know when the game will be over. The optimal duration of the game is half a minute. Too short will make the game too difficult and too long, will make it lose its challenge. To measure time, we will use a function called millis() which counts the milliseconds that have passed since starting the program. You can use this function to inform the player that there are 30000 milliseconds (30 seconds) until the game ends. To do this we need a new variable of type, long. The function noLoop()will tell our program to end once time has run out. Finally, we use text() to display the time left on the screen.

    
    

    New commands:

    • long: this is a datatype for large integers. It’s convenient to use this when handling time variables because that data can be very large. Do you remember how we explained that a variable is a container of data? Well, you could say that long is a larger container than int. An int runs out of space faster than a long.
    • noLoop(): stops the continuous execution of the code inside draw. To resume the program you would need to call loop().

    The time variable t is initialized in setup() to mark the start time. After we’ve drawn Newton and the apple, we create a new variable called timer to calculate how much time has passed. This is done with(millis()-t) / 1000; current time minus the start time and then divided by 1000 to equal seconds.

    If timer is more than 30, we call noLoop() to stop the program. As long as timer isn’t more than 30 seconds, use text() to display how much time there is left.

    The game timer will look as follows:

  12. Add Images to our game

    Include images for the apple, Newton, and the background. You can create your own images, look online, or use the ones provided . PNGs allow transparency between the image and the drawing, so it is important to use that format for a better looking game. Please note that if your images have different proportions from the ones provided, you’ll have to correct the values ​​in the part of the program dedicated to collision detection.

    
    

    To load our images, we use the same method as in the previous project using to arrays. Instead of changing the color to red when there is a collision, use the boolean pCount to change out the image of Newton.

    The end result of the game looks as follows:

Experiment further

To improve this game there are a number of things you can do:

  • Make custom images of your own.
  • Create an opening game screen that will load the game once a button is pressed.
  • Create a ending screen showing the results once time has expired.
  • Make it possible to restart the game after the time has run out – don’t forget to reset all variables that are needed.
  • Use scientific superpowers to make it move by changing the acceleration instead of speed.