| COMP 310 
		 Fall 2011
 | HW02:  Inheritance-based Ballworld | 
	
		|          | 
Assignment Instructions 
	The assignment is to create Ballworld implementation where the ball 
	implementations are sub-classes of an abstract ball.
	
	See the 
	
on-line demo of the inheritance-based Ballworld.   You are to replicate 
	all the functionality of the demo, except that you can make your own kind of 
	balls.
	
	
	
There is nothing sacred about the class names used 
	in this, or any assignments!   For instance, if you prefer to call 
	your "balls" something like "ASprite" 
	instead of the "ABall" mentioned below, 
	feel free to do so.   The only requirement is that you use names 
	that mean something in the context of your program.
	Step 0: Copy your HW01 code as per the instructions given in class to 
	create both a new HW02 project in Eclipse as well as a new HW02 folder in 
	SVN.    Ask for help if you're not sure what to do!
	Requirements:
	
		- Other than than the code for the individual concrete ball 
		subclasses, no code in the rest of the system can reference a ball 
		sub-class.
- Balls should bounce correctly off the sides of a panel on the main 
		frame, not the entire frame.   Balls should bounce from their edges, not 
		their middles or only one side.
- The application should be able to dynamically load any ball 
		sub-class, given its fully qualified name at run-time (i.e. typed into a 
		text field).
- The application should be able to clear out any balls that are 
		already on the screen.
- At least 3 different types of ball sub-classes must be implemented 
		which have distinct behaviors.  This can include changing colors, 
		curving around, changing radius, etc.  
Turn-in instructions:  
	
	
		- Be sure that your code is commiting to a separate HW02 folder in 
		SVN!    
- Add any instructions on how run your program in the comments of your 
		main controller file.
- Commit your code.
 
Recommended Methodology
A structured, planned approach to this assignment will 
save you a lot of time and head scratching.  It is key to understand what 
processes are happening where and how information flows from part of the system 
to the other, in particular, between the model and the view.
Break your work down into pieces where you fully 
understand each piece BEFORE coding anything!  Work on getting one small 
piece working at a time before moving to the next part.
Design --> Code --> Test --> Fix Design --> Fix Code --> 
Retest --> etc.
DO NOT ATTEMPT TO CODE EVERYTHING AT ONCE!
What Processes Take Place in the Model 
vs in the View?
	- While you are not required to implement a full-blown Model-View-Controller 
	for this assignment, it is recommended that you review the materials on the
	Model-View-Controller design pattern. 
	.    You may omit the controller and adapters for this 
	assignment, though it is recommended, if you have time, to create a MVC for 
	your system as we will require it in the next assignment anyway. 
- Your frame (GUI) is your view, so you need to create a class to 
	represent your model.
- The listeners connected to your GUI components should make calls 
	directly to the methods of classes in your model (or to the methods of the 
	adapters if you are implementing a MVC).  Remember that there should be no "business logic" in the 
view.
Building a Controller
	- The Controller is the class that has the 
	main() method.   
- The job of the main() method is to 
	instantiate the Controller object.
- The constructor of the controller will instantiate the model and the 
	view and start them once they are fully constructred.
Building a GUI
	- Make sure that you have a fully operational GUI before attaching it to 
	your model!  Otherwise, you won't know where your errors are. 
	
- "Fully operational" here means that
	
		- you have all the GUI components that the demo has 
- the two buttons are able to successfully call methods in your model
- you are able to send the text in the text field to the model when 
		the Make Ball button is clicked.
- The display canvas panel in the center of the screen is able to 
		paint a filled circle (ellipse) when it paints.  For now, just 
		write the code to paint the circle right in the
		paintComponent method.   In the end, 
		the actual circle-painting code will be moved to the balls themselves, 
		but test it here for now.
 
- Put the setVisible(true) statement in a 
	separate public void start() method so that 
	the GUI can be fully constructed without making it visible.  Once the 
	GUI is visible, events will start to be generated, beyond your control.
- The controller will call the start() 
	method when everything is ready.
The Variant and Invariant Aspects 
of a Ball
	- What are the fields of an  abstract Ball?
