クリック先に移動

 クリックした地点にボールが移動する・クリックした瞬間に方向を変えられる、ように改造した。
 もともとこの動作をさせるために配列に位置情報を入れるプログラムをこれまで考えていたのだが、いざ作ってみると配列など不要だった。


import java.awt.event.* ;
import javax.swing.* ;
import java.awt.Graphics ;
import java.awt.Color ;

public class MovaBall2 extends JPanel
implements MouseListener {
static int myX = 300;
static int myY = 150;
static int myTerminusX = 200;
static int myTerminusY = 150;
static int myVX = 0;
static int myVY = 0;
static int r = 20; // 円の半径
final static Color bc = Color.green; // 背景色
public MovaBall2() {
addMouseListener(this);
setBackground(bc);
}//this
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(255,255,255));
g.fillOval(myX-r,myY-r,r*2,r*2);
}
public void mouseClicked(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) {
myTerminusX = e.getX();
myTerminusY = e.getY();
}
public void mouseReleased(MouseEvent e) { }
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { System.exit(0); }
});
frame.getContentPane().add( new MovaBall2() );
frame.setSize(400,300);
frame.setVisible(true);
while(true){
myX = myX + myVX;
if(myTerminusX == myX){
myVX = 0;
}else{
myVX = (myTerminusX - myX)/50
+(myTerminusX - myX)/Math.abs(myTerminusX - myX);
}
myY = myY + myVY;
if(myTerminusY == myY){
myVY = 0;
}else{
myVY = (myTerminusY - myY)/50
+(myTerminusY - myY)/Math.abs(myTerminusY - myY);
}
try{
Thread.sleep(20);
}catch(InterruptedException ee){
}
frame.repaint();
}
}
}


 うまく動作してくれた。
 目的地にきちんと着地・停止させるのが意外に難しい。おかげで座標計算が非常に見苦しい形になったし、挙動も少々おかしい。その元凶は終点近くでの速度が1以下になってしまうのを避けるためヘンな式にしているからで、別に1式で実現しなくても場合分けで速度を定義すればいいのだろうが、面倒なので(式をいじくり回すほうが面倒だった気がするが)、不恰好だがとりあえずこれで良しとする。
 技術とはこういう所に現れるのだろう。


 うまくいかない原因は自分の腕なので、今日も怒らずに終わる。