Anda di halaman 1dari 40

Animation Land!!

!
Mr. Fahrenbacher
AP Computer Science A

Name: _________________________________

Welcome to Animation Land! This project will introduce you to the concepts of Class design. Please create a New Java
project in Eclipse named Animation Land. Then put the project files in your src folder. If you set up Eclipse correctly,
your project should look like this.

Part One: Creating Objects


In Animation Land, you will be able to create Performer objects. Each Performer will "perform" animations based on
commands you send to them (instance methods) and properties that represent their current state (instance variables or
fields). But before we can tell our Performers to do anything, we must first design a class that can represent any
Performer. Look at the Performer class to see what we have so far:

!
Doesn't look like much right now. The two import statements at the top indicate Java libraries that our Performer will
need later. You can ignore the @SupressWarnings() command and the extends command (although we will talk about
extends later in the course).
We would like to make multiple instances of the Performer class - different Performers may be at different positions in the
screen, they may say different things, and they might be drawn differently. To enable the creation of an instance of a
class, you need to write a constructor. Please add the code below to your Performer class:

Constructor
!

1/40

That block of code you just added is called a constructor. It looks kind of like a method (it ends with parentheses, has
curly braces, has public, etc), but there are three major differences:
!

1) The name of the constructor must ALWAYS match the name of the class
2) A constructor never has a return type
3) You will not be using the return keyword in the constructor

Now go to the AnimationLoader class and find the loadAnimations() method.

Method
!
AnimationLoader is called the Client. It will create the instances of the Performer class and tell them to do different
animations. In the loadAnimations() method, please add the code below:

Creates a Performer instance


!
This statement has 5 parts.
1) The left side is declaring a variable of type Performer (similar to how we declared variables of type int, boolean,
or String).
2) The name of our variable is steve. steve will represent an instance of the Performer class.
3) We are assigning this variable the data created on the right side of the equals
4) The new keyword means we are creating an Object (specifically, a Performer object)
5) and Performer() means we are calling the constructor of the Performer class.
Now if you run your project, you will see a very short-lived performance:

!
To quit your presentation, simply hit the escape key.

2/40

The problem is that our Performer has no attributes. Go to the Performer class and add a Color attribute (instance
variable) like below:

Instance variable

!
Now our Performer objects will have a color. But what color? It's good practice to assign instance variables in the
constructor, like below:

Assigning the instance variable

!
Now our Performer will show up!

3/40

Now for our Performer's first trick - having it switch colors in an animated manner. Go back to the AnimationLoader. Add
the line of code below:

Assigning steve's instance variable


!
The new line tells the Performer named steve to change its color property to red. The dot (period) operator is a way of
communicating with the Performer object. To see our animation (changing from red to blue), you will need to add the
following new command twice:

Show steve for 1 second

Show steve changing from blue to red


over 1 second.

The animate command tells our window to perform the changes (showing blue, then shifting to red) over 30 increments
(about 1 second). The larger the number, the longer the animation will take (60 is roughly 2 seconds, for example).
The code between AnimationFrame.animate(n) is what constitutes an animation. Below, there would be two animations.
!

Create steve
Animate changing color to red
Animate changing color to
magenta

But the two examples below would only represent one animation (you will never see steve change to the magenta color in
the first example).

4/40

Next, let's make our Performer have an x-coordinate. Add an xCenter instance variable of type double to the Performer
class, and initialize the xCenter to 200.0 in the constructor.

Instance variable

Assigning the instance variable


!

Now when you run your program, you should see that steve has moved 200 pixels to the right.
In AnimationLoader, change steve's centerX to 300.0. Run the program and enjoy the animation!
!

changing steve's instance variable

5/40

The real power in Classes is that it will allow us to make multiple instances of the same class. In Animation Land, that
means we can make many Performer objects. Go ahead and add another Performer object named bill to the
AnimationLoader, but with a different animation. In my example below, bill will move its x-center to 100, and change it's
color to green.

Second Performer instance

!
Here's why this is soooo cool: Both steve and bill have their own color and centerX variables! Each time you create a
new Performer(), java makes an object that has all of the properties (instance variables) declared in the Performer class.
Then, changing one Performer object does not effect the other Performer.

Before animation
steve

After animation
bill

steve

bill

color

blue

blue

color

red

green

centerX

200.0

200.0

centerX

300.0

100.0

You can also have one Performer act while the other Performer watches.

