Bonk.io clone!

One of the most popular and entertaining .io games out there right now is bonk.io If you've not played it you should definitely check it out. The game is pretty simple. You're a little ball and you bounce off the ground and various objects. You have some ability to affect your motion, but if you get bounced by some object or some other player so that you fly off the board you lose the game. It's a little bit like sumo wrestling that way.

Here is the (video) game plan: (1) Add gravity to the pong game. (2) Add horizontal forces that are controlled by the left and right arrow keys. (3) Optional Challenge #1: Add a game over, (4) Optional challenge #2: Add vertical forces (besides gravity) that are controlled by the up and down arrow keys. (5) Have fun!

Step 1. Check out this modified version of the pong game

Click here to look at this modified version of the pong game!

Step 2. Look closely at the code!

function draw(){

    // Update velocity
    vy += deltaVy;
   
    // Update location
    y += vy*dt;
  
    ay = 0; // fix this!!
    deltaVy = ay*dt;
  
    if (y - blob_radius < 0) {
       vy = -vy;
    }
  
    // Draw axes and other stuff
    // This will clear the screen and re-draw it
    display();

    drawForce(x,y,0,-mass*g);
    drawBlob(x,y,vx,vy,deltaVx/dt,deltaVy/dt,blob_radius);
  
    // Add more graphics here before the end of draw()
 
} // end draw()

At this stage the ball shouldn't actually do anything when you run the code because gravity hasn't been added yet as you can see from clicking this link

Look closely at the code. What looks different from the pong game? Do parts of the code remind you of any other exercises?

Step 3. Add gravity to the code!

You may notice this code:

  ay = 0; // fix this!
  deltaVy = ay*dt;

The code above just means that there is no gravity (acceleration is zero). You may notice that near the beginning of the code there is now a variable g = 9.8;. Add gravity by setting ay = -g; What happens now? Your code should behave like this

Step 4. Give the ball an initial velocity!

Step 4a. Set vx = 15

Near the beginning of the program there is this code:

vx = 0;
vy = 0;

This sets the initial velocity of the ball. Change the code to this:

vx = 15;
vy = 0;

After you make this change your code should behave like this. The velocity vector isn't pointing perfectly straight up or straight down anymore, but the ball isn't moving to the right either.

Step 4b. Let the ball move horizontally

Look carefully at the code and modify it so that the ball actually moves horizontally. This is very much in the spirit of other exercises where things only move in 1D and you have to make it go in 2D (examples: Move the blob, Accelerate the blob and Planetoids)

Make sure your code acts like this! The ball should bounce a few times on the ground before it moves off the screen.

Step 5. Add horizontal forces!

The game would be a lot more fun if you could affect the motion of the ball with the arrow keys. Here is some code you can add to do that:

    Fx = 0;
    if (keyIsDown(LEFT_ARROW)) {
        Fx = -15;
    }
    if (keyIsDown(RIGHT_ARROW)) {
        Fx = 15;
    }
    Fnetx = Fx;  // why the extra step?
    ax = Fnetx/mass;
    deltaVx = ax*dt;

You should be able to drop this into the code and it should work. If it doesn't work, make sure you are updating BOTH the velocity in the x direction AND the velocity in the y direction!

Step 6. Add arrows to show the horizontal force

You can display the horizontal force (Fx) on the screen with this line of code:

drawForce(x,y,Fx,0);

Make sure you paste this code close to the other drawForce command!, otherwise it might not work because the code from Step 4 determines Fx, and because display() clears the screen

If you follow all these steps your code should behave like this! This is pretty close to the original bonk.io game, at least in terms of the physics.

Step 7. Add code to show the path of the ball

After display(); you can add this code and it will show the path of the ship:

    for( i = 0; i < xhistory.length ; i+= 1) {
     drawPoint(xhistory[i],yhistory[i]); 
    }

Step 8. Add a graph of $v_y$ versus time!

You can add a plot of $v_y$ versus time by adding this code to the program. You can put it anywhere after the display() function

graph1.addPoint(vy);
graph1.display();

Press the button above to copy the code to the clipboard. In the code editor press Control+V to paste it into the code.

Does the plot make sense to you? Why does it look so jagged like a sawtooth?

Challenge #1: Add a Game Over!

In the game of bonk.io the game over happens if the ball is y < 0, but if there is a floor on the bottom of the game (as many of the levels have), then that doesn't happen unless the ball is off the screen to the left or off the screen to the right.

Modify the code to add Game Over behavior like the bonk.io game! To help get you started, here is the game over code from the Lunar Descent exercise

    if (y < 0) {
     drawText('Game Over!',0.42*width,height/2); 
     noLoop();
    }

Paste the above code into your program, but when you run the code you will notice that it doesn't do anything. This is because there is this code that changes vy before the object can get to y < 0

    if (y - blob_radius < 0) {
       vy = -vy;
    }

This code is similar to what the real bonk.io game does, but in the real game if your blob moves outside of the screen (x < 0 or x > width) it won't bounce when it gets close to y = 0, and instead it will trigger a game over. If you've never played bonk.io before, here is a demo of how the "game" over behaves. Notice that the game over happens not when the blob reaches the edge of the screen, but after it passes the edge and then drops down to y < 0!

