Report8

    
オリジナルのJavaアプレットを作れ。

     <<もぐらたたきゲーム>>
// mole
// もぐらたたきゲーム

import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.lang.*;


public class mole2 extends java.applet.Applet implements Runnable {

    MediaTracker mt;

    Image pict[] = new Image[4] ; // 穴やもぐらの絵を入れる配列

    int speed = 800; // もぐらを出すスピード
    int time; // もぐらが出る回数
    int mole; // もぐらが出てくる穴の番号
    int score; // 点数
    int card[] = new int[12]; // 表示する絵(番号)を入れる配列
    int x[] = new int[12]; // 穴の位置(x座標)
    int y[] = new int[12]; // 穴の位置(y座標)
    int cardWidth = 32, cardHeight = 32; // 穴の絵の幅、高さ

    Thread kicker = null;     // アニメーションのためのスレッド変数

    Dimension d;  // 表示領域
    Image  offs;  // オフスクリーン
    Graphics grf;

    public void init(){
        int i ,j; // カウンター
        int k; // カード番号
        int yy; // 段毎のy座標

        mt = new MediaTracker(this);

        /* イメージファイルの読み込み */
        for( i = 0 ; i < 4 ; i++ ){
            pict[i] = getImage(getCodeBase(), "img" + (i) + ".gif");
            mt.addImage(pict[i],0);
        }


        /* 絵の位置(x、y座標)の設定 */
        k = 0;
        for( i = 0 ; i < 3 ; i++ ){
            yy = i * cardHeight + 5;
            for( j = 0 ; j < 4 ; j++ ){
                x[k] = j * cardWidth + 5;
                y[k] = yy;
                k = k + 1;
            }
        }


        /* オフスクリーンの設定 */
        d = size(); // 表示領域の取得
        offs = createImage( d.width, d.height);
        grf  = offs.getGraphics();
        /* 変数の初期化 */
        time = -1; // もぐらの出る回数をセット
        score = 0; // 点数のリセット
        for( i = 0 ; i < 12 ; i++ ){
            card[i] = 0; // すべて穴だけの状態に戻す
        }
    }

    public void paint(Graphics g) {
        update(g);
    }

    public void update(Graphics g){
        int i; // カウンター

        /* 読み込み中メッセージの表示 */
        if (mt.checkID(0) == false) {
            g.setColor(Color.black);
            g.fillRect(0, 0, d.width, d.height);
            g.setColor(Color.yellow);
            g.setFont(new Font("TimesRoman", Font.PLAIN, 14));
            g.drawString("Loading...", 40, 50);
            return;
        }


        /* バックをオレンジで塗る */
        grf.setColor(Color.orange);
        grf.fillRect(0,0,223,106);

        /* タイトルの描画 */
        grf.setColor(Color.red);
        grf.drawString("MOGU! MOGU!", 138, 20);

        /* カードの描画 */
        for( i = 0 ; i < 12 ; i++ ){
            /* セットされている絵を描く */
            grf.drawImage( pict[card[i]], x[i], y[i], this);
        }

        /* STARTボタンの描画 */
        grf.setColor(Color.green);
        grf.fillRect( 138, 70, 65, 25 );
        grf.setColor(Color.black);
        grf.drawString("START", 150, 88);

        /* 点数の表示 */
        grf.setColor(Color.black);
        grf.drawString("Score : "+score, 142, 40);
        grf.setColor(Color.blue);
        if ( time == 0 ) {
            /* 点数によってメッセージを出力 */
            if ( score >= 35 ) {
                grf.drawString("I'm crazy for you!", 142, 60);
            } else {
                if ( score >= 25 ) {
                    grf.drawString("Great!!!", 142, 60);
                } else {
                    grf.drawString("good!", 142, 60);

                }
            }
        } else {
            if ( time > 0 ) {
                /* 残り時間の表示 */
                grf.drawString("time", 142, 55);
                for( i = 0 ; i < time ; i++ ){
                    grf.drawString("|", 142+i, 65);
                }
            }
        }

        /* オフスクリーンのイメージを一挙に実際の表示領域に描く */
        g.drawImage(offs, 0, 0, this);

    }