6/40

Vocabulary: Define the following terms in your own words and explain their purpose
Constructor

Instance

Instance Variable

new

Dot operator

Client (code)

Exercises:
1) Y? Because I asked.
(a) Add a centerY property to your Performer class - its type should be double.
(b) In the Performer class' constructor, initialize the centerY property to 200.0
(c) In the AnimationLoader class, have steve and bill change their centerY properties to be 300.0 and
400.0, respectively.
2) The long and the short of the matter.
(a) Make your Performers support width and height instance variables (they should both be ints)
(b) In the Performer class' constructor, initialize the width and height properties to be 100 and 100.
(c) In the AnimationLoader class, have steve's width increase by 50 and bill's height decrease by 50.
3) Can I Have This Dance?
Make steve and bill perform a dance of some kind. They may either move together or separately.

7/40

Questions:
1) Below is a class that represents a PiggyBank and another class, Driver, that represents client code.
public class PiggyBank {
int pennies;
int nickels;
int dimes;
int quarters;
public PiggyBank() {
pennies = 0;
nickels = 0;
dimes = 0;
quarters = 0;
}
}
public class Driver {
public static void main(String[] args) {
PiggyBank hamm = new PiggyBank();
hamm.pennies += 5;
hamm.quarters += 10;
hamm.dimes += 4;
hamm.nickels += 2;
}
}
(a) Identify all the PiggyBank instance variables and their types.

(b) When hamm the PiggyBank is first made, how many pennies nickels, dimes, and quarters does he
have? How many will he have at the end of the main method?

(c) Write segment(s) of code that will determine how much money in dollars that hamm contains at the
end of the main method.

8/40

2) Below is a class that is supposed to represent a Square.


public class Square {

}
(a) In which box would you declare the instance variable(s)? In which box would you declare the
constructor?
(b) A square can be represented by a side length property. Fill in the box above so it has an instance
variable that describes the length of the Square
(c) When creating a Square, you need to be able to specify the length of the side. Fill in the other box
above so it has a constructor that initializes the side length to be 5.
(d) In the method below, create a Square object named spongeBob. Then change spongeBob's side
length to be 20.
public static void main(String[] args) {

9/40

Part Two: Different construction techniques


Let's say we want steve and bill to start in different spots than our constructor is currently setting. We could write code
like the following in the AnimationLoader:

!
There's got to be a better way! Here is what we'd like to be able to do:

But we can't (as you can see by the red squiggle)... unless we add another constructor to the Performer class!

10/40

Adding this new constructor should remove the red squiggle error messages and allow your program to run correctly.
This second constructor takes 5 parameters (input variables)- one to specify the color, two to specify the center, and two
to specify the dimensions. The goal of all constructors is to assign the instance variables, usually with values taken from
the parameters. When you create steve in this way:

the yellow color is put into the c parameter and then put into the color instance variable. Then the number 200.0 is copied
into the cx parameter and then copied into the centerX instance variable. You can have as many constructors as you like!
Below is a digram of how data flows from client code to the class' constructor.

In AnimationLoader:

In Performer:

In the above code, the value Color.YELLOW is called the actual parameter, while the variable Color c is called the
formal parameter. Each of the actual parameters is being mapped to the corresponding formal parameter in the
constructor. Another word for parameter you will see sometimes is argument. For example, 75 is the 5th argument that
is being passed into the above constructor.
A common constructor error is called assignment dyslexia. This occurs when a coder assigns the parameters to hold
the instance variable values instead of the other way:

Assignment Dyslexia

In this situation, a Performer object will have none of its instance variables assigned a value. Make sure to always put the
parameters on the right and the instance variables on the left!
Now our Performer object can be created with two different constructors - each has the same name, but different
parameter lists. When you have two constructors with the same name but different parameter lists, we say that we have
overloaded the constructor (the same applies for methods too). Java picks the construction to use when creating your
object based on the parameters you pass in.

11/40

Vocabulary: Define the following terms in your own words and explain their purpose
Overloaded

Assignment Dyslexia

Parameter / Argument

Formal parameter

Actual parameter

12/40

Exercises:
1) Color Me:
a) Add another constructor to the Performer class. It should have one Color parameter - the color of the
Performer. Initialize the color instance variable to hold the value in the color parameter. Assign the other
instance variables to numbers of your choosing
b) In the AnimationLoader, create a new Performer named grace. Create grace using your one argument
constructor. Run your program to make sure grace is appearing correctly.
2) The Long and Short of the Matter:
a) Add another constructor to the Performer class. It should have two integers parameters - the width and
height of the Performer. Initialize the width and height instance variables to hold the values in the
parameters. Assign the other instance variables to values of your choosing.
b) In the AnimationLoader, create a new Performer named ada. Create ada using your two argument
constructor. Run your program to make sure ada is appearing correctly.
3) Sharper Image:
a) Add another instance variable to your Performer class. It's type should be BufferedImage, and its
name should be image.

