BallWorlds
Feel free to ask questions of your instructor, student assistants and classmates as desired.
Note on Details: We used to have much more detailed descriptions of
parts this project for CSSE 120. We believe that they were too wordy for
most students. But I will include links to them in case you want to
see more. Those detailed documents ask lots of questions and suggest some
activities. You may want to mentally ask the questions and to do the
activities, but none of these are required in 220
Overview details
Goals
The goals of this exercise are to:
- Learn about informal use of UML to communicate and brainstorm.
- Learn about inheritance and its benefits.
- Gain more practice implementing interfaces.
- Learn about visibility modifiers
The Exercise:
Instructions Part 1 - Demo and Basic Specification
Your instructor will demo BallWorlds and discuss the basic spec with you.
Instructions Part 2 - Design
UML (Unified Modeling Language) diagrams are used primarily for two purposes.
First, project designers use them during the design phase of larger projects
to brainstorm relationships between classes. Second, they can then be used for
communication: to convey the design to the implementors of the project.
We are using UML for the second purpose here.
The whole diagram is interesting in its own right, and we encourage you to take time
at some point to explore it and the related code. However, we will now focus on the parts
directly related to the implementation we will do.
Hints:
- The six classes for types of balls are the classes that you will eventually implement.
- These six ball classes extend the abstract Ball class, which in turn implements three interfaces.
Thus, your classes must implement those three interfaces.
- The Ball class, and hence each of your classes which extends Ball,
has the BallEnvironment object.
- Some of your Ball classes may want to refer to instances of the classes to which they point
(e.g., Color).
Instructions Part 3 - Get the starting code
You should connect to your personal repository to get the starting BallWorlds code.
Refer back to earlier projects if you need a reminder how to connect.
Instructions Part 4 - Write the code and execute the project
You will write this project in stages. We highly recommend getting one ball to work at a
time in the order in which they are presented here. You don't need to answer the
questions for each one in writing, but answering them will help you think about
how to code it.
Note: You must take full advantage of inheritance in this project to get full credit!
1. Dud
Dud details (only if you want to read a
very wordy description)
A Dud is a ball that merely appears on the screen.
It should appear in a random location (otherwise, they will all appear on top of
each other), with any reasonable size and color.
- According to your UML diagram, how many methods must any Ball (including a Dud) have?
- A note in BallWorld's UML class diagram indicates that every Ball must have a constructor that:
takes a BallEnvironment object, which adds the Ball to its World.
Looking at the UML class diagram, what is the only object that a Ball has?
What method does that object have that will be helpful to a Ball?
- Given that a Dud basically does nothing, what method(s) must it actually implement?
- What fields should a Dud have?
Commit your work to the repository now!
2. DudThatMoves
DudThatMoves details (only if you want to
read a very wordy description)
A DudThatMoves should behave exactly like a Dud (including
random location), except that it moves, on its own,
in a straight line (i.e., a constant velocity). It can move at any reasonable speed you choose --
try numbers like 0.1 for starters.
Each new ball type's color should be different from colors of the Ball
types that you already implemented.
- You need to use inheritance here. A DudThatMoves is very similar to the Dud, and you should exploit
that similarity by inheriting functionality from the Dud.
- The framework calls act() on each Ball every 20th of a second or so.
So, a DudThatMove's act() method is the place to change the DudThatMove's position.
Commit your work to the repos (last reminder, after this, you are on your
own).
3. Mover
Mover details and hints (only if you
want to read a very wordy description)
A Mover should start in the exact middle of its world (even if its world is resized).
Each Mover should have its own fixed velocity that is set at random when the Mover is constructed.
The random velocity should be in any reasonable range that includes all directions (not just the "positive" direction).
Additionally, it should be "selectable", "draggable", and "killable" by the mouse. Remember, each new ball type needs to be a different new color.
For each of these specs, you should use the UML diagram to determine which method is involved and how:
- What class implements both MouseListener and MouseMotionListener
(and hence responds to mouse events)?
- The World responds to a mouse-press by selecting the Ball nearest the mouse
(and showing this by turning that Ball red while the mouse is pressed).
- The World responds to a mouse-drag by (repeatedly, throughout the drag)
telling the selected Ball to move to the current mouse-point.
Which Ball method must be implemented in order for this Ball-dragging to work correctly?
- The World responds to a mouse-left-click (i.e. press and release)
by telling the selected Ball to toggle between the paused and not-paused state.
(So, if the Ball is acting, it should stop acting; while if it is not acting,
it should resume acting.) Which Ball method must be implemented in order
for this Ball-pause-resume to work correctly?
- The World responds to a mouse-right-press by telling the selected Ball to kill itself,
that is, to have itself removed from its World. Which method must be implemented in order
for this Ball-suicide to work correctly?
- In summary, you don't need to deal with the mouse directly. The starting
code does that for you. For example, pauseAndResume() is called
on the nearest ball whenever the user clicks the mouse. By implementing
pauseOrResume(), you are saying what should change when a ball is paused.
A Bouncer should behave just like a Mover, except that it bounces off the edges of its World.
A Shrinker should behave just like a Bouncer, except that as it moves/bounces,
it also shrinks and expands, as follows:
- Stage 1: It picks a random size between 0 and its initial size,
and shrinks to that in small increments (through the act method).
- Stage 2: After it reaches that random size, it picks a random size between its initial size
and 4 times its initial size, and grows to that in small increments (through the act method).
- Stage 3: The process then repeats, picking a new random number for the size to shrink/grow to,
at each iteration of shrinking/growth.
It should neither move nor shrink/grow when in the paused state.
An Exploder should behave just like a Bouncer, except that as it moves/bounces,
it also:
- Stage 1: It picks a random size between 1 and 10 times its initial size,
and grows to that in small increments (through the act method).
- Stage 2: When it reaches that random size, it dies
(and hence is no longer in the World, hence is no longer drawn, etc).
- Stage 3: When it reaches that random size, it constructs two new Exploders,
each starting where the original Exploder died.
It shouldn't grow or explode when in the paused state.According to the UML, Exploder should extend Bouncer. Why is that preferable to extending Shrinker?
BONUS "Implementer's Choice"
You should design a Ball with its own special properties,
extending the appropriate existing Ball class.
Bonus points will vary from just a couple points for something that basically just copies something else that a ball can do
(like just using random colors), for up to 20 for something really original, cool-looking, and non-trivial!
Alternative: it would be really cool to implement bumpers, as shown in the UML diagram.
It seems like a real challenge! Hint: you'll need to add a new BallButton
somewhere -- look at the UML diagram to figure out which class contains
BallButtons.
Don't forget to commit your final project!