Animation 16 Sep21 Moving pictures n Animationmaking objects

Animation 16 -Sep-21

Moving pictures n Animation—making objects that appear to move on the screen—is done by displaying a series of still pictures, one after the other, in rapid succession n n Generally you should try for at least 20 pictures/second is repainting every 50 milliseconds 2

The bouncing ball n “Bouncing ball” is the “Hello World” of animation n We will develop this program using: n n Model-View-Controller Observer-Observable Threads Timers 3

Review of MVC n MVC stands for Model-View-Controller n The Model is the actual internal representation n The View (or a View) is a way of looking at or displaying the model n n n It should be independent of the other classes It’s handy if this class can extend Observable It’s handy if this class implements Observer The Controller provides for user input and modification These three components are usually implemented as separate classes (or sets of classes) 4

Review of Observer and Observable n java. util. Observable is a class n When it does something that should be observed, it says: n n n set. Changed(); notify. Observers(); /* or */ notify. Observers(arg); java. util. Observer is an interface n It has to register itself with (subscribe to) an Observable: n n my. Observable. add. Observer(my. Observer); It has to implement: n n public void update(Observable obs, Object arg) This method is automatically called when observers are notified obs is the object being observed If the Observable did notify. Observers(), arg is null 5

Review of Threads n You can extend the Thread class: n n class Animation extends Thread {…} Limiting, since you can only extend one class You must override public void run( ) To make it “go”: n n Animation anim = new Animation( ); anim. start( ); Or you can implement the Runnable interface: n n n class Animation implements Runnable {…} You must implement public void run( ) To make it “go”: n Animation anim = new Animation( ); Thread my. Thread = new Thread(anim); my. Thread. start( ); 6

Timers n n A java. util. Timer is used to schedule code for future execution A Timer may: n n n Timer constructors: n n n Schedule a one-time execution, or Schedule repeated executions at regular intervals Timer() Timer(boolean is. Daemon) Timer(String name, boolean is. Daemon) A Timer can keep an application from terminating, unless it is specified as a daemon thread n n A daemon thread dies if there are no non-daemon threads running Create daemon Timer threads with new Timer(true) or new Timer(name, true) 7

Using a Timer for animation n n public void schedule(Timer. Task task, long delay, long period) n Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay (which may be zero) n Subsequent executions take place at approximately regular intervals separated by the specified period n Times are specified in milliseconds (1/1000 s of a second) Notice that schedule requires a Timer. Task as an argument n n Timer. Task is an abstract class you must extend and provide a public void run() method Timer. Task provides an (implemented) public boolean cancel() method n Returns false if there were no scheduled executions to cancel 8

The Model class, I n import java. util. Observable; class Model extends Observable { public final int BALL_SIZE = 20; private int x. Position = 0; private int y. Position = 0; private int x. Limit, y. Limit; private int x. Delta = 6; private int y. Delta = 4; // methods (on next slide) } 9

The Model class, II n public void set. Limits(int x. Limit, int y. Limit) { this. x. Limit = x. Limit - BALL_SIZE; this. y. Limit = y. Limit - BALL_SIZE; } public int get. X() { return x. Position; } public int get. Y() { return y. Position; } public void make. One. Step() { // code for making one step (on next slide) } 10

The Model class, III n public void make. One. Step() { // Do the work x. Position += x. Delta; if (x. Position < 0 || x. Position >= x. Limit) { x. Delta = -x. Delta; x. Position += x. Delta; } y. Position += y. Delta; if (y. Position < 0 || y. Position >= y. Limit) { y. Delta = -y. Delta; y. Position += y. Delta; } // Notify observers set. Changed(); notify. Observers(); } 11

The View class n import java. awt. *; import java. util. *; import javax. swing. JPanel; class View extends JPanel implements Observer { Model model; View(Model model) { this. model = model; } @Override public void paint(Graphics g) { g. set. Color(Color. WHITE); g. fill. Rect(0, 0, get. Width(), get. Height()); g. set. Color(Color. RED); g. fill. Oval(model. get. X(), model. get. Y(), model. BALL_SIZE); } } public void update(Observable obs, Object arg) { repaint(); } 12

The Controller class, I n import import java. awt. *; java. awt. event. *; java. util. Timer. Task; javax. swing. *; public class Controller extends JApplet { JPanel button. Panel = new JPanel(); JButton run. Button = new JButton("Run"); JButton stop. Button = new JButton("Stop"); Timer timer; Model model = new Model(); View view = new View(model); // View must know about Model 13

The Controller class, II n n @Override public void init() { lay. Out. Components(); attach. Listeners. To. Components(); // Connect model and view model. add. Observer(view); } private void lay. Out. Components() { set. Layout(new Border. Layout()); this. add(Border. Layout. SOUTH, button. Panel); button. Panel. add(run. Button); button. Panel. add(stop. Button); stop. Button. set. Enabled(false); this. add(Border. Layout. CENTER, view); } 14

The Controller class, III n private void attach. Listeners. To. Components() { run. Button. add. Action. Listener(new Action. Listener() { public void action. Performed(Action. Event event) { run. Button. set. Enabled(false); stop. Button. set. Enabled(true); timer = new Timer(true); timer. schedule(new Strobe(), 0, 40); // 25 times a second } }); stop. Button. add. Action. Listener(new Action. Listener() { public void action. Performed(Action. Event event) { run. Button. set. Enabled(true); stop. Button. set. Enabled(false); timer. cancel(); } }); } 15

The Controller class, IV n @Override private class Strobe extends Timer. Task { public void run() { model. set. Limits(view. get. Width(), view. get. Height()); model. make. One. Step(); } } 16

Summary n In this program I used: n Model-View-Controller n n Observer-Observable n n This is a good design pattern for helping to isolate the Model from the View Threads n n n This is a good design pattern for many uses; it separates the “business logic” (the Model) from the classes that are basically I/O If you want to have a controllable animation, Threads are essential The animation runs in one Thread, the controls in another Timers n n Timers are a convenient way to schedule regularly repeating tasks With a slightly different design, you could use Thread. sleep(ms) instead 17

The End In preparing for battle I have always found that plans are useless, but planning is indispensable. — Dwight D. Eisenhower, general and president Weeks of programming can save you hours of planning. — unknown 18
- Slides: 18