!
b) Add another constructor to the Performer class. It should have one String parameter - the name of an
image. Your field and constructor should look like this:

!
c) To initialize the image instance variable, you will use the ImageLoader class' loadCompatibleImage
method like so:

!
d) Initialize the other instance variables in this constructor to appropriate values.
e) In the AnimationLoader, create a new Performer named knuth. Create knuth using your one argument
constructor - specify that the image name is "face.png" (or "frown.png"). Run your program to make sure
knuth is appearing correctly.

13/40

Questions:
1) Below is a modified version of our previous PiggyBank class and Driver.
public class PiggyBank {
int pennies;
int nickels;
int dimes;
int quarters;
public PiggyBank() {
pennies = 0;
nickels = 0;
dimes = 0;
quarters = 0;
}
public PiggyBank(int p) {
pennies = p;
nickels = 0;
dimes = 0;
quarters = 0;
}
public PiggyBank(int p, int n, int d, int q) {
pennies = p;
nickels = n;
dimes = d;
quarters = q;
}
}
public class Driver {
public static void main(String[] args) {
PiggyBank hamm = new PiggyBank();
PiggyBank mint = new PiggyBank(40);
PiggBank money = new PiggyBank(1, 2, 3, 4);
}
}
(a) How many constructors does the PiggyBank class have?

(b) How many of each type of coin will the different PiggyBanks have?

pennies

nickels

dimes

quarters

hamm
mint
money
14/40

2) Below is a class that is supposed to represent a Rectangle.


public class Rectangle {

}
(a) In which box would you declare the instance variable(s)? In which box would you declare the
constructor(s)?
(b) A rectangle can be represented by a width and a height. Fill in the box above so it has two instance
variables that describes these twos length of the Rectangle
(c) There are three ways you can create a Rectangle. First, you'd like to be able to create a Rectangle
where the width and height default to 1 always. Second, you'd like to be able to create a Rectangle
where the width and height are each assigned by one given parameter. Third, you'd like to be able to
create a Rectangle where the width and height are each assigned by two given parameters. Write these
three constructors in the appropriate box above. Below is client code using the three constructors you
are to make.
public static void main(String[] args) {
Rectangle a = new Rectangle(); //width and height are both 1
Rectangle b = new Rectangle(5); //width and height are both 5
Rectangle c = new Rectangle(3, 4); //width is 3, height is 4
}

15/40

3) Below is a class that represents a WaterBucket.


public class WaterBucket {
int amountOfWater;
int capacity;
public WaterBucket() {
amountOfWater = 0;
capacity = 10;
}
public WaterBucket(int cap) {
amountOfWater = 0;
capacity = cap;
}
public WaterBucket(int amount, int cap) {
amountOfWater = amount;
capacity = cap;
}
}

Finish the main method below so that the client code creates three WaterBuckets - one with no water but a
capacity of 10, one with no water but a capacity of 20, and one with a water level of 15 and a capacity of 20.
public class Driver {
public static void main(String[] args) {

}
}

16/40

Part Three: Adding Instance Methods


We have implemented instance variables and constructors in our class; now we are also going to implement instance
methods. Instance methods are commands given to an Object (move to the right), sometimes in the form of a question
(can you move to the right?). We are going to look at several commands that we will want to give to our Performer object.
The first command we will add to the Performer class is the moveBy method, shown below.

Methods generally go below the constructors in a class. This method is called a mutator - it takes two parameters and
changes (mutates) the values of the centerX and centerY properties of a Performer. Now in AnimationLoader, there will
be two ways to tell a Performer object to move:

changes steve's instance fields

Or:

calls steve's instance method

Notice that to call a method, you still use the dot operator and a name. But unlike an instance variable, you will put
parentheses and specify some number of parameters.

17/40

