ひっきぃのメモ帳

趣味で作るプラモデル製作の過程と作品、日々の資格取得へ向けての活動、Apple中心のIT関連ネタを書いています。

[]第8回 イベント処理











 第7回では、キー操作のサンプルと簡単なイベント処理について説明しました。
 第8回 では、このイベント処理のパターンを紹介します。

 第7回のプログラムは、何かキー操作が発生したときに、 processEvent でイベントを受け取って処理を開始します。この形式の処理を、イベント駆動型(イベントドリブン)と呼ばれています。iアプリではなくても、この形式のプログラムは多いので覚えておいて損はないでしょう。イベント駆動型では、イベントが発生した時だけプログラムが動作します。
 

イベント発生→イベント処理→描画処理呼び出し
 
 ところが、リアルタイムに動くようなゲームを作りたい場合は、もっと正確にタイミングを取りたい場合もあります。そんな時によくつかわれるのがフロー駆動型のプログラミングです。他の処理のことをあまり考えないので、構成はシンプルになることが多いかもしれませんが、常にプログラムが動作しているので携帯電話であれば電池の消耗が早いかもしれません。
    
キーチェック→必要な処理→描画処理→キーチェック→…

    public void start() {
        MainCanvas mc = new MainCanvas();
        Display.setCurrent((Frame)(mc));
        mc.exe();
    }
 呼び出し方が、イベント駆動型とは少し違っています。キャンバスを表示した後に、自分でプログラムを起動します。
   mc.exe( ); で MainCanvasの中に書いた exe( )を呼び出します。
 
 一方呼び出される方の、MacinCanvasではこのexe()の中にプログラムを書かなければいけません。

void exe()
{
     while(true) {
           int key = keyCheck()   // キーチェック
           process(key);          // 必要な処理
           paint(getGraphics());  // 画面描画
     }
}
基本はこんな形になります。 while(true) で無限に繰り返しを行います。
 
この中身は続きを…

この繰り返しの中にすべてを記述しても、もちろん動作します。しかし、プログラムが大きくなると見にくくなってきますので、メソッドに分けて書いていくことにしましょう。
 
キーチェックのメソッド

int keyCheck() {     // 押されたキーを調べて、その値を返します。
        int k=getKeypadState();
        if((k & (1<<Display.KEY_SOFT1))!=0) {
            return Display.KEY_SOFT1;
        }
        if((k & (1<<Display.KEY_LEFT))!=0) {
            return Display.KEY_LEFT;
        }
        if((k & (1<<Display.KEY_RIGHT))!=0) {
            return Display.KEY_RIGHT;
        }
        if((k & (1<<Display.KEY_UP))!=0) {
            return Display.KEY_UP;
        }
        if((k & (1<<Display.KEY_DOWN))!=0) {
            return Display.KEY_DOWN;
        }
        return 0;
}
 processEvent で処理するときと違って、直接値を比較できません。同時に押されたキーも判定できるようにするためです。今回は、同時の判定をしないので、どのキーが押されたのかを判定した後に processEvent で得られる値と同じ値を返すようにしました。何も押されていないときは0が返ります。

処理を行うメソッド
void process(int key) { //調べたキーの値で、変数を変更する処理をします。
            if (key== Display.KEY_SOFT1) {
                (IApplication.getCurrentApp()).terminate();
            }
            if( key == Display.KEY_LEFT) {
                x--;
            }
            if( key == Display.KEY_RIGHT) {
                x++;
            }
            if( key == Display.KEY_UP) {
                y--;
            }
            if( key == Display.KEY_DOWN) {
                y++;
            }
}
 キーのチェックで processEvent と同じ値を返していますから、イベント駆動型の時とほぼ同じ処理です。

描画処理は、paint()を使います。
   フロー駆動型では、自分のプログラムから描画を行います。自分で呼び出すためには、パラメータに Graphics が必要です。Canvasでは getGraphics()で取得できます。

    paint(getGraphics());
 

 これで、processEvent は不要になったはずですが、そううまくはいきません。文法上どうしても存在している必要があるので、外側だけ残して中は消しましょう。
 

  public void processEvent(int type, int param) {
    }

  これで、フロー駆動型のプログラムが完成です。イベント駆動型と違って、常にキーを押した状態をチェックしているので連続して移動します。ゲームの動きっぽいでしょ?
 
完成版のプログラム

 public class Hello2 extends IApplication {

    public void start() {
        MainCanvas mc = new MainCanvas();
        Display.setCurrent((Frame)(mc));
        mc.exe();
    }

}

/**
 * MainCanvas
 *
 */
class MainCanvas extends Canvas {

    int x = Display.getWidth() / 4;
    int y = Display.getHeight() / 2;

    MainCanvas() {
        setSoftLabel(SOFT_KEY_1, "END");
        setBackground(Graphics.getColorOfName(Graphics.BLUE));

    }
    
    void exe()
    {
        while(true) {
            int key = keyCheck();
            process(key);
            paint(getGraphics());
        }
        
    }
    
    int keyCheck()
    {
        int k=getKeypadState();
        if((k & (1<<Display.KEY_SOFT1))!=0) {
            return Display.KEY_SOFT1;
        }
        if((k & (1<<Display.KEY_LEFT))!=0) {
            return Display.KEY_LEFT;
        }
        if((k & (1<<Display.KEY_RIGHT))!=0) {
            return Display.KEY_RIGHT;
        }
        if((k & (1<<Display.KEY_UP))!=0) {
            return Display.KEY_UP;
        }
        if((k & (1<<Display.KEY_DOWN))!=0) {
            return Display.KEY_DOWN;
        }
        return 0;
    }

    void process(int key) { //調べたキーの値で、変数を変更する処理をします。
        if (key== Display.KEY_SOFT1) {
            (IApplication.getCurrentApp()).terminate();
        }
        if( key == Display.KEY_LEFT) {
            x--;
        }
        if( key == Display.KEY_RIGHT) {
            x++;
        }
        if( key == Display.KEY_UP) {
            y--;
        }
        if( key == Display.KEY_DOWN) {
            y++;
        }
   }

    public void paint(Graphics g) {
        g.lock();
        g.clearRect(0, 0, Display.getWidth(), Display.getHeight());
        g.setColor(Graphics.getColorOfName(Graphics.WHITE));
        g.drawString("Start IApplication", x, y);
        g.unlock(true);
    }
    
    public void processEvent(int type, int param) {
    }
}