RandomBallsTimer
Retired DISLab
RandomBallsTime.java
import acm.program.*; import acm.util.*; import acm.graphics.*; import java.awt.event.*; import java.util.*; public class RandomBallsTimer extends GraphicsProgram { @Override public void init() { addMouseListeners(); addMouseMotionListener(this); addKeyListeners(); } @Override public void run() { terminated = false; ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { moveOneStep(); } }; SwingTimer timer = new SwingTimer(TIMER_RATE, listener); timer.start(); } public void moveOneStep() { if (clear) { removeAll(); clear = false; } if (reserved2Remove != null) { remove(reserved2Remove); reserved2Remove = null; } if (!paused) moveObjects(); } @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_Q : shutdown(); break; case KeyEvent.VK_P : paused = !paused; break; case KeyEvent.VK_C : clear = true; break; case KeyEvent.VK_N : createRandomBall(); break; } } @Override public void mousePressed(MouseEvent e) { createRandomBall(); } @Override public void mouseMoved(MouseEvent e) { if (reserved2Remove == null) reserved2Remove = getElementAt(e.getX(), e.getY()); } private void createRandomBall() { double w = random.nextDouble(MIN_SIZE, MAX_SIZE); GDimension vec = new GDimension(random.nextDouble(MIN_VELOCITY, MAX_VELOCITY), random.nextDouble(MIN_VELOCITY, MAX_VELOCITY)); double dx = random.nextDouble(w, getWidth() - w); double dy = random.nextDouble(w, getHeight() - w); GMovingBall ball = new GMovingBall(w, vec, dx, dy); ball.setColor(random.nextColor()); add(ball); } public void moveObjects() { Iterator<GObject> it = this.iterator(); while (it.hasNext()) { GObject gobj = it.next(); if (gobj instanceof GMovingBall) { GMovingBall ball = (GMovingBall)gobj; double r = ball.getWidth() / 2; boolean directionIsChanged = false; double vecX = ball.getVectorX(); double nextX = ball.getX() + vecX; double wallX = getWidth() - r; if (nextX >= wallX || nextX <= r) { if (nextX >= wallX) { nextX = wallX - (nextX - wallX); } else { nextX = (nextX < 0) ? r - nextX : r + (r - nextX); } vecX = -vecX; directionIsChanged = true; } double vecY = ball.getVectorY(); double nextY = ball.getY() + vecY; double wallY = getHeight() - r; if (nextY > wallY || nextY < r) { if (nextY > wallY) { nextY = wallY - (nextY - wallY); } else { nextY = (nextY < 0) ? r - nextY : r + (r - nextY); } vecY = -vecY; directionIsChanged = true; } if (directionIsChanged) { ball.setVector(vecX, vecY); } ball.setLocation(nextX, nextY); } } } private void shutdown() { terminated = true; removeAll(); } /* Private static final constants */ private static final long MIN_SIZE = 1; private static final long MAX_SIZE = 50; private static final long MIN_VELOCITY = -10; private static final long MAX_VELOCITY = 10; private static final int TIMER_RATE = 20; //private ArrayList arr = new ArrayList(); private boolean terminated = false; private boolean paused = false; private boolean clear = false; private GObject reserved2Remove = null; private RandomGenerator random = RandomGenerator.getInstance(); public static final long serialVersionUID = 1; }
GBall.java
- 이 부분의 본문은 GBall.java입니다.
/* * File: GBall.java * ---------------- * This file defines a GObject class that represents a ball. */ import acm.graphics.*; /** * This class defines a GCompound subclass that represents a ball * whose reference point is the center rather than the upper * left corner. */ public class GBall extends GCompound { /** Creates a new ball with radius r centered at the origin */ public GBall(double r) { radius = r; ball = new GOval(2 * radius, 2 * radius); ball.setFilled(true); add(ball, -radius, -radius); markAsComplete(); } /** Creates a new ball with radius r centered at (x, y) */ public GBall(double r, double x, double y) { this(r); setLocation(x, y); } public void setRadius(double r) { ball.setSize(r * 2, r * 2); } public double getRadius() { return radius; } /* public void setSize(double r) { ball.setSize(r, r); } public double getWidth() { return ball.getWidth(); } public double getHeight() { return ball.getHeight(); } */ private GOval ball; private double radius; }
GMovingBall.java
- 이 부분의 본문은 GMovingBall입니다.
import acm.graphics.*; public class GMovingBall extends GBall { /** Creates a new ball with radius r centered at the origin * @param w Weight of this ball (radius) * @param vecX x 축 방향의 벡터 크기 * @param vecY y 축 방향의 벡터 크기 */ public GMovingBall(double weight, GDimension vec) { super(weight); vector = new GDimension(vec); } /** Creates a new ball with radius r centered at (x, y) */ public GMovingBall(double weight, GDimension vec, double x, double y) { this(weight, vec); setLocation(x, y); } public GDimension getVector() { return new GDimension(vector); } public double getVectorX() { return vector.getWidth(); } public double getVectorY() { return vector.getHeight(); } public void setVector(GDimension vector) { this.vector = vector; } public void setVector(double dx, double dy) { vector.setSize(dx, dy); } private GDimension vector; // vector(dx, dy) }