円(ボール)を1個に限定する

解決策2

ボールが複数ある時に出るdx,dyをグローバル変数にしたことによる問題の解決策その2。

ボールが1個であれば問題ありません。1つある時にはボタンを押せないようにします。

moveDisk

MoveDisk7.javaをもとに変更するように説明しますが、MoveDisk6.javaからでもできます。

ファイル名 MoveDisk8.java の一部

actionPerformedに書き加えます。setEnabled(false)がボタンを押せなくするメソッド。setText("busy")がボタンの表示を変えるメソッドで、busyに変えて押せなくしていることを知らせます。


//イベント処理
@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == rbtn) {
        rbtn.setEnabled(false);
        rbtn.setText("busy");
        Thread thread = new moveDisk(mypnl,buffimg);
        thread.start();

ゲーム性を取り入れる

1つになってしまうとつまらないので、このボールを障害物にあてて消していくゲームにしたてます。

moveDisk

障害物を複数作れるようにTargetというクラスで表し、配列にします。

ファイル名 MoveDisk8.java の一部

これもインナークラスとして、moveDiskのあとにつなげましょう。

}//end of class moveDisk
class Target{
    int x;   //x位置
    int y;   //y位置
    boolean cleared = false;   //クリアされたかどうか
    public Target(int w,int h){
       x = (int)(w*Math.random());
       y = (int)(h*Math.random());
    }
}//end of class Target

MoveDisk8のフィールドにこの配列を加えます。tmaxは障害物の数をあとで変更できるように導入しました。

int tmax = 4;
Target[] ts = new Target[tmax];

障害物は配置される四角の大きさが決まってから作る必要があります。movdDiskのコンストラクタの中がいいでしょう。

public moveDisk(MyPanel pn, BufferedImage im) {
    this.pnl   = pn;
    this.image = im; 
    y = (int)(image.getHeight()*Math.random());
    int w = image.getWidth();
    int h = image.getHeight();
    for(int i=0 ; tmax>i ; i++){
        ts[i] = new Target(w,h);
    }
}

画面に書くのはスタートボタンを押したときにします。

public void run() {
    Graphics thg = image.createGraphics();
    Color bc= new Color(255,255,191);  //背景の色 
    thg.setColor(Color.blue);
    for(int i=0 ; tmax>i ; i++){
        if (ts[i].cleared) continue;
        thg.fillOval(ts[i].x-d/2,ts[i].y-d/2,d,d);            
    }
    //thg.setColor(Color.red);
    //thg.drawString(getName(),x-90,y);  //文字はいらない
    while ( true  ){

衝突判定

ボールが通ったところが背景色になりますから、ぶつかっても半分削れるだけという現象が起こります。また、すべてクリアしたときに何かの動作を起こすためにも衝突判定が必要です。

runメソッド中のボールを動かしているwhile内に置かなければなりません。


while ( true  ){
   // .......ここにdx,dyの交換処理があります............
   thg.setColor(bc);
   thg.fillOval(lx-d/2,ly-d/2,d,d);
   for(int i=0 ; tmax>i ; i++){
       if (ts[i].cleared) continue;
       if (d/2>Math.abs(ts[i].x-x)){
           if (d/2>Math.abs(ts[i].y-y)){
              ts[i].cleared = true;
              thg.fillOval(ts[i].x-d/2,ts[i].y-d/2,d,d);
              //clct++;
           }
       }
   }
   thg.setColor(Color.red);
   thg.fillOval(x-d/2,y-d/2,d,d);            

終了処理

たとえば上記のclctでクリア数を数えておき、tmaxとおなじになったらそのむねを表示する様にします。

このとき、同時にクリックした回数や、壁に跳ね返った数を別々に、あるいはその合計数をも表示する様に工夫します。この数を少なくすることを競うゲームとします。

if (clct==tmax) {
    thg.drawString("Cleared",getSize().width/2, getSize().height/2); 
    //クリック回数、壁に衝突した回数の表示を加える
}

moveDisk

課題

1.

MoveDisk7.javaをもとにします

上記の様に働くようにし、動作を確認しなさい。

ファイル名 MoveDisk8.java

もくじ

聖愛高等学校
http://www.seiai.ed.jp/
Last Modified