Session 12 Introduction to PinBallGame (Chaper 7).

39
Session 12 Introduction to PinBallGame (Chaper 7)

Transcript of Session 12 Introduction to PinBallGame (Chaper 7).

Page 1: Session 12 Introduction to PinBallGame (Chaper 7).

Session 12

Introduction to PinBallGame

(Chaper 7)

Page 2: Session 12 Introduction to PinBallGame (Chaper 7).

Pinball Game Construction Kit Version 1

Page 3: Session 12 Introduction to PinBallGame (Chaper 7).

Some cool new features

• Replaced the fire button with a mouse event.

• Multiple balls can be in the air at once.

• Control is no longer in the paint method.

• But before we talk about what Budd did correctly, well…

Page 4: Session 12 Introduction to PinBallGame (Chaper 7).

Say It Once and Only Once!

In the interest of simplifying the number of files we need to run a program, Budd has repeated code that can be reused by inheritance (figure 7.3, p 102).

Gravity affects a PinBall in the same way that it affects a CannonBall. The only differences between a PinBall and a CannonBall are its size and its initial trajectory.

So, we can say:public class PinBall extends CannonBall {

public PinBall( int sx, int sy ) {super( sx, sy, 10,-2 + Math.random()/4, -15 );

}}

Inheritance makes our job easier—as well as isolating repeated code.

Page 5: Session 12 Introduction to PinBallGame (Chaper 7).

Looks the same, but it’s not.

• Replaced the fire button with a mouse event.

• Multiple balls can be in the air at once.

• Control is no longer in the paint method.

Page 6: Session 12 Introduction to PinBallGame (Chaper 7).

Handling Mouse Events

The CannonWorld handles only events that are generated by the active components — a button and a slider — that we added to it.

More generally, though, we will want to trap and respond to any mouse action, anywhere within the frame.

Any listener that wishes to monitor mouse activity must implement the MouseListener interface:

Page 7: Session 12 Introduction to PinBallGame (Chaper 7).

public interface MouseListener {public void mouseClicked ( MouseEvent e );public void mouseEntered ( MouseEvent e );public void mouseExited ( MouseEvent e );public void mousePressed ( MouseEvent e );public void mouseReleased( MouseEvent e );

}

The MouseListener interface is part of the package java.awt.event. It specifies what an object must do to be a mouse listener within the Java Event Model.

Page 8: Session 12 Introduction to PinBallGame (Chaper 7).

How the MouseListener works.

Think back to how we implemented Button listeners:

private class FireButtonListener implements ActionListener {

We can do a similar thing for MouseListeners…

private class PinballGameListener implements MouseListener{

However, to implement an interface, the Java language insists that the programmer provide a definition for all operations.

But what if I don’t want all 5 mouse events??

Page 9: Session 12 Introduction to PinBallGame (Chaper 7).

MouseAdapter to the rescue

• To simplify this process, the Java library provides a simple class named Mouse Adapter. The class MouseAdapter implements the MouseListener interface, but uses an empty method for each method.

• Rather than implement a MouseListener, we may choose to implement a MouseAdapter. (Let’s go back to the code (also p 104))

Page 10: Session 12 Introduction to PinBallGame (Chaper 7).

Mouse Events in the Pin Ball Game

In the PinBallGame class, we have the following class relationship:

MouseListener

implements

MouseAdapter

extends

MouseKeeper

Page 11: Session 12 Introduction to PinBallGame (Chaper 7).

• What does a MouseKeeper do?

Page 12: Session 12 Introduction to PinBallGame (Chaper 7).

• What does a MouseKeeper do? – If the mouse is pressed in the“shooting area”,

then it creates and launches a new pinball.

Page 13: Session 12 Introduction to PinBallGame (Chaper 7).

• What does a MouseAdapter do?

Page 14: Session 12 Introduction to PinBallGame (Chaper 7).

• What does a MouseAdapter do?– Nothing, in response to any sort of mouse

event.

Page 15: Session 12 Introduction to PinBallGame (Chaper 7).

• Why do you suppose that Java’s creators call it an “adapter”?

Page 16: Session 12 Introduction to PinBallGame (Chaper 7).

• Why do you suppose that Java’s creators call it an “adapter”? – They use a common design from the world as

an analogy.

Page 17: Session 12 Introduction to PinBallGame (Chaper 7).

• Why do you suppose Java’s creators bothered to define the MouseListener interface? Why not have everyone extend MouseAdapter?

Page 18: Session 12 Introduction to PinBallGame (Chaper 7).

• Why do you suppose Java’s creators bothered to define the MouseListener interface? Why not have everyone extend MouseAdapter? – Inheritance is not free. Why force

programmers who plan to implement most or all of the interface to pay the extra price?

Page 19: Session 12 Introduction to PinBallGame (Chaper 7).

Another adaptor you might find handy

In constructoraddWindowListener(new Closer());

As inner classprivate class Closer extends WindowAdapter {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

}

Page 20: Session 12 Introduction to PinBallGame (Chaper 7).

Pinball Version 1

• Replaced the fire button with a mouse event.

• Multiple balls can be in the air at once.– Uses a Vector to contain many balls

• Control is no longer in the paint method.

Page 21: Session 12 Introduction to PinBallGame (Chaper 7).

Keeping track of multiple objects.

• In the past we have kept track of multiple items through an array, e.g., in Multi-ball world for chapter 5.

• What are the limitations of using an array?

Page 22: Session 12 Introduction to PinBallGame (Chaper 7).

Keeping track of multiple objects.

• In the past we have kept track of multiple items through an array, e.g., in Multi-ball world for chapter 5.

• What are the limitations of using an array? – You have to state the number of elements at

construction time.

Page 23: Session 12 Introduction to PinBallGame (Chaper 7).

Keeping track of multiple objects.

• In the past we have kept track of multiple items through an array, e.g., in Multi-ball world for chapter 5.

• What are the limitations of using an array? – You have to state the number of elements at

construction time.

• If we don’t know the number in advance we can use the concept of a Vector. (Let’s go back to the code (also pp 102-103))

Page 24: Session 12 Introduction to PinBallGame (Chaper 7).

Using Vector

• import java.util.Vector;

• private Vector balls; // holds only objects

• balls = new Vector( ); // create a Vector

• Using the Vector:balls.addElement(newBall); // add element

balls.size( ); // return # elements

// Retrieving an element requires a cast

PinBall aBall = (PinBall) balls.elementAt (i);

Page 25: Session 12 Introduction to PinBallGame (Chaper 7).

Exercise

• Modify version 1 of the PinBallGame to allow users only six shots.

• Add a Label at the top of the Frame that displays the number of shots that have been fired so far.

• If the user tries to fire again after six shots, the label should display a “Sorry...” message.

Page 26: Session 12 Introduction to PinBallGame (Chaper 7).

From javadoc for the Label class:Constructor SummaryLabel()Constructs an empty label.

Label(String text)Constructs a new label with the specified string of text, left

justified.

Method SummaryString getText()Gets the text of this label.

void setText(String text)Sets the text for this label to the specified text.

Page 27: Session 12 Introduction to PinBallGame (Chaper 7).

A Possible Solutionpublic class PinBallGame extends Frame { ...private int numberOfShotsTaken;private Label numberOfShotsLabel;public PinBallGame () { ... // all the original code plus:

numberOfShotsTaken = 0;numberOfShotsLabel = new Label( "Number Of Shots Taken: 0" );add( "North", numberOfShotsLabel );

}...private class MouseKeeper extends MouseAdapter {

public void mousePressed (MouseEvent e) { ...if ( (x > FrameWidth-40) ... {

if ( numberOfShotsTaken < 6 ) {// make ball and thread, then:numberOfShotsTaken++;numberOfShotsLabel.setText("Number Of Shots Taken: " +

numberOfShotsTaken );} else

numberOfShotsLabel.setText( "Sorry, but you have already [...]!" );}

}}

Page 28: Session 12 Introduction to PinBallGame (Chaper 7).

Threads of ExecutionWhat? How? Why?

The Thread class provides methods to start, run, sleep, and stop an independent path of computation, among other things. The start() method manages the overhead of threads for us; we can simply watch them go! (This is similar to the benefits we get from using Frames...)

The pinball game separates these responsibilities into different objects:

• painting the frame• controlling the movement/location of balls

Page 29: Session 12 Introduction to PinBallGame (Chaper 7).

Threads of ExecutionThis separation simplifies all of the methods

involved, for writing, reading, and modifying. The cost is an increase in the number of methods needed.

You may also suffer some separation anxiety. To programmers used to writing the omniscient, omnipotent main(), decentralizing control can cause a sense of fragmentation. This will largely go away as you gain OO and Java experience.

Page 30: Session 12 Introduction to PinBallGame (Chaper 7).

PinBall Version 2

• Adds targets for the PinBalls to bounce off of and score on

• Types of targets:– Spring– Wall– Hole– ScorePad

• What do all targets have in common?

Page 31: Session 12 Introduction to PinBallGame (Chaper 7).

PinBallTarget Interface

interface PinBallTarget {

public boolean intersects (Ball aBall);

public void moveTo (int x, int y);

public void paint (Graphics g);

public void hitBy (Ball aBall);

}

Why use an interface?– we want to process targets uniformly, e.g., check if a ball hit it– the interface makes them the same “type” for storage in a Vector

Page 32: Session 12 Introduction to PinBallGame (Chaper 7).

Hole target

• structurally similar to a ball – round like a ball– has a location on the frame like a ball

• behavioral– it must adhere to the interface

class Hole extends Ball implements PinBallTarget

Inherits moveTo and paint, but supplies intersects and hitBy

Page 33: Session 12 Introduction to PinBallGame (Chaper 7).

More on Threads

• We can think of separate threads as separate programs running concurrently.

• They don’t literally run at the same time (unless you have a machine with more than one CPU). Instead, one thread gets the CPU for a while, then it gets put on hold while another thread gets the CPU, and so on.

• When separate threads are running, sometimes we need to worry about two threads taking actions that conflict with one another. We can use the keyword synchronized to have the JVM help maintain order.

Page 34: Session 12 Introduction to PinBallGame (Chaper 7).

A Problem Caused bySeparate Threads of Control

Page 35: Session 12 Introduction to PinBallGame (Chaper 7).

More on Threads

• Example: The second version of the pin ball game keeps track of the score the user earns for hitting targets in the field of play. It keeps track of the score in an instance variable named score:

private int score = 0;• When a pin ball strikes a target, the target tells the pin

ball game to add its point total to the instance variable by sending an addScore message:

public void addScore( int value ) {score = score + value;scoreLabel.setText( "score = " + score );

}

Page 36: Session 12 Introduction to PinBallGame (Chaper 7).

A Problem Caused bySeparate Threads of Control

Page 37: Session 12 Introduction to PinBallGame (Chaper 7).

The solution

synchronized public void addScore( int value ) {score = score + value;scoreLabel.setText( "score = "

+ score );}The keyword synchronized is used to ask

Java to guarantee that only one thread at a time can be executing the addScore() method.

Page 38: Session 12 Introduction to PinBallGame (Chaper 7).

PinBall Contruction Kit Version 3

Page 39: Session 12 Introduction to PinBallGame (Chaper 7).

Understanding the PinBallGame Kit• How is the “black box” in the PinBallGame drawn?• What is the difference between the items outside the box

of the game window and the items inside the box?• What messages can we send to a Peg, and where is

each behavior defined?• What method is used to determine the number of

elements held in a Vector? What method is used to access the values? What method is used to insert a new value into the collection?

• What is the purpose of the PinBallTarget interface?• Why can’t we do without it?• Why is the PinBallGame instance stored in a class

variable instead of an instance variable? (See class PinBallGame for the declaration, but study the code in class ScorePad to find the reason.)