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)
}
개인 도구
이름공간
변수
행위
둘러보기
구성원
연구
연구실
기타
도구모음
인쇄/내보내기