以下のような“状態遷移”を実現する必要があります。
コード:
[文字表示]
↓
[入力待ち]
↓ キーが押された
…
[]でくくった箇所がひとつの状態を表し、↓の横に書いてあるのが遷移の条件を表します。
何も書かれていない場合は、無条件で即座に遷移するものとします。
最も単純な方法は、switch-case文による分岐です。以下のサンプルプログラムを示します。
参考にしてみてください。
► スポイラーを表示
コード:
#include "DxLib.h"
// 各フェイズを表す列挙体
enum Phase
{
INITIALIZING_PHASE, RUNNING_PHASE, WAITING_PHASE, UNKNOWN_PHASE
};
// 各フェイズで共有する変数
int StartCount;
// 初期化フェイズ
Phase InitializingPhaseTask(void)
{
StartCount = GetNowCount();
return RUNNING_PHASE;
}
// 動作フェイズ
Phase RunningPhaseTask(void)
{
// 経過時間
int elapsed = GetNowCount() - StartCount;
DrawFormatString(50, 50, GetColor(255, 255, 255), _T("%d ms"), elapsed);
// 一秒経過したら入力待ちフェイズへ
if (1000 <= elapsed) {
return WAITING_PHASE;
}
// 動作フェイズ継続
return RUNNING_PHASE;
}
// 入力待ちフェイズ
Phase WaitingPhaseTask(void)
{
DrawString(0, 0, _T("EnterキーかSpaceキーを押してください"), GetColor(255, 255, 255));
// キーが押されたら、実行フェイズへ
if (CheckHitKey(KEY_INPUT_RETURN) || CheckHitKey(KEY_INPUT_SPACE)) {
StartCount = GetNowCount();
return RUNNING_PHASE;
}
// 入力待ちフェイズ継続
return WAITING_PHASE;
}
// 現在のフェイズによって、処理を振り分ける
// 戻り値は、次に実行すべきフェイズを表す
Phase UpdatePhase(Phase phase)
{
switch (phase) {
case INITIALIZING_PHASE:
return InitializingPhaseTask();
case RUNNING_PHASE:
return RunningPhaseTask();
case WAITING_PHASE:
return WaitingPhaseTask();
}
return UNKNOWN_PHASE;
}
int WINAPI _tWinMain(HINSTANCE, HINSTANCE,LPTSTR, int)
{
ChangeWindowMode(TRUE);
if (DxLib_Init() == -1) {
return -1;
}
SetDrawScreen(DX_SCREEN_BACK);
// 初期フェイズの設定
Phase phase = INITIALIZING_PHASE;
while (ProcessMessage() == 0) {
// Escapeキーで終了
if (CheckHitKey(KEY_INPUT_ESCAPE)) {
break;
}
// 変な値が入ってたら、エラー終了
if (phase == UNKNOWN_PHASE) {
MessageBox(NULL, _T("unkonow phase"), _T("error"), MB_ICONERROR);
break;
}
ClearDrawScreen();
// フェイズの更新
phase = UpdatePhase(phase);
ScreenFlip();
}
DxLib_End();
return 0;
}
このプログラムは、1秒間実行したあと入力待ちをし、キーが入力されたら再び1秒間実行を繰り返すものです。
状態遷移図を書くと以下のようになります。
コード:
↓
[初期化]
↓
特定の ┌→[実行中]
キーが │ ↓ 実行開始から1秒間経過
押された└─[入力待ち]
現在の状態を保持する変数としてphaseを用意し、phaseの値によって処理をswitch-caseで振り分けます。
ここでは、各フェイズの処理関数は次のフェイズを表す値を返すようにしてみました。
コード:
// フェイズの更新
phase = UpdatePhase(phase);
この部分で、特定の条件を満たしたときにはphaseが変更されるので、状態遷移が実現できます。
(値が変わらない場合は、フェイズが継続していることを意味する)
何か分からないことがありましたら、言ってください。