入力待ちの方法について RSSフィード
 

リスト表示 | ツリー表示
ツリー全部最新の50件

1alg-ljalg-lj   入力待ちの方法について

ユーザーの入力(画面タップでも、ボタン押しでも、とにかくユーザーの何らかの行為)があるまで処理を待つ、っていうのはどんなコードにしたらいいんでしょうか?

PilotMainのif(!SysHandleEven(&event))の前に入れて、フラグがtrueだったら待つ、みたいにしてみたんですけど、なんかFatal Errorを誘発しているような気がするんですよねぇ。

それに、どうも意図した動きをしないときがあるので、そもそも考え方が間違っている気が(汗)。

Boolean wait4Tap(EventType * eventP) {

FormPtr pForm;

Boolean handled = false;

switch(eventP->eType) {

case penDownEvent:

if(wait4TapF) {

handled = true;

wait4TapF = false;

}

break;

}

return handled;

}

UInt32 PilotMain (UInt16 cmd,

void *cmdPBP,

UInt16 launchFlags)

{

EventType event;

UInt16 error;

if (cmd == sysAppLaunchCmdNormalLaunch)

{

startApp();

FrmGotoForm(MainForm);

do

{

// Wait for an event

EvtGetEvent(&event, evtWaitForever);

// ask event handlers, in turn, to deal with the event.

if (wait4Tap(&event))

continue;

if (!SysHandleEvent (&event))

if (!MenuHandleEvent (0, &event, &error))

if (!appHandleEvent (&event))

FrmDispatchEvent (&event);

} while (event.eType != appStopEvent);

stopApp();

FrmCloseAllForms();

}

return 0;

}

返信2005/06/21 00:42:14

2alg-ljalg-lj   1  Re:入力待ちの方法について

…書き込んだら、tabが無視されてえらく見にくい。
tabじゃなくて全角スペースとかにしないと駄目かも。

Boolean wait4Tap(EventType * eventP) {

  FormPtr pForm;

  Boolean handled = false;

  switch(eventP->eType) {

    case penDownEvent:

      if(wait4TapF) {

        handled = true;

        wait4TapF = false;

      }

      break;

  }

  return handled;

}

UInt32 PilotMain (UInt16 cmd,

  void  *cmdPBP,

  UInt16 launchFlags)

{

  EventType  event;

  UInt16    error;

  if (cmd == sysAppLaunchCmdNormalLaunch)

  {

    startApp();

    FrmGotoForm(MainForm);

    do

    {

      // Wait for an event

      EvtGetEvent(&event, evtWaitForever);

      // ask event handlers, in turn, to deal with the event.

      if (wait4Tap(&event))

        continue;

      if (!SysHandleEvent (&event))

      if (!MenuHandleEvent (0, &event, &error))

      if (!appHandleEvent (&event))

        FrmDispatchEvent (&event);

    } while (event.eType != appStopEvent);

    stopApp();

    FrmCloseAllForms();

  }

  return 0;

}

返信2005/06/21 00:46:40

3chamekanchamekan   2  Re:Re:入力待ちの方法について

すみません。

Mage's Mazeは、ペン入力がないと、ゲームが進行しないですよね?

(違う例としては、リアルタイムでかつ、ペン入力で意思表示というパターンもある)

ブロック崩しの場合、入力とは関係なくリアルタイムに進む必要があったんで、ちと、行儀の悪い作法になっています。

Mage's Mazeの場合は、スケルトンで生成されたmainFormEventHandler関数にイベント処理書いていくほうがいいかもしれません。

以下のような部分。

/*

* Event handler for the main form.

*/

  static Boolean

mainFormEventHandler(EventPtr pEvent)

{

  Boolean handled = false;

  FormPtr pForm = FrmGetActiveForm();

  switch (pEvent->eType)

  {

  case frmOpenEvent: // Form's 1st event

    FrmDrawForm(pForm);

    mainFormInit(pForm);

    handled = true;

    break;

  // *** ADD EVENT HANDLING HERE *** //

  default:

    break;

  }

  return handled;

}

えーと、これの「// *** ADD EVENT HANDLING HERE *** //」というところありますよね。イベントハンドリングはここに追加せよ、と書いてあるので、そこに、case文を追加して、

case PenDownEvent:

ほげほげ

case PenMoveEvent:

ほげほげ

case PenUpEvent:

ほげほげ

と書くと。