- What are the methods of an abstact Ball?
- What are the fields/methods of a particular concrete 
Ball?
- Design and implement your Ball architecture separately from the 
	rest of the system -- the balls have nothing to do with how the rest of the 
	system manages them.
- Use the Green UML plug-in for Eclipse to enable you to concentrate on 
	the design of the ball and not worry about the syntax details so much.
- Be sure that your abstract Ball class implements the 
	java.util.Observer interface so that the dispatcher, a
	java.util.Observable, can talk to them.
- It is recommended that you defer writing the painting and bouncing 
	aspects of the ball until a little later (see below).
 
 Understanding Painting and Animation
	- Study the Comp310 Resources site's 
	materials on painting and animation.
- At this stage, simply hard-code the instantiation of a specific ball.   
	Later, install the dynamic ball loading capability.
- Be sure you understand the difference between the sequences of processes 
of
	
		- Timer --> panel's repaint()  vs.
		 
- paintComponent(g) --> Ball's paint()
 
- Be sure you can trace the various paint-related calls 
to/from the view (from the model).
- The "call-back" lambda for painting the sprites is really just a 
	simplified adapter from a MVC pattern.   
- Notice how the supplied code for the call-back demostrates how to use an 
	anonymous inner class to instantiate a panel and override its
	paintComponent method in one fell swoop.
- The only way that the rest of the system ever communicates to a ball is 
	via the dispatcher -- this tells you what the call-back lambda must do.  
	
- Remember that all instances of balls must be loaded into the dispatcher 
	via its addObserver method before they can 
	be notified (their update method called) to 
	move and paint.
- Put the code to start the timer in a separate, 
	public void start() method of the model.    This way 
	the model can be fully constructed before it starts doing anything.  
- The controller will call the model's start() 
	method once everything is fully constructed.
 
Dynamic Ball Loading
	- Think about where the ball loading code should go.   Where do 
	you have sufficient information and access to the propoer objects to 
	accomplish the task?   Who'se bailiwick is it?
- Using the supplied dynamic class loader code (see below), the system 
	will be able to load the class specified by the fully-qualified name 
	specified in the text field of the GUI.   Therefore, where do you 
	get the input parameter value when calling the 
	loadBall method?
-  The supplied loadBall method 
	returns an instance of a ball, which must still be added to the dispatcher.
- The supplied code assumes that the constructor of a ball takes a 
	location, a velocity, a radius, a color and reference to the display canvas 
	panel (you can add this later, in the next section).
 
Bouncing Balls
	- To bounce a ball off the wall, you need to detect if the
	edge of the ball is beyond the 
	left, right, top and/or bottom of the display canvas panel.   
	(You will need to modify the constructor of the ball to take the display 
	canvas/panel.  The recommended type for this parameter is the most
	abstract entity that has a width and height, which is
	java.awt.Component.  You will need to 
	modify your call to add a new ball from the view to the model to pass this 
	parameter along with the classname.)  .
- If you know which wall the ball is bouncing off of, bouncing is really 
	just a matter of negating the value of the velocity in the direction 
	perpendicular to that wall.   That is, if you hit the left or 
	right wall, set the x-component of the velocity to the negative of the 
	x-component of the velocity.   Likewise, if you hit the top or 
	bottom wall, set the y-component of the velocity to the negative of itself.
- Because of the discrete nature of animations, a ball's position may be 
	such that it overlaps the wall or it may even be substantially beyond the 
	wall when the wall collision is detected.   In such, it is 
	necessary to adjust the position of the ball such that the ball is placed
	completely back inside the drawing canvas.  Here is a 
	relatively straighforward mathematical rubric to do this:
		- Given that it has been detected that a ball has collided with a 
		specific wall (left, right, top, and bottom) in a specific associated 
		direction (x or y), we assume that the ball has been travelling in a 
		straight line since the last timer tick.
- The position of the ball (perpendicular to the wall) where it 
		would just barely contact the wall, is the average of (i.e. halfway 
		between) the current perpendicular position and the position of where 
		the ball should be, had it actually bounced off the wall.  
		
- Make yourself a detailed drawing of the paths of bouncing balls to 
		convince yourself that the above relationship is true.  (Hint:  
		Draw actual and desired paths of the center of the ball, not 
		its edge.)