Try to get the behavior in the example you just played with by modifying this code:

    if (y - blob_radius < 0) {
       vy = -vy;
    }

You need to modify the if statements so that the bounce only happens if 0 < x < width

Advice #1: Review the if statements in the Pong game

Advice #2: You can use multiple or/and symbols in one if statement or you can make two or even three if statements inside of each other to get it to work. There is more than one right way to do it.

Challenge #2: Add vertical forces

If you've gotten to this point and done everything so far correctly, there is still an important element that is missing from our bonk.io clone. Specifically, the real bonk.io game has vertical forces controlled by the up and down arrows that are very important to the game. In fact, most bonk.io levels start with the ball on the ground at rest and you use the up and down arrows to start bouncing.

Add vertical forces to the code by adapting adapt this code from earlier to the y direction:

    Fx = 0;
    if (keyIsDown(LEFT_ARROW)) {
        Fx = -15;
    }
    if (keyIsDown(RIGHT_ARROW)) {
        Fx = 15;
    }
    Fnetx = Fx;  // why the extra step?
    ax = Fnetx/mass;
    deltaVx = ax*dt;

The idea is that you will modify this code so that the up and down arrows create a vertical force (Fy) and this factors into the change in velocity in the y direction (deltaVy)

In the above we've highlighted this line of code:

Fnetx = Fx;   // why the extra step?

The reason we highlighted this is that we don't absolutely need this line for the force in the x direction. You could just skip it and use ax = Fx/mass; instead of ax = Fnetx/mass; and everything would still work fine.

So why bother with Fnetx? Answer: when there is more than one force, it is only the "net" force that matters. In this case (Fnety) we will have a vertical force (Fy) and the weight (-mass*g). Both of these forces contribute to the net force. So when you write down Fnety you'll want to put down something like this:

Fnety = Fy - mass*g;

This is all that was meant by "why the extra step?" We were just pointing out that, in general, one can have multiple forces in the x & y directions.

Advice #1: Remove this code:

    ay = -g; 
    deltaVy = ay*dt;

Replace it with your modified version of the horizontal force code above.

Advice #2: Add force arrows for the vertical forces with this code:

drawForce(x,y,0,Fy);

When you're done your code should behave like this!

Finished!

Comments on further improvements to the game

Even if you have completed both challenges, you may notice some things that we are still missing. Perhaps the most important one is that bonk.io is not a single player game!

Here's how we would do one step better than this: Use the key variable to allow a player to use the AWSD keys to control the ball. Let the other player use the arrow keys. Add variables for the second ball (example: x2, y2, vx2, vy2).

This approach should work fine, but we would also have to add code if the two balls collide with each other (which would be an elastic collision). Elastic collisions turns out to be more tricky to do in two dimensions than perfectly inelastic collisions, which was the focus of the momentum coding activity. There is a brief discussion of 1D elastic collisions in the momentum coding activity which involves a relatively simple formula that arises from the conservation of momentum and energy in that case.

In 2D elastic collisions we still use the conservation of energy and momentum to get the answer but it turns out to involve quite a bit more algebra which you can read about in the "Two Dimensional" section on the Elastic Collisions, and see especially the figure on "Two-dimensional Elastic Collisions" Advice: assume $m_1 = m_2$ to make the formula "Two-dimensional collision with two moving objects" easier to deal with. This just means the balls have the same mass, which in bonk.io is certainly true.

Eventually we will do a whole coding activity just on getting two objects to bounce off of each other elastically. If you can't see how to convert the formula on the wiki page into a working program, you're probably not alone.

How to get full credit on this assignment!!!

1. Write a sentence or two comparing this code to other activities (Step 1)

There are parts of the code that were used in other coding activities. Just name the parts of the code and the coding activities where they came from.

2. Make sure gravity is in the code and the ball bounces (Step 3)

Follow the directions in step 2 and make sure your ball accelerates towards the ground. This only requires changes to the line of code that says // fix this!. At this stage your could should behave like this

3. Make sure the ball can move horizontally (Step 4)

As in Move the blob, Accelerate the blob, and Planetoids you need to make sure the object can move in two dimensions instead of one. In those examples, the object could only move in the x direction, and you had to modify the code to get it to also move in the y direction (which makes for a much more fun game). Here the object only moves in the y direction and you have to modify it to also move in the x direction. Otherwise it's the same task as before. After you modify the code it should behave like this

4. Add horizontal forces (Steps 5 & 6)

Follow the directions in steps 4 & 5 to add horizontal forces that are controlled by the left and right arrows. It's important that a blue arrow appear in the direction of the horizontal force when you're pushing the arrow key, which is the task of Step 5.

5. Add the trail to the object and the graph to the screen (Steps 7 & 8)

Just copy the code to the clipboard with the button and do a Control + V to paste it into the code

6. Consider doing one or both challenges

Talk to your teacher to see how many challenges you should try to do. They might want you to choose one of the two that are there.