The BallInheritance
activity explores inheritance, superclasses, and subclasses in the context of a Ball
class that will be used to model the motion of a graphical ball on the screen.
The completed activity should be compressed as BallInheritance.zip
and uploaded to the server.
A Ball
class describes a model of a 2-dimensional ball, with a radius
, x
position, y
position, and velocities vX
and vY
in the x- and y-directions.
Write the Ball
class, with a constructor that takes those five values as parameters, along with getters and setters for those instance variables.
The move
method for the Ball
class takes a float parameter t
that represents a period of time that passes, and calculates the ball's new position based on physics formulae. Include this method in your class.
/**
* The move method calculates new x- and y-positions based
* on the current positions, the velocity in each direction,
* and an amount of time t that has passed (standard physics
* calculations).
* @param t a float that indicates an amount of time
*/
public void move(float t)
{
x = x + vX * t;
y = y + vY * t;
}
Additionally, write a toString
method that identifies the state of the ball in the format
Ball[r=30.0,x=455.2798,y=386.9585,vX=0.1,vY=0.7]
We'd like to actually be able to see the ball moving on a screen. Although Java has its own graphics libraries, we're going to use the Processing environment to:
setup
and draw
methods.The main project file is given here. Put this into the first tab of a new Processing project called BallInheritance
.
/**
* The Ball Inheritance project demonstrates object-oriented
* programming and inheritance in the context of balls moving
* around on a Processing graphical window.
*/
///////////////////////////////////////////////////////////
// Global variables for the main program declared here
///////////////////////////////////////////////////////////
BouncingBall b; // A single instance of the Ball class
float deltaT; // a time-interval for moving the ball
boolean launched; // true if the ball has been launched
PVector p0, p1; // Two PVector points, used just at
// beginning to identify direction. Each
// point has instance variables x,y
///////////////////////////////////////////////////////////
// Global variables and the Processing window initialized
///////////////////////////////////////////////////////////
void setup()
{
size(900, 700); // the size of the graphical window
background(255); // background color is white
b = new BouncingBall(30, width/2, height/2, 0, 0);
deltaT = 0.3; // An arbitrary time period
launched = false; // flag turns true when ball is launched
}
///////////////////////////////////////////////////////////
// Additional functions to handle interactions with mouse
// (used for launching the ball)
///////////////////////////////////////////////////////////
/**
* Processing function to identify when mouse is pressed.
* Here, first click is captured for "drawing back the bowstring"
*/
void mousePressed()
{
p0 = new PVector(mouseX, mouseY);
}
/**
* Processing function to identify when "bowstring is released,"
* launching the ball.
*/
void mouseReleased()
{
p1 = new PVector(mouseX, mouseY);
}
////////////////////////////////////////////////////////////////////////
//////////////////////// Main draw() loop ////////////////////////////
////////////////////////////////////////////////////////////////////////
void draw()
{
background(255); // Clear the screen each time
if (launched)
{
b.display();
println(b); // displays ball state in console
b.move(deltaT); // changes ball state
}
else // ball hasn't been launched yet
{
// We'll click-drag a line, where the direction of the line
// indicates the direction of the launch, and the magnitude
// represents the intial velocity of the launch
if (p0 != null) // If we've clicked to start bowstring pull
{
if (p1 == null) // If we haven't released the mouse...
{
line(p0.x, p0.y, mouseX, mouseY); // draw to the mouse location
// (so we can aim)
}
else // We've released the mouse!
{
b.setVx( (p0.x - p1.x)/10 ); // Set the ball's initial velocity
b.setVy( (p0.y - p1.y)/10 ); // in x and y directions as a function
launched = true; // of how far the bowstring was pulled
// back.
}
}
}
}
In the Processing project, open up a new tab where we can put in our Ball
class.
You may have noticed that the draw
loop calls a display()
method for the ball object, and we haven't written that method yet.
Modify the Ball
class to include a display
method that calls Processing's ellipse()
function to draw the ball at its current position in the graphical window. Note that the ellipse takes x- and y-diameters as parameters, so doubling the radius is required to draw the ball the correct size.
Run and debug your project.
Ball
Having the ball disappear off the screen is not very interesting. If you look at the Processing console, you can see that the ball is still moving through space. It's just that we can't see it in the window we're looking at.
WrapperBall
Write a WrapperBall
class that inherits from Ball
. A WrapperBall
object is a type of ball, but it wraps around the screen: if it moves off the bottom of the screen it reappears at the top, or if it moves off the right side of the screen it reappears on the left, etc.
Which methods from the superclass Ball
can we use unmodified? Which methods from the superclass will we need to override for this class? Do we need to write any additional methods that will only be used by WrapperBall
?
Modify your BallInheritance
main program to test this new type of ball.
BouncingBall
Write a BouncingBall
class that inherits from Ball
. This class bounces off the edges of the screen.
MultiBall
ProjectUsing any of the classes that you've created, create a new project called MultiBall
in which the runner creates an Array or ArrayList of WrapperBall
or BouncingBall
objects and displays them all on the screen.
BouncingBall
Modify your BouncingBall
class so that the balls in the project are subject to the force of gravity. Do you need to modify the Ball
class to do this? (You shouldn't!) Do you need to modify the BouncingBall
class to do this? (Possibly?) Or maybe you can write a GravityBall
class that inherits from BouncingBall
? This may or may not be possible, depending on how you've written the original BouncingBall
.