Simple Animation

Download Report

Transcript Simple Animation

Simple Animation
26-Jul-16
The bouncing ball


The “bouncing ball” is to animation what “Hello world”
is to programming
With a single Thread, we can either...





...animate the display
...provide controls for the display
...but we can’t do both
We will use Observer and Observable to help
decouple the model from the view
To highlight the important portions of the program, I’ll
use blue for Thread-relevant code and red for Observerrelevant code
2
The Model class, I
import java.util.Observable;
class Model extends Observable implements Runnable {
final int BALL_SIZE = 20;
int xPosition = 0;
int yPosition = 0;
int xLimit, yLimit;
int xDelta = 6;
int yDelta = 4;
public boolean running = false; // can be changed from outside
public void run() {...}
void makeOneStep() {...}
}
3
The Model class, II


void makeOneStep() {
xPosition += xDelta;
if (xPosition < 0) {
xPosition = 0;
xDelta = -xDelta;
}
if (xPosition >= xLimit) {
xPosition = xLimit;
xDelta = -xDelta;
}
yPosition += yDelta;
if (yPosition < 0 || yPosition >= yLimit) {
yDelta = -yDelta;
yPosition += yDelta;
}
}
Nothing in here is relevant to Threads or Observers
4
The Model class, III
public void run() {
while (running) {
makeOneStep();
this.setChanged();
this.notifyObservers();
try { Thread.sleep(20); }
catch (InterruptedException e) { }
}
}
5
The Controller class, top
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Controller extends Applet {
Panel buttonPanel = new Panel();
Button runButton = new Button(" Run ");
Thread thread;
Model model = new Model();
View view = new View();
public void init() {...}
}
public void start() {...}
6
The Controller class: init() I

public void init() {
// Lay out components
setLayout (new BorderLayout ());
buttonPanel.add (runButton);
this.add (buttonPanel, BorderLayout.SOUTH);
this.add (view, BorderLayout.CENTER);
// Attach actions to components
...
// Tell the View about myself (Controller) and about
// the Model ...
}
7
The Controller class: init() II


// Attach actions to components
runButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (model.running) {
model.running = false;
runButton.setLabel(" Run ");
} else {
model.running = true;
runButton.setLabel(" Stop ");
thread = new Thread(model);
thread.start();
}
}});
Notice that we create a new Thread every time the “Run” button
is clicked
8
The Controller class: init() III



// Tell the View about myself (Controller) and about the Model
view.model = model;
model.addObserver(view);
The View has to know about (have a reference to) the Model in
order to display information about it
The Model doesn’t know anything about the View



The Observer is added from the outside (here, in the Controller class)
The only thing in the Model class about this is that it has to extend
Observable
To be in a separate Thread, the Model has to implement
Runnable and supply a public void run() method
9
The Controller class, start()






public void start() {
// Getting the view size MUST be done in the start() method
model.xLimit = view.getWidth() - model.BALL_SIZE;
model.yLimit = view.getHeight() - model.BALL_SIZE;
}
The Model class needs to know the size of the area that it’s bouncing the ball
around in
You can request the size only after the Applet has been inited
The start() method is your first chance for this
If you want to be able to change the size of the Applet (something you can do
from appletviewer, but not from a browser), you need to get the size every
time you paint
When you write an application, you should always allow for the possibility
that the user will change the window size
10
The View class
import java.awt.*;
import java.util.*;
class View extends Canvas implements Observer {
Model model;
int stepNumber = 0;
int position = 50;
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillOval(model.xPosition, model.yPosition,
model.BALL_SIZE, model.BALL_SIZE);
}
}
public void update(Observable obs, Object arg) {
repaint();
}
11
The End
12