0
プログラム
ボールとボールの接触(当たって反射するかんじ)を行わせるにはどのようなプログラムを追加したらよいでしょうか?
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Fall {
public static void main(String[] args) {
FallPane fallPane = new FallPane();
JFrame frame = new JFrame("落ちてくる玉を拾え");
frame.setSize(400, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(fallPane);
frame.setVisible(true);
}
}
abstract class AbstractFallBall {
private Point location;
private Dimension size;
private double verticalAccel;
private double horizontalAccel;
public AbstractFallBall() {
location = new Point(0, 0);
size = new Dimension(0, 0);
}
public int getX() {
return location.x;
}
public int getY() {
return location.y;
}
public int getWidth() {
return size.width;
}
public int getHeight() {
return size.height;
}
public void setBounds(Rectangle value) {
location = value.getLocation();
size = value.getSize();
}
public Rectangle getBounds() {
return new Rectangle(location, size);
}
public void setLocation(Point value) {
location = value;
}
public Point getLocation() {
return new Point(location);
}
public void setSize(Dimension value) {
size = value;
}
public Dimension getSize() {
return new Dimension(size);
}
public void setVerticalAccel(double value) {
verticalAccel = value;
}
public double getVerticalAccel() {
return verticalAccel;
}
public void setHorizontalAccel(double value) {
horizontalAccel = value;
}
public double getHorizontalAccel() {
return horizontalAccel;
}
public abstract void paintBall(Component target, Graphics g);
}
class DefaultFallBall extends AbstractFallBall {
private Color color;
public DefaultFallBall() {
color = Color.BLACK;
}
public void setColor(Color value) {
color = value;
}
public Color getColor() {
return color;
}
public void paintBall(Component target, Graphics g) {
Rectangle rect = getBounds();
g.setColor(color);
g.fillOval(rect.x, rect.y, rect.width, rect.height);
}
}
class BallController implements Runnable {
private FallPane fallPane;
private AbstractFallBall fallBall;
private Thread thread;
private int sleepTime;
private boolean stoped;
public BallController(FallPane fallPane, AbstractFallBall fallBall) {
this.fallPane = fallPane;
this.fallBall = fallBall;
sleepTime = 10;
}
public void setSleepTime(int value) {
sleepTime = value;
}
public int getSleepTime() {
return sleepTime;
}
public void start() {
if (thread != null && thread.isAlive()) {
throw new IllegalStateException();
}
stoped = false;
thread = new Thread(this);
thread.start();
}
public void stop() {
stoped = true;
}
public void run() {
while (!stoped) {
try {
Thread.sleep(getSleepTime());
} catch (Exception e) { }
// ボールを移動
Rectangle ball = fallBall.getBounds();
ball.x += fallBall.getHorizontalAccel();
ball.y += fallBall.getVerticalAccel();
fallBall.setVerticalAccel(fallBall.getVerticalAccel() + 0.1);
// バーとボールの中央位置を算出
Rectangle bar = fallPane.getBarBounds();
int barCenter = bar.x + bar.width / 2;
int ballCenter = ball.x + ball.width / 2;
// 当たり判定
if (bar.intersects(fallBall.getBounds())) {
ball.y = bar.y - ball.height;
fallBall.setVerticalAccel(-(fallBall.getVerticalAccel() * 0.8));
fallBall.setHorizontalAccel(-((barCenter - ballCenter) * 0.1));
} else if (ball.y > fallPane.getHeight()) {
break;
}
// ボールが画面の端に衝突した
if (ball.x < 0 || (ball.x + ball.width) > fallPane.getWidth()) {
fallBall.setHorizontalAccel(-fallBall.getHorizontalAccel());
}
fallBall.setBounds(ball);
fallPane.repaint();
}
fallPane.removeFallBall(fallBall);
}
}
// ウィンドウに表示されるゲーム画面
// JComponentを継承,MouseMotionListenerとMouseListenerとComponentListenerを実装するクラスFallPaneの定義
class FallPane extends JComponent implements MouseMotionListener, MouseListener, ComponentListener {
private Vector<AbstractFallBall> balls;
private Rectangle bar;
private Random random;
public FallPane() { // コンストラクタ
bar = new Rectangle(0, 0, 100, 20);
balls = new Vector<AbstractFallBall>();
random = new Random();
addComponentListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
// 指定されたボールを追加する
public void addFallBall(AbstractFallBall fallBall) {
balls.add(fallBall);
BallController ballctrl = new BallController(this, fallBall);
ballctrl.start();
}
public AbstractFallBall getFallBall(int index) {
return balls.get(index);
}
public void removeFallBall(AbstractFallBall fallBall) {
balls.remove(fallBall);
}
public void removeFallBall(int index) {
balls.remove(index);
}
public Rectangle getBarBounds() {
return new Rectangle(bar);
}
// コンポーネントイベントによって実行されるメソッド
public void componentHidden(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {}
public void componentResized(ComponentEvent e) {
bar.y = getHeight() - bar.height * 2;
repaint();
}
public void componentShown(ComponentEvent e) {}
// マウスイベントによって実行されるメソッド
// クリックするとボールを増やす
public void mouseClicked(MouseEvent e) {
DefaultFallBall ball = new DefaultFallBall();
Dimension dim = new Dimension(20, 20);
int diff = getWidth() - dim.width;
int x = random.nextInt(diff);
int y = dim.height;
Point pt = new Point(x, y);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
Color color = new Color(r, g, b);
ball.setColor(color);
ball.setLocation(pt);
ball.setSize(dim);
ball.setVerticalAccel(1.0);
ball.setHorizontalAccel(1.0);
addFallBall(ball);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
// マウスモーションイベントによって実行されるメソッド
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {
int x = e.getX() - (bar.width / 2);
if (x < 0) {
bar.x = 0;
} else if (x + bar.width > getWidth()) {
bar.x = getWidth() - bar.width;
} else {
bar.x = x;
}
repaint();
}
public void paintComponent(Graphics g) {
g.fillRect(bar.x, bar.y, bar.width, bar.height);
for (AbstractFallBall ball : balls) {
ball.paintBall(this, g);
}
}
}