Informatik I -Schmiedecke

Lab X3: BallWorld

 

 


This time, you will actually be writing Java classes – using eclipse. BallWorld is all about interfaces and inheritance. You will be given interfaces to implement and interfaces describing objects that you can use. And you will save a lot of work by extending your own classes rather than re-writing the same parts again and again.

Objectives: Classes, objects, inheritance, interfaces, behavior.

Direct reference :Lectures 4-6,  Chapter 7, Chapter 8 , Chapter 9, Chapter 11


Introduction: The simulation environment Ballworld:

Try the  BallWorld demonstration: Download ballworld.jar  , import it into eclipse (as an external library) and start it- with BallworldGUI as main class. You will see a green "lawn" which serves as "playground" for your ball objects. Some ball classes are predefined, so you can instantiate a test ball: Select File>Load Ball and type ballworld.Shrinker. A new button appears at the bottom of the filed: pressing it results in instantiating the class Shrinker: You will see a "ball" that slowly shrinks and slides downward. Every time you press the button, another Shrinker object appears.

So what is your job: Invent and program new ball classes that can be launched like Shrinker and show some interesting behaviour.

We know you cannot program graphical user interfaces etc – so BallWorld will do all the displaying for you. You just provide Ball classes that obey the Ballworld rules:

·         They have to implement the interface Ball

·         They have to implement the interface Animate

So any class implementing these two interfaces is acceptable to be loaded into BallWorld.

Note: This time, the code of the given classes is much more complicated than with EtchASketch. But if you are curious, download the source code and read along. By the way, we are using a version that was revised and improved by one of your predecessors in this course, c.f. the copyright note at the bottom.

 

The Interface Ball

Every ball has to define a set of functions, given by the interface Ball, which are called by BallWorld to determine the position and the size of the ball – getX, getY, and getRadius. The prefix "get" suggests that these methods should read attribute values x, y, and radius – take that for an implementation hint. Much like in Etch-a-Sketch, these functions are not just called once, but periodically, so that you can even make you ball move – although the other interface will provide us with a better means for that.

The methods userClicked and userTyped are called when the user interacts with your ball through mouse and keyboard. Use these methods to change the ball's state on user interaction, so that getX, getY or getRadius yield modified values.

Finally, the method setWorld is called upon creation of a ball. It is used to pass environment information from BallWorld into the Ball object through the parameter world. The parameter is of the interface type World. A World object represents the "green lawn" – it knows its size and  has methods for adding, finding and removing balls. So, your ball should make sure it stores the World object, which is  passed to it as a parameter, for later use.

public interface Ball {   
  public double getX();   
  public double getY();   
  public double getRadius();   
  public void setWorld(World theWorld);   
  public void userClicked(double atX, double atY);   
  public void userTyped(char key);
}

The Interface World

Your ball is NOT to implement the World interface. You are given it so that you know what to do with the World object reference passed to you through the setWorld parameter. So, if you have an object of type World, you can use it to determine the size of the "lawn" (dynamically – the lawn allows resizing). If you have a Ball object and a World object, you can find the ball's nearest neighbour, and you can add balls to and remove balls from the lawn.

public interface World {   
  public double getMinX();   
  public double getMinY();   
  public double getMaxX();   
  public double getMaxY();   
  public Ball getClosestBall(Ball fromBall);   
  public void addBall(Ball aNewBall);   
  public void removeBall(Ball toBeRemoved);
}

The Interface Animate

There is a second interface to be implemented by Ball objects: Animate. Animate has just one method, act. This method will be called in an endless loop by BallWorld, so this is the best place to implement behaviour. E.g. if you implement act to increment the radius attribute like this
           
public void act() { raduius ++; },

your ball will continually grow bigger. So here is your second interface to be implemented by all Balls:

public interface Animate {   
  public void act();
}

Prep Questions:

1.    Write down the class header of your first Ball class called Prototype .

2.    Why is Prototype  not allowed to have an empty body?

3.    Try to draw the relationship between your Ball called Prototype , and the three interfaces provided.

 

Lab experiments

1.    Demo:
Try some more predefined Balls, such as Throbber, Faller, Exploder. Try also Fabian's Planet: If you select a planet and type a +, it will gain a new planetoid
J - and find out about some other keys he programmed for this class.

2.    Prototype:
Now add a new class Prototype to your project. Prototype Balls have a radius of 5 and sit in (20,20). –You know how to write a class in Eclipse, but this time let the class wizard deal with the two interfaces. Use the Add button and type the first letters of the interface name – then select it in the search window. Eclipse will prepare your class with all the methods you need to implement. So what needs to be done to implement Prototype ?
Recompile your project (if you have not chosen "build automatically"), start BallWorld and launch your new Ball Prototype  (if it is defined in a package p, you have to type p.Prototype ). Can you launch several Prototype  balls? What do you see?

3.    Kick:
Now define a Ball that moves across the lawn according to some (linear) rule, and is reflected like a billard ball by the edges of the lawn.
Don't copy code from Prototype, extend it!
 
Add some stochastics:
Math.random()yields random values between 0 and 1. Initialize the x, y, and radius attributes with random values (in the constructor). Now all Bounce objects will behave differently.
Hint: using  Math.random
()-0.5 you get positive and negative values – use that for initial movement in different directions.

4.    Bubble:
Create an exploding ball type: Bubble is an extension of Kick, but grows continually, starting with a radius of 2. When it reaches 10, it "explodes". I.e. it is removed from the lawn.

5.    Balloon:
Now extend Kick, so that you can play with it:  Balloon reacts to mouse and keyboard. When a user clicks the ball, the distance of the click from the center of the ball is tripled (or multiplied by a random value to simulate impulses of different strength) and the ball is moved there. So Balloons will make little leaps when clicked. Balloons can be inflated and deflated: When the user types +, the size of the currently selected ball is increased by 2, with – it is decreased by 2.  When the user types an <, that's a needle point: The currently selected Balloon bursts and disappears from the lawn.

 
From here follows voluntary work – for quickies, freaks and new fans.....

6.    Pool:
Extend Kick at let the balls bounce not only from the walls, but also from each other. Add Prototype  stationary balls as Holes: On collision with a Hole, the colliding ball disappears. Use instanceOf to find out whether the ball you hit is a Hole.

7.    ChainReaction:
Now change Bubble to start a chain reaction when it explodes: Let it create an launch 2 new balls with similar behaviour.
This is a little new: you actually create Ball objects yourself and add them to the lawn using the World method
addBall(). Also, you want to start your new Balls at the old Balls position. That requires a second constructor which accepts coordinates as parameters: public ChainReaction(double startX, double startY).

8.    Further experiments:
Start being creative yourself! Here are some suggestions:
- Let ChainReaction explosions stop after launching 50 new balls. From then on, all balls shrink till they finally disappear.
- Make your ball move along a ballistic curve – starting in one direction and then accelerating downward and slowly decelerating vertically.
- Create hunting Balls: let your ball shoot (remove) any ball that comes too close to it. (of course it is pure chance, which one shoots faster).
- and so on….
-


Copyright note

The idea and original software for this lab is taken from Prof. Lynn Andrea Stein's "IPIJ - Interactive Programming in Java". The software was corrected and improved by Fabian Quosdorf in 2005.

Lab instructions by  Ilse Schmiedecke 2004/2005 –for  questions and comments: schmiedecke@tfh-berlin.de