import java.awt.*; import java.applet.*; public class RoadApplet extends Applet implements Runnable { public void init() { canvas = new RoadCanvas(); slowdown = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 100); slowdown.setPageIncrement(10); slowdown.setValue(10); arrival = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 100); arrival.setPageIncrement(10); arrival.setValue(50); Panel p = new Panel(); p.setLayout(new GridLayout(1, 6)); p.add(new Label("Slowdown")); p.add(slowdown); p.add(new Label("")); p.add(new Label("Arrival")); p.add(arrival); p.add(new Label("")); setLayout(new BorderLayout()); add("North", p); add("Center", canvas); } public double getSlowdown() { return 0.01 * slowdown.getValue(); } public double getArrival() { return 0.01 * arrival.getValue(); } public void run() { for(;;) { canvas.update(getSlowdown(), getArrival()); try { Thread.sleep(50); } catch(InterruptedException e) {} } } public void start() { runner = new Thread(this); runner.start(); } private RoadCanvas canvas; private Scrollbar slowdown; private Scrollbar arrival; private Thread runner; } class RoadCanvas extends Canvas { public RoadCanvas() { freeway = new Road(); row = 0; } public void update(double slowdown, double arrival) { freeway.update(slowdown, arrival); if (buffer == null) { xsize = size().width; ysize = size().height; buffer = createImage(xsize, ysize); } Graphics bg = buffer.getGraphics(); freeway.paint(bg, row, XDOTDIST, DOTSIZE); if (row < ysize - 2 * DOTSIZE + 1) row += DOTSIZE; else { bg.copyArea(0, DOTSIZE, xsize, ysize - DOTSIZE, 0, -DOTSIZE); bg.clearRect(0, ysize - DOTSIZE, xsize, DOTSIZE); } bg.dispose(); repaint(); } public void paint(Graphics g) { if (buffer != null) g.drawImage(buffer, 0, 0, null); } public void update(Graphics g) { paint(g); } private final int DOTSIZE = 2; private final int XDOTDIST = 1; private Road freeway; private Image buffer; private int row; private int xsize; private int ysize; } class Road { public Road() { speed = new int[LENGTH]; colors = new Color[LENGTH]; for (int i = 0; i < LENGTH; i++) speed[i] = -1; } public void update(double prob_slowdown, double prob_create) { int i = 0; while(i < LENGTH && speed[i] == -1) i++; while (i < LENGTH) { if (Math.random() <= prob_slowdown && speed[i] > 0) speed[i]--; else if (speed[i] < MAXSPEED) speed[i]++; int inext = i + 1; while(inext < LENGTH && speed[inext] == -1) inext++; if (inext < LENGTH) { if (speed[i] >= inext - i) speed[i] = inext - i - 1; } if (speed[i] > 0) { if (i + speed[i] < LENGTH) { int ni = i + speed[i]; speed[ni] = speed[i]; colors[ni] = colors[i]; } speed[i] = -1; } i = inext; } if (Math.random() <= prob_create && speed[0] == -1) { speed[0] = (int)(5.99 * Math.random()); colors[0] = ++count % 10 == 0 ? Color.red : Color.black; } } public void paint(Graphics g, int row, int dotdist, int dotsize) { for (int i = 0; i < LENGTH; i++) { g.setColor(colors[i]); if (speed[i] >= 0) g.fillRect(i * dotdist, row, dotsize, dotsize); } } public static final int LENGTH = 400; public static final int MAXSPEED = 5; private int[] speed; private Color[] colors; private int count; }