rendered paste bodyimport java.awt.*;import java.awt.event.*;import java.util.Random;import java.util.Vector;class Simulator extends Frame implements ActionListener{ public static void main(String[] args) { new Simulator("Simulator"); } public static final int MAX_X = 700; public static final int MAX_Y = 700; public static final int START_RADIUS = 200; public static final int START_COUNT = 10; public static final int ATOM_RADIUS = 2; public static final int ATOM_DIAMETER = 2 * ATOM_RADIUS; public static final double SPEED_LOSS = -0.95; public static final double PERIOD_TIME = 0.001 * 2; public static final double START_GRAV_MULTI = 1; Vector<Atom> _atoms; Image _back; Graphics _gc; DrawArea _area; Gravity _grav; TextField _tf, _tf2; boolean _path = false; Simulator(String s) { super(s); setVisible(true); setResizable(false); addWindowListener(new MyWindowAdapter()); // === Button restart = new Button("Restart"); Button path = new Button("Path"); restart.addActionListener(this); path.addActionListener(this); Panel north = new Panel(); north.setLayout(new FlowLayout()); north.add(restart); north.add(path); add("North", north); // === _area = new DrawArea(); _area.addMouseListener(new MyMouseAdapter()); add("Center", _area); // === _tf = new TextField("0%",3); _tf2 = new TextField("0%",3); Panel south = new Panel(); south.setLayout(new FlowLayout()); south.add(new Label("Gravity")); south.add(new Label("x:")); south.add(_tf); south.add(new Label("y:")); south.add(_tf2); add("South", south); // === _grav = new Gravity(); setText(); pack(); } void setText() { int xx = (int)(200 * _grav._vx / _area.getWidth()); int yy = (int)(200 * _grav._vy / _area.getHeight()); _tf.setText(String.valueOf(xx) + "%"); _tf2.setText(String.valueOf(yy) + "%"); } class MyMouseAdapter extends MouseAdapter { public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); _grav._vx = x - _area.getCenterX(); _grav._vy = y - _area.getCenterY(); setText(); } } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Restart")) { _grav.init(); } else if (e.getActionCommand().equals("Path")) { _path = !_path; _area.clean(); } } class MyWindowAdapter extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } class DrawArea extends Canvas { int _centerX, _centerY; DrawArea() { setSize(MAX_X, MAX_Y); _centerX = getWidth() / 2; _centerY = getHeight() / 2; initBuffer(); } void initBuffer() { _back = Simulator.this.createImage(MAX_X, MAX_Y); Graphics gc = _back.getGraphics(); gc.setColor(Color.lightGray); gc.fillRect(0, 0, getWidth(), getHeight()); _gc = gc; } void draw() { getGraphics().drawImage(_back, 0, 0, this); } void clear() { _gc.setColor(Color.lightGray); _gc.fillRect(0, 0, getWidth(), getHeight()); } void clean() { initBuffer(); } void paint() { for (Atom a : _atoms) { _gc.setColor(a._color); _gc.fillOval(a.getDrawX(), a.getDrawY(), ATOM_DIAMETER, ATOM_DIAMETER); } _gc.setColor(Color.black); _gc.drawLine((int)(_area.getCenterX() + _grav._vx), (int)(_area.getCenterY() + _grav._vy), _area.getCenterX(), _area.getCenterY()); _gc.setColor(Color.white); _gc.fillOval(_area.getCenterX() - ATOM_RADIUS, _area.getCenterY() - ATOM_RADIUS, 6, 6); _gc.setColor(Color.black); _gc.drawOval(_area.getCenterX() - ATOM_RADIUS, _area.getCenterY() - ATOM_RADIUS, 6, 6); _gc.drawRect(0, 0, _area.getWidth() - 1, _area.getHeight() - 1); } int getCenterX() { return _centerX; } int getCenterY() { return _centerY; } } class Gravity extends Thread { double _vx, _vy; Gravity() { init(); start(); } void init() { _atoms = new Vector<Atom>(); for (int i = 0; i < START_COUNT; i++) { _atoms.add(new Atom()); } _vx = 0; _vy = (double)_area.getCenterY() * START_GRAV_MULTI; _area.clean(); } public void run() { int count = 0; long _update = 0; int _count = 0; for(;;) { if (_update + 1000 < System.currentTimeMillis()) { System.out.println(_count + 1); _update = System.currentTimeMillis(); _count = 0; } else { _count++; } try { if (!_path) _area.clear(); } catch (Exception e) { } try { moveAtoms(); } catch (Exception e) { } try { _area.paint(); } catch (Exception e) { } if (count == 20) { _area.draw(); count = 0; } else { count++; } waiter(1); } } long _lastCall = System.currentTimeMillis(); void waiter(long time) { while(_lastCall > System.currentTimeMillis()) { try { sleep(0,1); } catch (Exception e) { } } _lastCall += time; } void moveAtoms() { for(Atom a : _atoms) { a.move(); } } } /*static Color[] _colors = { Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, //Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW, };*/ class Atom { double _x, _y, _vx, _vy; Color _color; Atom() { int x = 0; int y = 0; for(;;) { x = (int)((Math.random() * 2 - 1) * 200); y = (int)((Math.random() * 2 - 1) * 200); if (x * x + y * y < START_RADIUS * START_RADIUS) break; } _x = _area.getCenterX() + x; _y = _area.getCenterY() + y; _vx = x; _vy = y; //_color = _colors[new Random().nextInt(_colors.length)]; _color = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256)); } int getDrawX() { return (int)_x - ATOM_RADIUS; } int getDrawY() { return (int)_y - ATOM_RADIUS; } void move() { int x = (int)_x; int y = (int)_y; if ((x <= ATOM_RADIUS && _vx < 0) || (_area.getWidth() - x <= ATOM_RADIUS && 0 < _vx)) _vx *= SPEED_LOSS; if ((y <= ATOM_RADIUS && _vy < 0) || (_area.getHeight() - y <= ATOM_RADIUS && 0 < _vy)) _vy *= SPEED_LOSS; _x += _vx * PERIOD_TIME; _y += _vy * PERIOD_TIME; _vx += _grav._vx * PERIOD_TIME; _vy += _grav._vy * PERIOD_TIME; } }}