dx,dy共に0でない値を持てば、斜めに動きます。
縦の壁で跳ね返る場合、dy を変化させずに dx を反転させます。天井と床で跳ね返る場合、dx を変化させずに dy を反転させます。
blueボタンをクリックしたら斜めに動くか縦横に動くか入れ替わることにします。
具体的には dx, dyにdの平均2倍程度の値を乱数で求めて代入します
AnimeDisk7.javaをもとに変更していきます。
(1)〜(4)の4箇所を変更します。
(1) MyPanelクラスのフィールドに isnaname (斜めだよ)という変数を宣言し、初期値をfalseにします。
class MyPanel extends JPanel{ BufferedImage buffimg; Graphics2D bfg; Color bgcolor= new Color(255,255,191); //背景の色 int greenct = 0; boolean isnaname = false;
(2) actionPerformed()の青ボタンの内容を変更します。「!」はtrueとfalseを反転させるということです。
//イベント処理 @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == rbtn) { //mypnl.moveDisk(); //●を描くメソッド MoveDisk disk = new MoveDisk(mypnl); disk.start(); } if (e.getSource() == gbtn) { //mypnl.drawToBuff('g'); mypnl.greenct++; } if (e.getSource() == bbtn) { //mypnl.drawToBuff('b'); mypnl.isnaname = ! mypnl.isnaname; } }
(3) MoveDiskクラスのフィールドにも isnaname (斜めだよ)という変数を宣言し、コンストラクタではパネルの現在の状態を取り込むようにします。(これはfalseにしておくのが順当かもしれません)
また、run()メソッドの中にパネルのnanameのモードが変わったら追随する部分を加えます。長くなりそうなのでsetNaname();とresetNaname();のメソッドを作って実際の部分はそこに書きます。
class MoveDisk extends Thread { int x; int y; int d, dx, dy ; int xmax, ymax; Graphics2D thg; MyPanel mypnl; BufferedImage buffimg; int greenct = 0; boolean isnaname; public MoveDisk(MyPanel mypnl) { this.mypnl = mypnl; this.buffimg = mypnl.buffimg; thg = buffimg.createGraphics(); thg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); xmax = buffimg.getWidth(); ymax = buffimg.getHeight(); x = (int)(xmax*Math.random()); y = (int)(ymax*Math.random()); d = xmax/40; //円の大きさ 10 dx = 0; dy = ymax/40; //動きの大きさ 10 this.greenct = mypnl.greenct; this.isnaname = mypnl.isnaname; } @Override public void run() { while ( true ){ thg.setColor(mypnl.bgcolor); thg.fillRect(x-d/2,y-d/2,d,d); if ( greenct != mypnl.greenct ) { int tmp = dx; dx = dy; dy = tmp; greenct = mypnl.greenct; } if ( isnaname != mypnl.isnaname ) { if (mypnl.isnaname==true) { setNaname(); } else { resetNaname(); } isnaname = mypnl.isnaname; } x+=dx; if (x >xmax){ x = 2*xmax-x; dx = -dx; } 以下略
(4) setNaname();とresetNaname();のメソッドは run()メソッドのあとに加えます。
setNaname()メソッドは
dの平均2倍程度の値を乱数で求めてdxに代入する
dの平均2倍程度の値を乱数で求めてdyに代入する
はたらきをします。
void setNaname(){ dx = (int)( d* 4 * Math.random()-d*2 ); dy = (int)( d* 4 * Math.random()-d*2 ); }
resetNaname()メソッドは 50%の確率で横か縦に進むようにします。速度は元のdになります。。
void resetNaname(){ if (Math.random()>0.5){ dx = d; dy = 0; }else{ dx = 0; dy = d; } }
blueボタンを上記の様に働くようにし、動作を確認しなさい。