Another command we could add to our Performer object allows us to ask it a question - how much area does it take up?

To use this new method in AnimationLoader.

call steve's instance method

store the result of the method


You can use this result in a number of ways - you could print it to the screen, use the value in another calculation, etc.
The getArea() method is called an accessor, as it doesn't change the instance variables of the object, but it does ask the
object for some information. It's important to notice how these two methods are the same and how they are different.

Return type

void

int

moveBy

getArea

Parameters

x (type double), y (type double)

none

Modifies
instance
variables?

yes

no

Returns a
value

no

yes

Method name

18/40

Another interesting method we could write is one that finds the distance between two Performers. Mathematically, the
distance between two points can be found by the distance formula:

d = (x2 x 1 )2 + (y1 y2 )2
Our method in the Performer class would look like this:

The most interesting thing about this method is that the parameter is another Performer object. Hopefully this makes
some sense - to find the distance from yourself to another Performer, you'd need to know information about the other
Performer. To call this method from the client code:

calling steve's instance method

19/40

Up to this point, everything we've made has been public - classes, instance variables1, and instance methods. There are
several situations where this is bad programming practice, specifically for instance variables. Instance variables represent
the properties of an object, and many times we want to keep properties within a certain range. For our Performer's
perhaps we want to keep the centerX and centerY coordinates between 0 and 500 (so they stay on the screen). But if a
client wrote code like the following:

Bad client!

our poor Performer would leave the screen. You might think that you just won't do that in your code, but there are two
problems with that thinking:
(a) you are assuming you will remember these "rules" a week or month from now when you look at your project
again
(b) you are assuming your client will follow your rules.
A nice way to think about this is:
"Build something that is foolproof, and someone will invent a better fool."
To protect our code from ourselves and other clients, we will try to enforce some rules. One of those rules will be:
Instance variables must ALWAYS be declared private.
Private means that the code cannot be used outside of the given class. In the Performer class, here are all of the
instance variables declared with the correct access permissions:

All instance variables are declared private now

Technically, our instance variables have been declared with "no modifier". This effects how subclasses interact with the
variables. We won't go into detail about this topic.

20/40

The side effect of this change is that clients cannot directly access the instance variables:

Can't access private data

So how can you do anything with the instance variables? Fortunately, we have a public method to do this!

Calling public instance method

Oh wait... now we have the same problem again! But this time we can prevent the client from messing up our Performer
object by making sure the changes to the instance variables are okay.

21/40

Another solution:

By making instance variables private, you are using a concept called information hiding. There may be internal instance
field data that client code does not need to know about. By marking this data as private, you can prevent the client from
viewing, modifying, and potentially messing up the internal state of an object. To provide client access to internal data, we
usually provide getter and setter methods. For example, we could add these public methods to the Performer class:

With these two methods, we have provided clients with the ability to change the color of the Performer as well as the
ability to ask the Performer for its width [this could be useful if you want to create a loop that increases steve's width until it
reaches 300, etc].

22/40

A couple of final thoughts on public and private. First, you can make methods private. Just like instance variables, private
methods can only be used inside of the class they are defined. Second, do not make local variables private - you will get
an error if you try.

Can't apply to local variables


And finally, even though we have made all of our instance variables private, this method in the Performer class still works.

The reason? the centerX and centerY instance variables are private to the Performer class. Because the distanceTo
method is inside of the Performer class, it is allowed to access the private instance variables of another Performer object.
So to summarize:
Instance variables must ALWAYS be declared private.
To access and modify instance data from client code, you should use a provided instance method.

Vocabulary: Define the following terms in your own words and explain their purpose
Instance Method

return type

parameter

private

Information Hiding

Mutator/Setter

Accessor/Getter

23/40

