タスクシステム

見よう見まねでタスクシステムを実装。キーボードから'O'を押して30フレーム以内に'K'を押したら画面が青くなり、時間切れもしくは異なるキーを押したら画面が赤くなります。で、60フレーム後に黒に戻ります。

using System;
using y4cs.timer;
using y4cs.aux;
using y4cs.draw;
using y4cs.input;
using y4cs.task;

// タスク用ワーク領域
public class Work {
  public int count;  // カウンター
  public int c;    // 文字コード
  public Screen screen;
  public KeyBoardInput key;

  public Work(int count, int c, Screen screen, KeyBoardInput key) {
    this.count = count;
    this.c = c;
    this.screen = screen;
    this.key = key;
  }
}

public class MyTask {
  // タスクの初期化
  public static void Init(TCB cb) {
    Work w = cb.work as Work;
    w.screen.setClearColor(0, 0, 0);
    w.screen.clear();
    cb.proc = new TaskProc(MyTask.InitO);
  }

  // Oの初期化
  public static void InitO(TCB cb) {
    Work w = cb.work as Work;
    w.c = (int)KeyCode.o;
    w.count = 30;
    cb.proc = new TaskProc(MyTask.O);
  }

  // Oの入力を待つ
  public static void O(TCB cb) {
    Work w = cb.work as Work;
    if (w.key.isPush(w.c))
      cb.proc = new TaskProc(MyTask.InitK);
  }

  // Kの初期化
  public static void InitK(TCB cb) {
    Work w = cb.work as Work;
    w.c = (int)KeyCode.k;
    w.count = 30;
    cb.proc = new TaskProc(MyTask.K);
  }

  // Kの入力を待つ
  public static void K(TCB cb) {
    Work w = cb.work as Work;
    if (w.key.isPress(w.c)) {
      cb.proc = new TaskProc(MyTask.OK);
    }
    else if (w.key.isPush() || --w.count == 0) {
      // キーを間違えたか、時間切れ
      cb.proc = new TaskProc(MyTask.NG);
    }
  }

  // OKの入力が成功したら画面を青に
  public static void OK(TCB cb) {
    Work w = cb.work as Work;
    w.screen.setClearColor(0, 0, 255);
    w.screen.clear();
    w.count = 60;
    cb.proc = new TaskProc(MyTask.Wait);
  }

  // OKの入力が失敗したら画面を赤に
  public static void NG(TCB cb) {
    Work w = cb.work as Work;
    w.screen.setClearColor(255, 0, 0);
    w.screen.clear();
    w.count = 60;
    cb.proc = new TaskProc(MyTask.Wait);
  }

  // 一定時間待つ
  public static void Wait(TCB cb) {
    Work w = cb.work as Work;
    if (--w.count == 0) {
      cb.proc = new TaskProc(MyTask.Init);
    }
  }
}

public class Sample02 {
  // タスクリスト
  static TaskList tasks = new TaskList(3);

  public static void Main() {

    // お決まりのパターン
    Screen screen = new Screen();
    screen.beginScreenTest();
    screen.testVideoMode(640,480,0);
    screen.endScreenTest();

    // 60fps
    FpsTimer fpstimer = new FpsTimer();
    fpstimer.setFps(60);

    KeyBoardInput key = new KeyBoardInput();

    // タスク登録
    tasks.make("テスト", 1000, new TaskProc(MyTask.Init), 
      typeof(Work), 0, 0, screen, key);

    while (GameFrame.pollEvent() == 0) {
      screen.clear();

      key.update();

      // タスクを優先度順に処理する
      TCB cb = tasks.head;
      while (cb != null) {
        cb.proc(cb);
        cb = cb.next;
      }
      screen.update();
      fpstimer.waitFrame();
    }
  }
}

親子タスクにはまだ未対応です。