    public boolean mouseDown(java.awt.Event evt, int ix, int iy){
        int i; // カウンター
        int row, col; // マウスが押された位置(行、列)
        int nn; // マウスが押された穴の番号

        if ( ix > 138 & ix < 203 & iy > 70 & iy < 95 ) {
          /* マウスの座標(ix,iy)がSTARTボタン内 */
            /* だったら穴の絵をセットし直す     */
            stop();
            gameStart();
            repaint();
            return true; // このメソッドを抜ける
        }

        /* マウスで何列目が押されたか */
        col = 0;
        if( ix > cardWidth + 5  ) col = 1;
        if( ix > cardWidth * 2 + 5 ) col = 2;
        if( ix > cardWidth * 3 + 5 ) col = 3;
        if( ix > cardWidth * 4 + 5 ) col = -1;
        if( col < 0 ) return true; // 穴の無い場所だったらこのメソッドを
        抜ける

        if ( time == 0 ) return true;

        /* マウスで何行目が押されたか */
        row = 0;
        if( iy > cardHeight + 5 ) row = 1;
        if( iy > cardHeight * 2 + 5 ) row = 2;
        if( iy > cardHeight * 3 + 5 ) row = -1;
        if( row < 0 ) return true; // 穴の無い場所だったらこのメソッドを
        抜ける

        /* 穴の番号の計算 */
        nn = row * 4 + col;

        if ( mole == nn ) {
            score = score + 1; // 点数を加算
            card[nn] = 3; // 叩かれているもぐらの絵(番号)をセット


        } else {
            card[nn] = 2; // トンカチの絵(番号)をセット

        }

        repaint(x[nn], y[nn], 32, 32);

        return true;
    }

    public void start() {
        if(kicker == null) {
            /* スレッドを実行させる */
            kicker = new Thread(this);
            kicker.start();
        }
    }
    public void stop() {
        /* スレッドを止める */
        if ( kicker != null ) {
            kicker.stop();
            kicker = null;
        }


    }

    public void run() {
        int i;

        /* 全てのイメージの読み込みを待つ */
        try{
            mt.waitForID(0);
        } catch (InterruptedException e) {
            return;
        }

        /* timeが0になるまで繰り返し */
        while( time > 0) {
            /* 乱数でもぐらが出る穴を決める */
            mole = (int)( Math.random() * (float)(12) );
            card[mole] = 1;

            /* 再描画 */
           repaint();

            try{
                Thread.sleep(speed);
            } catch (InterruptedException e){}

            for( i = 0 ; i < 12 ; i++ ){
                card[i] = 0; // すべて穴だけの状態に戻す
            }

            time = time -1; // 残りの回数を減らす
        }

        repaint();
    }

    public void gameStart(){
        int i;
        /* 変数の初期化 */
        time = 40; // もぐらの出る回数をセット
        score = 0; // 点数のリセット
        for( i = 0 ; i < 12 ; i++ ){
            card[i] = 0; // すべて穴だけの状態に戻す
        }
        start();
    }
}