Exercises:
1) Error Fix:
(a) Look through the AnimationLoader class and find all the red error squiggles you have on commands
that change the instance variables of your Performer objects (for example, increasing the width by 50)
(b) In the Performer class, create mutator methods that change the values in the instance variables (you
can model off of setColor() and moveBy())
(c) Change your code in AnimationLoader that is trying to access private instance data so that it now uses
your public instance methods.
2) You said what?:
a) Add another instance variable to the Performer class of type String - give it the name message.
b) Create an instance method named say(). This method is a mutator - it has a void return type and
takes one parameter, a String value to be stored in the message instance variable.
c) In the AnimationLoader class, tell one of your Performer objects to say something by calling the say()
method.
3) Spinning Out:
a) Add another instance variable to the Performer class of type int - give it the name angle.
b) Create an instance method named rotateBy(). This method is a mutator - it has a void return type and
takes one parameter, a integer value to increase the angle instance variable by.
c) In the AnimationLoader class, tell one of your Performer objects to rotate by some angle - enjoy the
show!
4) Perimeter Breach:
a) Create an instance method named getPerimeter(). This method is an accessor - it has an int return
type and takes no parameters.
b) In the AnimationLoader class, ask one of your Performer objects for its perimeter and print out the
result. Could you make the Performer say what its perimeter is?
5) Come To Me:
a) Create an instance method named goTo(). This method is a mutator - it has a void return type and
takes one parameter of type Performer - the Performer we would like to "go to". Copy the centerX and
centerY positions from the parameter into the instance variables.
b) In the AnimationLoader class, ask one of your Performer objects to go to the position of another
Performer object.

24/40

Questions
1) Below is anther version of our PiggyBank and Driver classes
public class PiggyBank {
private int pennies, nickels, dimes, quarters;
public PiggyBank() {
pennies = 0;
nickels = 0;
dimes = 0;
quarters = 0;
}
public PiggyBank(int p, int n, int d, int q) {
pennies = p;
nickels = n;
dimes = d;
quarters = q;
}
public void addCoins(int p, int n, int d, int q) {
pennies += p;
nickels += n;
dimes += d;
quarters += q;
}
public double getAmount() {
double value = pennies * 0.01 + nickels * 0.05 + dimes * 0.1 + quarters * 0.25;
return value;
}
}
public class Driver {
public static void main(String[] args) {
PiggyBank hamm = new PiggyBank(3, 8, 1, 2);
hamm.addCoins(2, 9, 4, -1);
double value = hamm.getAmount();
}
}
(a) Identify the instance methods and constructors of the PiggyBank class. Also, identify if the methods
are mutators or accessors, their return type, and their parameters.

(b) What number will be stored in the variable value in the Driver class?

25/40

2) Below is a class that is supposed to represent a Triangle.


public class Triangle {

}
(a) In which box would you declare the instance variable(s)? In which box would you declare the
constructor(s)? In which box would you declare the instance method(s)?
(b) A Triangle can be represented by a base and a height. Fill in the box above so it has two instance
variables that describes these twos length of the Triangle
(c) Add one constructor to the Triangle class - it should take two parameters that specify the base and
height of the Triangle. The instance variables of the class should be assigned appropriately.
(d) Add a setter method that allows a client to change the base of the triangle
(e) Add a getter method that returns the area of the Triangle object

26/40

3) Below is a class that represents a WaterBucket.


public class WaterBucket {
int amountOfWater;
int capacity;
public WaterBucket(int amount, int cap) {
amountOfWater = amount;
capacity = cap;
}
public void fillBy(int more) {
amountOfWater += more;
}
public int getFreeSpace() {
return capacity - amountOfWater;
}
}

Finish the main method below so that the client code creates one WaterBucket with a water level of 10 and a
capacity of 20. Then fill the water bucket with 5 more units of water. Then print out the amount of free space left
in the bucket.
public class Driver {
public static void main(String[] args) {

}
}

27/40

Part Four: Static versus Instance (Dynamic)


One concept that can be confusing when defining class is the use of the keyword static. To demonstrate the difference,
here is some code in the AnimationLoader:

The first Performer (steve) is supposed to be red, have a center location of (150, 150) and have a width and height of 50.
The second Performer (jobs) is supposed to be blue, have a center location of (300, 300) and have a width and height of
50.
With our regular instance variables, here is what you should see:

!
Observe the difference when we make the centerY and color static.

!
Woah! Both steve and jobs ended up being blue with the same centerY coordinate! Why did this happen? The static
keyword means that our instance variables have been transformed into a class variable - no longer are they dynamically
made for each object we make. Instead, they are statically create for the class, and all instance share the same variables.
So when jobs is changing its color to be blue, it is also functionally changing steve's color as well. (Unless you want all
your Performer's to have the same color and centerY, you probably should get rid of the static now!)

28/40

Use of the static keyword does have its uses. If you want to keep track of how manny Performer objects have been
created, a static variable makes a lot of sense.

