On this page:
2.1 Have a Ball
8.5

Lab 2: Simple Data Definitions and Methods

Goals: The goals of this lab are to design some simple data definitions, examples and methods in Java.

Related files:
  tester.jar     javalib.jar  

2.1 Have a Ball

In BSL if you wanted to define a Ball, it might look something like this:

;; A Ball is a (make-ball Posn Number Color)
(define-struct ball (center radius color))
 
(define b (make-ball (make-posn 0 0) 5 "blue"))

In Java, that same definition looks like this:

import java.awt.Color;
 
//represents a ball that can be drawn onto a scene class Ball {
CartPt center;
int radius;
Color color;
 
Ball(CartPt center, int radius, Color color) {
this.center = center;
this.radius = radius;
this.color = color;
}
}
 
//represents a point on the Cartesian plane class CartPt {
int x;
int y;
 
CartPt(int x, int y) {
this.x = x;
this.y = y;
}
}
 
class ExamplesBall {
Ball b = new Ball(new CartPt(0, 0), 5, Color.BLUE);
}

In Java, center, radius, and color are all called fields. They are attributes of a ball.

Problem 1 Add templates to the Ball and CartPt classes.

Now, in BSL, if we wanted the area of a ball, we would have a function that looked like this:

;; Ball -> Number
;; Returns the area of a ball
(define (area b)
  (* pi (sqr (ball-radius b))))

Wouldn’t it make more sense for the ball to know how to compute its own area? That’s where methods come in. In Java, functions that live inside objects are called methods. These methods can use the data that’s inside the objects, as in the below example.

import tester.Tester;
import java.awt.Color;
 
//represents a ball that can be drawn onto a scene class Ball {
CartPt center;
int radius;
Color color;
 
Ball(CartPt center, int radius, Color color) {
this.center = center;
this.radius = radius;
this.color = color;
}
 
// computes the area of this ball double area() {
return Math.PI * Math.pow(this.radius, 2);
}
}
 
//represents a point on the Cartesian plane class CartPt {
int x;
int y;
 
CartPt(int x, int y) {
this.x = x;
this.y = y;
}
}
 
class ExamplesBall {
Ball b = new Ball(new CartPt(0, 0), 5, Color.BLUE);
 
boolean testBall(Tester t) {
return t.checkInexact(b.area(), 78.5, 0.001);
}
}

Note the use of this.radius. What this is doing is referencing the number we gave the ball when we created it. In this example, ball b has a radius of 5, so the area of b should be somewhere around 78.5. If you need the radius of another ball, you can access it with otherBall.radius. This works for the other fields as well.

Also note the use of checkInexact. The area of the given ball is roughly 78.5, but not exactly. In fact, all comparisons with floating-point numbers cannot be done completely precisely, so whenever we need to test such values, we must use checkInexact instead of the more familiar checkExpect. The last parameter, 0.001 specifies the tolerance we’re willing to accept: here, we’re saying the two values must be equal to within 0.1% (or a factor of 0.001).

Problem 2

Design a circumference method for Ball.

Problem 3

Design a distanceTo method in the Ball class. The method should take in a Ball and calculate the distance between the center of this Ball and the given one’s. Remember to delegate to the CartPt class!

Problem 4

Related files:
  bouncing.jar  

For this problem, you will need the bouncing.jar file above. Add it to your project the same way you added the other jar files. This contains some basic BigBang code specific to Bouncing Balls. For now, you don’t have to learn how BigBang works with Java. That will come a little later in the course.

Create a new project BouncingBalls. Then, create a file called Ball.java. Copy the code below, fill in the constructor and add a template for the BouncingBall class. Start designing the methods. Don’t forget to test them!

import tester.Tester;
import java.awt.Color;
import javalib.worldimages.*;
 
class BouncingBall {
Posn pos;
Color color;
int size;
int dx; // how fast is the ball moving to the right? int dy; // how fast is the ball moving downward?  
BouncingBall(Posn pos, Color color, int size, int dx, int dy) {
// TODO: FILL IN YOUR CODE HERE }
 
// Returns a new BouncingBall that's just like this BouncingBall, but moved // by this BouncingBall's dx and dy BouncingBall move() {
// TODO: FILL IN YOUR CODE HERE }
 
// Returns a new BouncingBall that represents this BouncingBall just after // it has bounced off a side wall. Does not actually move the ball. // This method will be called automatically when `collidesX` returns true BouncingBall bounceX() {
// TODO: FILL IN YOUR CODE HERE }
 
// Like bounceX, except for using the top or bottom walls BouncingBall bounceY() {
// TODO: FILL IN YOUR CODE HERE }
 
// Detects whether the ball is colliding with a side wall. boolean collidesX(Posn topLeft, Posn botRight) {
// TODO: FILL IN YOUR CODE HERE }
 
// Detects whether the ball is colliding with a top or bottom wall. boolean collidesY(Posn topLeft, Posn botRight) {
// TODO: FILL IN YOUR CODE HERE }
}
 
class ExamplesBouncingBalls {
int WIDTH = 300;
int HEIGHT = 300;
 
//ADD YOUR EXAMPLES AND TESTS HERE  
// NOTE: We have provided BouncingWorld for you, in the starter code. // We'll see how it works in a few lectures boolean testBigBang(Tester t) {
BouncingWorld w = new BouncingWorld(WIDTH, HEIGHT);
return w.bigBang(WIDTH, HEIGHT, 0.1);
}
}

Try running it and interacting with it and see what happens. Given what you know of "big-bang", does pressing a key seem to do anything? Does clicking the mouse?