- The above mathematical relationship can be rearranged to solve for 
		the position of where the ball should be given the ball's current 
		position, its radius and the location of the wall (zero or panel 
		width/height).
 
Click for full size image

Provided Code
Don't kill yourself trying to re-invent what is given to 
you.  The following code snippets are provided to you:
	- 
	Dynamic 
	Class Loader  -- Given a fully-qualified class name (i.e. package 
	name dot class name) as a String, instantiates an instance of that class 
	given certain assumptions on the available constructor input parameters. 
	
- Basic Animation
		- Timer -- Controls when the system updates.
- Dispatcher - Holds references to all the balls in the 
	system and sends the "update" call out to all of them when requested.
- Call-back lambda -- Communicates to the model that a painting 
		process is underway.  (Depending on how your model and view connect 
		to each other, this process may be handled via a direct call to the 
		model or through an adapter rather than using a lambda, which is just a 
		single-method adapter.)
 
- Utility classes for making interesting balls.   Note that 
	these classes are in a separate package (util) because they have nothing to do with 
	Ballworld in particular.   In such, leave them in their separate 
	packages.    You should not need to modify these classes in 
	any way. :
		- util.zip  
		-- Zip file of the entire util package, 
		containing the 5 classes/interfaces below.
			- util.SineMaker -- creates sinusoidally 
		varying values.
- util.IRandomizer -- interface to for a 
		ball to use that needs something that supplies random values of various 
		sorts.
- util.Randomizer  -- an 
		implementation of IRandomizer 
- util.ILambda -- an interface used for 
		specifying lambdas (commands) of various sorts.
- util.NoOpLambda -- an
			ILambda that does nothing.   
		Useful for insuring well-defined behavior before a lambda is completely 
		specified. 
 
 
 How to turn a ball
To change the direction of a ball without changing its speed, you need to 
rotate the velocity vector.   This can be easily accomplished by a 
simple matrix multiplication, which when multiplied out, becomes:
Vx, new = Vx, old cos(θ) - Vy, old 
sin(θ) 
Vy, new = Vy, old cos(θ) + Vx, old 
sin(θ) 
where θ is the counter-clockwise angle of rotation
per timer tick.   That 
is, for a positive angle value above, the ball will turn to the left.    
Sine and cosine are static methods of the
Math class.  
Notes:
	- Math.sin() and
	Math.cos() both take the input angle in
	radians.   Math.PI is a 
	pre-determined value for π, useful for converting if you'd rather work in 
	degrees.  Use a small fraction of a radian 
	for your turning angle.   For instance, an angle of one quarter of 
	a radian will take about 13 ticks for the ball to go completely in a circle.  
- This is fundamentally a floating point calculation, but since your 
	velocity values are probably integers, you will want to do the entire 
	right-hand side of the calculation in double-precision floating point and 
	then use Math.round() followed by a cast to
	int to round the value to the nearest 
	integer.
- Be careful!   Make sure that your code replicates the 
	above mathematics EXACTLY.   Pay attention to even the smallest of 
	details above.    If your curving balls quickly spiral to a 
	stop, there's something wrong with your code!    
Other Tasks
	- 
	Add a button to clear the balls from the screen.   
	This is simply a matter of deleting all the observers from the dispatcher.   
	You'll need to add methods and method calls to route clear request from the 
	view to the model. 
- 
	Randomized starting positions, velocities, colors, 
	etc.   If this feature is desired, use the
	IRandomizer utility (with
	Randomizer implementation) to easily create 
	random Points, 
	ints, Colors, etc. 
 
Grading Criteria:
	- Replicating the behavior of the demo:
		- Overall look: panel with controls plus separate display area -- 5
		
- Ability to type in ball class name - 5
- Ability to create the ball of the desired type - 15
- Ability to clear the balls - 10
- Ability to have multiple balls of multiple types on screen 
		simultaneously - 15
- Correct bouncing behavior off edges of display area and edges of 
		balls. - 10
- At least 3 different types of balls being made - 15
- Discretionary points - 5
 
- No references to concrete ball subclasses in code -- 15
- Other programming style and operational issues/discretionary points -- 5
 
 
© 2011 by Stephen Wong and Scott Rixner