Here we've added a static variable to the Performer class called count. When a Performer object is created, the
constructor increases the count variable by one [this would need to be done in ALL constructors]. There is also a new
static method named getCount() that returns the value stored in the count variable.
Back in AnimationLoader:

Notice how the getCount() method is being called using the Performer class name instead of the name of steve or jobs.
That's because static methods belong to the class, not an instance of the class! After the code above executes, the value
in the variable count will be 2. If the count variable had not been declared statically, then each Performer would get their
own count variable, each of which would have the value of 0 by the end of the code.

29/40

Questions
1) Below is anther version of our PiggyBank and Driver classes
public class PiggyBank {
private int pennies, nickels;
private static int dimes, quarters;
public PiggyBank(int p, int n, int d, int q) {
pennies = p;
nickels = n;
dimes = d;
quarters = q;
}
public void addCoins(int p, int n, int d, int q) {
pennies += p;
nickels += n;
dimes += d;
quarters += q;
}
public double getAmount() {
double value = pennies * 0.01 + nickels * 0.05 + dimes * 0.1 + quarters * 0.25;
return value;
}
}
public class Driver {
public static void main(String[] args) {
PiggyBank hamm = new PiggyBank(3, 8, 1, 2);!
hamm.addCoints(2, 9, 4, -1);! !
!
PiggyBank mint = new PiggyBank(1, 2,3, 4);!
mint.addCoins(5, 4, 1, 7);!
!
!
}

!
!
!
!

//Line 1
//Line 2
//Line 3
//Line 4

}
(a) Which of the variables of the PiggyBank class belong to instances of the class, and which belong to the class
itself (they are shared)?
Fill in this table that shows the values of hamm's and mint's instance variables after the lines in the client code
executes.

After...

hamm's variables
pennies

nickels

dimes

mint's variables
quarters

pennies

nickels

dimes

Line 1

Mint Doesn't exist yet

Line 2

Mint Doesn't exist yet

quarters

Line 3
Line 4
30/40

Part Five: Miscellaneous Class Issues


A) Constructor Complications
Classes have some strange but true properties. One is that every class ALWAYS have at least one constructor. Here is a
simplified version of our Performer class:

If you were to delete the constructor, it would appear that our class would have no constructors.

But interestingly, you can still create instances of the Performer class!

How is this possible? Java will provide your class with an implicit no argument constructor when you don't write your own.
It will initialize your integer and decimal instance variables to 0 and 0.0, and all object instance variables to null
[representing the absence of a created object].

31/40

Now things get a little weird when you don't write your own no-argument constructor.

!
Now back in the AnimationLoader...

Why the error? Java will only provide you with a no-argument constructor if you don't write any of your own. Based on
this setup, you can only create a Performer object by calling the three-parameter constructor:

So to summarize:
All java classes have at least one constructor
If you don't write any constructors, java will provide you with a no-argument constructor

32/40

B) toString() method
Classes are really good at encapsulating information. Many times it is important to get a textual representation of the
Object for debugging purposes. The common way to accomplish this in the Java programming language is by writing a
toString() method.

The toString method returns a String that is to represent the internal state of an object. The stripped down Performer
object above has three instance variables: a color, centerX, and a centerY. A common implementation of toString would
look like the following:

And the method could be used in a print statement back in client code.

For this example, the output would be:

When printing an object, the call to toString() is always automatically called, so the following print statement will also print
out the information about steve.

33/40

C) Returning Instances of a Class


Let's say we want to know, between two Performers, which has the most area. Such a method in the Performer class
might look like this:

This method is interesting because the return type is a Performer object! We want our method to pick between two
different performer objects and return the Performer with the largest area. Determining the areas is not so bad:

Now we have both our area and the other Performer's area, we can now write some conditional logic

In one case, the other Performer has the most area, so we clearly know which Performer object to return (other). But
what about the other case... we want to return ourself... but we don't have a name for ourself (this sounds like a very
existential problem). The creators of Java introduced a word to name "ourself", and that name is this.

34/40

In client code, we can write code like this:

When it executes, we enter the largestArea method with two pieces of information - the value of the parameter (sam), and
the value of "ourself" (bob). Inside the largestArea method, other means the same thing as sam. Likewise, this means
the same thing as bob.

sam

bob

What's REALLY interesting, is if you now add code to change the color of largest:

You should see that bob slowly changes color to green and announces it has the most area (5*10 > 6*8). Notice that
performing a command on the variable largest was equivalent to performer the same commands on bob. That's because
largest is an alias for bob - two different names for the same object!

