/* * Created by Nick on Jan 8, 2005 * */ package jmslexamples; import java.awt.*; import java.util.*; import javax.swing.*; import com.softsynth.jmsl.*; /** * An animation canvas is repainted 10 times a second. Each time, it renders the * current position of all its "characters". This is implemented as a MusicJob. * * Its characters are moved around by MusicJobs called CharacterScripts, which * update the (x, y) positions of the characters in their repeat() methods * * Note that the refresh rate of the Animation is constant and runs forever. The * character scripts can run at any rate they want to since they don't do any * actual drawing (they just update the location data of the characters) * * Thanks to Daniel Howe for suggesting this example * * For a version that makes sound, see jmslexamples.jsyn.AnimationAppletWithSound * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * didkovn@mail.rockefeller.edu * */ public class AnimationApplet extends javax.swing.JApplet { protected Point character1; protected Point character2; CharacterScript script1; CharacterScript script2; protected Animation animation; /** * cartoon contains the animation and the scripts for the characters running * in parallel */ protected ParallelCollection cartoon; public void start() { synchronized (JMSL.class) { initJMSL(); buildCharacters(); buildAnimation(); getContentPane().add(animation.getCanvas()); buildScripts(); buildCartoon(); startCartoon(); } } protected void initJMSL() { JMSL.clock = new DefaultMusicClock(); JMSL.clock.setAdvance(0.1); JMSL.scheduler = new EventScheduler(); JMSL.scheduler.start(); } private void buildAnimation() { animation = new Animation(); animation.addCharacter(character1); animation.addCharacter(character2); } private void buildCharacters() { character1 = new Point(100, 100); character2 = new Point(130, 130); } protected void buildScripts() { // a script to move character 1 around script1 = new CharacterScript(character1); script1.setRepeats(Integer.MAX_VALUE); script1.setRepeatPause(0.3); // a script to move character 2 around (note it's a different repeat // pause than character 1) script2 = new CharacterScript(character2); script2.setRepeats(Integer.MAX_VALUE); script2.setRepeatPause(0.15); } private void startCartoon() { cartoon.launch(JMSL.now()); } protected void buildCartoon() { cartoon = new ParallelCollection(); cartoon.add(animation); cartoon.add(script1); cartoon.add(script2); } public void stop() { synchronized (JMSL.class) { cartoon.finishAll(); try { cartoon.waitForDone(); } catch (InterruptedException e) { e.printStackTrace(); } JMSL.scheduler.stop(); JMSL.closeMusicDevices(); } } } /** * Animation is the "film" that runs at a constant frame rarte, repainting each * time. Other agent move their characters around in the animation by setting * their x,y positions. */ class Animation extends MusicJob { // characters are just Points in this example. Vector characters = new Vector(); JPanel canvas; public Animation() { setRepeats(Integer.MAX_VALUE); setRepeatPause(0.1); canvas = new JPanel() { // every time repaint() is called, render the position of each // character protected void paintComponent(Graphics g) { super.paintComponent(g); for (Enumeration e = characters.elements(); e.hasMoreElements();) { Point p = (Point) e.nextElement(); g.draw3DRect(p.x, p.y, 10, 10, false); } } }; canvas.setPreferredSize(new Dimension(200, 200)); } public void addCharacter(Point p) { characters.addElement(p); } public void removeCharacter(Point p) { characters.removeElement(p); } public JPanel getCanvas() { return canvas; } public double repeat(double playTime) { canvas.repaint(); return playTime; } } /** Updates x,y position of character over time */ class CharacterScript extends MusicJob { Point character; public CharacterScript(Point character) { this.character = character; } public double repeat(double playTime) { int xDelta = JMSLRandom.choose(-2, 3); int yDelta = JMSLRandom.choose(-2, 3); character.x += xDelta; character.y += yDelta; return playTime; } }