これは、システムとかメニューとかの処理が終わって、「FrmDispatchEvent (&event);」のところで、対応したフォームに紐付けた関数(この場合上記関数)が実行されます。

返信2005/06/21 08:55:09

4chamekanchamekan   3  Re:Re:Re:入力待ちの方法について

あと、

wait4TapFを、trueにしているところがあるのかな?


ともあれ、ペンイベントは、PalmOSの根幹なんで、あんまり横取りしないほうがいいので、システムとかがペンイベントを処理しおわったあとに、というほうがいいみたいです。

返信2005/06/21 09:11:06

5alg-ljalg-lj   3  Re:Re:Re:入力待ちの方法について

説明不足ですみません。

mainFormEventHandlerや他のフォーム用のEventHandler(itemFormEventHandler、mapFormEventHandler、battleFormEventHandler、など)にそれぞれイベントを書く、という方法はとっています。

たとえば迷路移動用フォームのイベントハンドラは、こんな感じです。

#define FwdBtn  1001

#define LeftBtn  1002

Int8 nowD;//向いている方向 N:-10 S:10 E:1 W:-1

(中略)

  static Boolean

gameFormEventHandler(EventPtr pEvent)

{

  Boolean handled = false;

  FormPtr pForm = FrmGetActiveForm();

  Char tmp1[10];

  UInt8 i;

  switch (pEvent->eType) {

    case frmOpenEvent:  // Form's 1st event

      FrmDrawForm(pForm);

      gameFormInit(pForm);  //迷路の初期状態表示

      handled = true;

      break;

    case keyDownEvent:

      pForm = FrmGetActiveForm();

      if(pEvent->data.keyDown.chr == vchrPageUp) { //前進

        restoreHPcheck(); //10歩移動ごとにHPが回復

        mazeFwd(); //前進に伴う処理(座標移動、アイテム取得チェック、敵遭遇チェック、など)

        handled = true;

      } else if(pEvent->data.keyDown.chr == vchrPageDown) { //後ろを向く

        nowD = 0-nowD;  //方向を変える

        mazeDraw(); //迷路の再描画

        encountCheck(); //敵遭遇チェック

        handled = true;

      }

      break;

    case ctlSelectEvent:

      pForm = FrmGetActiveForm();

      if(pEvent->data.ctlSelect.controlID == FwdBtn) { //前進

        restoreHPcheck(); //10歩移動ごとにHPが回復

        mazeFwd(); //前進に伴う処理(座標移動、アイテム取得チェック、敵遭遇チェック、など)

        handled = true;

      } else if(pEvent->data.ctlSelect.controlID == LeftBtn) { //左を向く

で、「前進に伴う処理」や「敵遭遇チェック」など、それぞれの処理の中で場合によっては入力待ちが発生します。

たとえば、敵遭遇チェックの中で敵に会わなかったら入力待ちはしません。

敵に会ったら「敵だ!」と表示して入力を待ち、入力があったら戦闘フォームに遷移する、という感じです。

それをどうしたもんかなぁ、というところなんです。

ちょっと前は入力待ち用の関数を作って、各処理からそれを呼び出していました。

ちなみにその入力待ち用関数部分のソースは消してしまいましたけど、使い方としてはこんな感じでした。

static void encountCheck(void) {

  UInt8 t;

  if(mNum != 0) { //敵の数がゼロでなかったら=まだそのフロアに敵がいるなら

    t = getmyRnd(); //0~99の乱数を取得

    if(t <= 10) {

      print(2,134,"敵だ!"); //printはブロック崩しソースから無断借用(汗)

    waitTap(); //入力があるまで次の処理に進まない

    battle(); //戦闘を開始する

    }

  }

}

ただwaitTap()があるせいでFatal Errorが出ていたようなので、その処理を消して、代わりにPilotMainのしょっぱなで、入力待ちフラグがTrueなら入力待ちをする、みたいにやろうとしたんですよね。

なので、「入力があるまで次の処理に進まない」という関数がErrorなしで実現できればベストです。

ただ、そんな入力待ちを使わないようなつくりにする、という方法もありますね…。

>wait4TapFを、trueにしているところがあるのかな?

そうですそうです。

>ともあれ、ペンイベントは、PalmOSの根幹なんで、あんまり横取りしないほうがいいので

やっぱりそうですか…。

今はまだ試行錯誤しながら作法を学んでいる感じです。

怒られたとき(=Fatal Error喰らったとき)に初めてダメなことだと学習する、みたいな。

※余談ですが、グループメンバーが増えて、こんな感じで疑問・質問や情報提供などのやりとりが活発になるといいですねぇ。現時点では私が質問してchamekanさんが答える、という形にしかなりようがないので(汗)。ご迷惑をおかけします。

返信2005/06/21 10:58:16

6chamekanchamekan   ははあ。

do

    {

      // Wait for an event

      EvtGetEvent(&event, evtWaitForever); ←これ

      if (!SysHandleEvent (&event))

      if (!MenuHandleEvent (0, &event, &error))

      if (!appHandleEvent (&event))

        FrmDispatchEvent (&event);

    } while (event.eType != appStopEvent);

いずれにしても、入力は、上記ループのEvtGetEventの部分でやる必要があるので、

ゲームの状態を表す変数をつくったらどうでしょう。

#define State_forward_before_input ****(重複しない適当な数字)

#define State_forward_after_input ****

#define State_encounter_before_input ****

#define State_encounter_after_input ****

(長いので、OnBoardCでは、適当に省略して短くすべきでしょう(^_^;)

SForB, SForA, SEncB, SEncAくらいか(^_^;))

UInt16 game_state;

「前進に伴う処理中」「敵遭遇チェック中」のそれぞれ、入力があったかないかみたいなのを全部わけるわけて、処理ごとに、game_stateがどの状態であるか、という数字を入れて判別するわけです。

しかし、これはアタマがわるいので、処理の内容と、入力前後は、別のフラグにするべきかもしれません。

UInt16 game_state;

Boolean input_state;

とか。

ちょっと、alg-ljさんのケースでどうすれば、最適の状態変数ができるのかわかりませんが(^_^;)(ゲームに依存する)。

ちょうど、わたしのブロックくずしでやっているgsという変数みたいで、あのときも、たとえば、ゲームスタート前は、ずっと入力があるのを待って、入力がないと、ゲーム開始という状態にはなりません。また、最初のある一定の時間は、ボールがパドルにひっついてて、パドルと一緒に動いて、最初に狙うブロックを決めることができたりします。

入力については、いつも、イベントループのEvtGetEvent関数を使ってるんですが、何を処理するか、とか、あるいは、何かの状態になるまで次の状態にならないというのは、そういうゲームの状態の変数をつくって、やっています。

そのあたりのことではないかな、と思うんですが、的はずれなら、また、情報をお知らせください(^_^;)。

ちなみに、わたしの作った関数とか、再利用OKというか、printとかbitmapなんか、だれがつくってもああなりますから(^_^;)。

返信2005/06/21 11:59:41

7alg-ljalg-lj   6  なるほど。

全然、的外れではないですよ。

>何を処理するか、とか、あるいは、何かの状態になるまで次の状態にならないというのは、そういうゲームの状態の変数をつくって、やっています。

なるほど。

そうやればいいんですね。

方針が何となくわかったので、自分のケースにはどうやれば適当か、試行錯誤してみます。

ありがとうございました。

返信2005/06/21 17:42:45

8FeerFeer   風邪気味Feerです。

こんばんは~。

SDKとか参考サイトを見ながら、練習で初めてスケルトン以外のソフトらしきものを作りました!

といっても、

画面の数個のボタンを押したら、そのボタンに対応した文字が画面に表示される

っていうものなんですけどね。

で、作ってみた後、ここの書き込み読んだら…それに、スケルトンとか読んだら

微妙にですけど、最初の頃よりもぐっと分かるようになったような感じです。

(はじめてできたんで、その気になってるだけとも言うw)

イベントが起きたら、pFormに起きた場所(フォーム)が記録されて

その中のイベントを起こしたリソースのIDが何番だったかを読み取って

それがこの番号だったら、こうする、この番号だったらこうする

ってやるんですね~。

多分、メニュー処理とかも、スケルトン見てみたら空っぽだけど

同じように、メニューのこのグループのこのIDの所が押されたら…

ってやるんでしょうね。

ワクワクしてきた…!

返信2005/08/13 23:17:02

9alg-ljalg-lj   8  Re:風邪気味Feerです。

ワクワクしてきた…!

進展してますねー。

メニューの考え方も合ってますし。

いろいろいじって思った通りのことができると、嬉しいですよね〜。

その調子で頑張って下さい。

それと、何かあったら新スレ立てちゃってもいいと思いますよ。

返信2005/08/14 02:02:40