35/40

Part Six: Creating Pong


We can expand the roles of Performers to represent the classic game of Pong: http://www.ponggame.org
To get started, we will need to create the necessary initial elements (Performers): 1 background, 2 paddles, 4 "walls", one
sphere, and two score keepers. Here is what a possible layout for you game could look like:
!

top wall

left wall

score keepers

left paddle

right wall

right paddle
sphere

bottom wall

My sphere is represented by a smiley face image and my background is orange (but you could pick whatever you like).
We're now going to add a run loop to your project. This is an infinite loop that keeps your performer's acting, with each
animation taking exactly 1 frame each time. This code should go beneath your created Performer objects in the
loadAnimations() method.

36/40

Next, we want to control our paddles using the keyboard. To do that, we will need some conditional statements.

!
This if case checks to see if the w key has been pressed by the user of the program. For the above code to compile, you
will need to import the KeyEvent class (hover over the error message and Eclipse should give you the option to import the
needed class). Generally we want the paddle to move up a few pixels when the w key is pressed:

After adding this code, your left paddle should move! You can add similar code to make the left paddle move down and
for the right paddle to move up and down. (The arrow keys are KeyEvent.VK_UP and KeyEvent.VK_DOWN).

Next, we want the sphere to move on its own. We don't always want the sphere to move in the same direction, so we will
need variables to hold the x velocity and the y velocity. These variables can be used to move the sphere.

!
Notice that the xVel and yVel are declared before the run loop (so they are not reset each iteration) and that the sphere
movement is not conditional (you may change that later...).

37/40

Now our sphere is moving, but it only moves in one direction (it never bounces off of obstacles). We need a way to
determine if our sphere is intersecting with the walls or the paddle. To do so, we're going to write an instance method for
the Performer class.

!
Determining if two things intersect is a fairly complex. Fortunately, Java has a built in library that helps us deal with
rectangle intersections - the Rectangle2D.Double class.

Rectangle2D.Double is a class that has a four argument constructor. The line above creates a Rectangle2D.Double
object with the same dimensions as our Performer. The constructor for the Performer requires the upper left hand corner
x and y coordinate instead of the center, which explains the subtraction of half the width and half the height. We will need
to form a Rectangle2D.Double object for the other Performer as well.
!

To save space, you should notice that I put each of the parameters on their own line. Now we can use the
Rectangle2D.Double classes built in intersects() instance method to determine if there is an intersection:

38/40

Back in client code, we can now have the sphere bounce off the paddles:

Similar code can now be written to handle bouncing off the top and bottom walls, and for changing the score when the
sphere hits the side walls.
To get the score keepers to work, you will need pictures for each of the different possible scores in pong. Then you can
have your Performer change its image to match the appropriate picture. For example, you could add this method to the
Performer class:

And then in client code, assuming you have an integer variable to hold the left player's score:

A very challenging problem is getting the sphere to bounce off of the top of the paddle correctly, as well as having the ball
bounce off the face of the paddle with a greater slope when the hit is further from the center. Adding a pause between
scores is always a nice touch...

39/40

Ending Extras
1) The AnimationFrame supports mouse events as well, if you would like to use them. For example:
Point p = AnimationFrame.mouseLocation();
boolean mouseIsDown = AnimationFrame.mouseIsDown();

2) You can override the way Performer's draw themselves by writing the method draw:
public void draw(Graphics2D g) {
!

//your custom drawing code

3) You can remove a Performer (say bob) by using the code segment below
AnimationFrame.remove(bob);

4) To have an animation occur instantaneously, run an Animation for 1 frame


!

bob.setColor(Color.RED);
AnimationFrame.animate(1); //jump right to red, no color blend

5) You can change the color and font for the messages Performer's say by creating instance variables for messageFont
(type Font) and messageColor (type Color).

6) Performers are drawn in the order they are created. That means the last Performer will draw on top of Performers
created at an earlier time. The order in which Performers are drawn can be changed by using the following commands:
AnimationFrame.moveToBack(bob); //make bob be drawn beneath everything else
AnimationFrame.moveToFront(bob); //make bob be drawn on top of everything else
AnimationFrame.moveBack(bob); //move bob back one in the draw order
AnimationFrame.moveForward(bob); //move bob one forward in the draw order

40/40

Anda mungkin juga menyukai