Last modified: January 24, 2023
In this lab, you will create a simple ball bounce simulation using Greenfoot.
You can download a demo of this lab here.
If you are on a Mac, the zip file will be extracted when you double click it, but for windows, you will need to extract all (available in the right click menu or the file explorer top bar)
You will notice the project only contains .class files, a project.greenfoot file and an images folder containing the images for the project. The .class files contain the compiled bytecode for the classes, which is all that is needed to run the program, but is not human readable.
Once you downloaded the demo and extracted/decompressed it, open the BallBounceSolution folder and double click on project.greenfoot to open it in greenfoot.
By the end of this lab, you should have created a Greenfoot scenario that:
The Greenfoot system is build on a simple process for every greenfoot application:
Here is a mockup of what that might look like (Note: this is not the actual code, but just shows the logic):
// First create an instance of your subclass of World (let’s assume the class is named MyWorld):
World w = new MyWorld();
// let’s assume there is a timer method that gets called every frame like in codeHS. That would look something like this:
public void onTick() {
w.act(); // call act() on the world
List<Actor> actors = w.getObjects(Actor.class); // get a list of all the Actor objects in the world
for (int i = 0; i < actors.size(); i++) { // for each index i in the list
Actor a = actors.get(i); // get the Actor at index i
a.act(); // call act() on the Actor
}
}
To create the ball actor, right-click on the "Actor" yellow box on the right panel, click "create subclass", name it Ball, and give it a ball image of your choice.
To add your ball to the world, open the "MyWorld" class's constructor, after super(600, 400, 1)
, insert the following code:
Ball ball = new Ball();
addObject(ball, getWidth()/2, getHeight()/2);
The above code snippet creates an instance of the Ball class you just defined and add it to the center of the World.
Compile your code. If everything runs successfully, you should see a ball in the center of the world.
As mentioned in the "Understand Greenfoot Conceptual" section above, every actor in Greenfoot is animated by calling its act()
method every few milliseconds.
So, to make the ball move and bounce accordingly, you will write the code that moves the ball in the Ball class's act()
method.
In JavaScript, you moved an object on canvas using something like setPosition(getX() + dx, getY() + dy)
In Greenfoot, you can move an actor on the World using this syntax: setLocation(getX() + dx, getY() + dy)
To animate a ball, first give the Ball class two instance variables to keep track of its dx and dy:
int dx = 3;
int dy = 3;
Then the act()
method of the Ball class, make it move dx dy using setLocation.
To make it bounce when hit the edge of the World, you can use the getX() and getY() methods to determine the ball's current location then compare it to the width and height of the world.
To get the world's width and height inside the Ball class, use the getWorld()
method to first get the world the ball is currently in, and call the getWidth()
and getHeight()
on the world obtained like this:
World w = getWorld();
int height = w.getHeight();
int width = w.getWidth();
You can condense the above code into something like this:
int height = getWorld().getHeight();
int width = getWorld().getWidth();
Then you can determine whether the ball is on the edge of the world using the technique you used in CodeHS ball bounce and actually make the ball bounce by adjusting the dx and dy.
According to Greenfoot's Actor API Documentation, any Actor can determine if it is colliding with another actor via the getOneIntersectingObject method:
protected Actor getOneIntersectingObject(java.lang.Class<?> cls)
In the Ball Bounce lab, you can use the following template inside the Brick's act method to determine if it has just been hit by a ball:
Actor possibleBall = getOneIntersectingObject(Ball.class);
if (possibleBall != null) {
// this means the brick has been hit by a ball because that ball is intersecting with the brick
} else {
// there is no ball around
}
It is very important to verify that possibleBall != null, otherwise it will create a Java error called
NullPointerException
In the event that a brick has been hit by the ball, you should remove the brick and bounce the ball.
We already covered how to bounce the ball earlier in this lab. And to remove the brick, get the world first, then use the removeObject(Actor object)
like this inside the brick class's act method (after it has verified that it has been hit by a ball):
World world = getWorld();
world.removeObject(this); // removes the ball itself from the world
Shorter version:
getWorld().removeObject(this);
Now, you should have a world, ball, and brick class ready to be put together.
Click the run button on Greenfoot to run. Congratulations on completing your Ball Bounce lab!
Zip your entire project folder and submit it below.
PX_LastName_FirstName_BallBounce
.PX_LastName_FirstName_BallBounce.zip
. For example if you were in 3rd period and named Michael Wang, then you would name the file P3_Wang_Michael_BallBounce.zip
You must Sign In to submit to this assignment