考察

       for( i = 0 ; i < 4 ; i++ ){
            pict[i] = getImage(getCodeBase(), "img" + (i) + ".gif");
            mt.addImage(pict[i],0);
        }
 作成した描画を読み込んでいます。  描画は穴だけの絵、もぐらが出てくる絵、トンカチの絵、もぐらが叩かれている絵の4種類です。
       public void run() {
        int i;

        /* 全てのイメージの読み込みを待つ */
        try{
            mt.waitForID(0);
        } catch (InterruptedException e) {
            return;
        }

        /* timeが0になるまで繰り返し */
        while( time > 0) {
            /* 乱数でもぐらが出る穴を決める */
            mole = (int)( Math.random() * (float)(12) );
            card[mole] = 1;

            /* 再描画 */
           repaint();

            try{
                Thread.sleep(speed);
            } catch (InterruptedException e){}

            for( i = 0 ; i < 12 ; i++ ){
                card[i] = 0; // すべて穴だけの状態に戻す
            }

            time = time -1; // 残りの回数を減らす
        }

        repaint();
    }
 このrunメソッドでは基本的なルールの設定をしています。 mouseDownとは  これはマウスが押された、というイベントに対しての処理を表します。  このプログラムではどの穴が叩かれたかの判定をします。 gameStartメソッド  このメソッドでは、4つの機能があります。   1、変数の初期化   2、モグラの出る回数をセット   3、点数のリセット   4、すべて穴だけの状態に戻す Graphicsクラス  タイトルやスタートボタンを表示するには数多くのGraphicsクラスが使われている。
メソッド意味
drawImage(Image img,int x,inty,ImageObsever io) 座標x,yに左上隅が配置されるようにイメージimgを描画する。描画処理の進行状況は、ioに送られる
drawRect(int x,int y,int w,int h) 座標x,yに左上隅が配置される幅w,高さhの四角形を描画する
drawString(String str,int x,int y)strを座標x,yに描画する
setColor(Color c)グラフィックコンテキストの現在のカラーとしてcを設定する
setFont(Font f)現在のオブジェクトのフォントとしてfを設定する
Color getColor()現在のオブジェクトのカラーを取得する
Font getFont()現在のオブジェクトのフォントを取得する
FontMetrics getFontMetrics()現在のオブジェクトのフォントメトリックスを取得する
Dimensionコンストラクタ Dimension() Dimension(Dimension d) Dimension(int w,int h)  dはDimensionオブジェクトです。wは幅、hは高さを表すピクセル値です。いずれも省略すると幅、高さ0を指定したものと見なされます。このクラスには、int型の インスタンス変数widthとheightがあります。 getImage()メソッド Image getImage(URL ur1) Image getImage(URL base, String fileName)  1つ目の形式では、イメージリソースを表す絶対URLを引数として受け取ります。  2つ目の形式では、イメージファイルをダウンロードするベースのURLを1つ目の引数として受け取り、目的のファイル名を2つ目の引数として受け取ります。 Componentクラス
メソッド意味
createImage(int width,int height) 幅width、高さheightのImageオブジェクトを返す
Font getFont()現在のフォントを返す
void repaint() JVMに対して、update()メソッドの呼び出しを要求する
public void update(Graphics g) コンポーネントを背景色で塗りつぶしてpaint()メソッドを呼び出す
Appletクラス
メソッド意味
void destroy()アプレットを破棄する
getCodeBase()コードベースを返す
void init()アプレットを初期化する
void start()アプレットを起動する
void stop()アプレットを停止する
ダブルバッファリング  update()メソッドの規定の実装では、ウィンドウ全体を背景色で塗りつぶして消去する。その後で、paint()メソッドを呼び出してアプレットの出力を表示して います。しかし、これは見苦しい「ちらつき」の原因となります。ウィンドウがちらついて見えるのは、1色による全面の塗りつぶしと別の色にとる描画が頻繁に行 われるからである。その「ちらつきを」防ぐのがダブルバッファリングという手法である。 ↓↓↓<もぐらたたきゲーム>↓↓↓ o o o o
o o o o
o o o o

このゲームはJavaが動くブラウザでお楽しみいただけます。

 
感想・反省
  今回のレポートはゲームをつくるということで楽しく出来ました。ほとんどが
 オリジナルのものではありませんが、こういう風につくるんだぁと新たな発見
 がたくさんあったレポートでした。春休みになったらもっとゲームを作って
今年の琉大祭で自分の作ったゲームで出てみたいなと思いました。

参考文献
・第2版 独習Java ジョゼフ・オニール著
・たまじゃば http://www.horae.dti.ne.jp/~yoji/TamaJava/Chapter6/frame.html