MiraikanPicodeワークショップ~カラダをつかってロボットプログラミング!~


// 変数の宣言
Human human;
PFont font, smallFont, largeFont;
PImage left, right, none, both;
Pose pose;
int start, score, lastScore, count, goal, showCount, time;

// --------------------------------------------------------------------------------
// はじめに一度だけ実行される処理
void setup() {

  // Kinectに接続する
  human = new Human();
  human.showCaptureFrame(true);

  // フォントやキャラクターの画像を読み込む
  font = createFont("Meiryo UI Bold", 64, true);
  smallFont = createFont("Meiryo UI Bold", 32, true);
  largeFont = createFont("Meiryo UI Bold", 96, true);
  left = loadImage("left.png");
  right = loadImage("right.png");
  none = loadImage("none.png");
  both = loadImage("both.png");

  // 設定など
  frameRate(15);  // draw()を実行する頻度
  size(640, 720); // 画面サイズ
  start = -1;     // スコアを計算するための現在時刻(ゲーム開始前は仮に -1 にしておく)
  score = 0;      // 合計スコア(最初はもちろん 0)
  lastScore = 0;  // 最後に正解したとき加算されたスコア
  count = 0;      // 正解した回数
  goal = 2;       // 最初の正解ポーズを決める(2: 両手をさげて!)
  showCount = 0;  // スコアを表示する残り時間(最初は表示しないので 0 にしておく)
}

// --------------------------------------------------------------------------------
// 1秒に15回実行されつづける処理
void draw() {

  // 人のポーズを取得する
  pose = human.getPose();

  // 画面にキャラクターやスコアを表示する
  showInfo();

  // ポーズが取れなかったらここで終わる
  // (ポーズの判定に進まない)
  if (pose == null) {
    return;
  }

  // ポーズが合っているか判定する
  boolean ok = false;
  switch (goal) {

    // 左手あげて!
    case 0:
      if (pose.eq())) {
        ok = true;
      }
      break;

    // 右手あげて!
    case 1:
      if (pose.eq())) {
        ok = true;
      }
      break;

    // 両手さげて!
    case 2:
      if (pose.eq())) {
        ok = true;
      }
      break;

    // 両手あげて!
    case 3:
      if (pose.eq())) {
        ok = true;
      }
      break;
  }

  // ポーズが正しくなかったらここで終わる
  if (ok == false) {
    return;
  }

  // 正解!!
  calcScore();  // スコアを計算する
  setNewGoal(); // 次の正解ポーズを決める
  if (lastScore > 0) {
    showCount = 45; // スコアを表示する残り時間をセットする(45 ÷ 15 = 3秒間)
  }
}

// --------------------------------------------------------------------------------
// draw() から呼ばれるサブルーチン

// 画面にキャラクターやスコアを表示する
void showInfo() {
  clearBackground();  // 背景を塗りつぶす
  showCharacter();    // キャラクターを表示する
  showTotalScore();   // スコアの合計を表示する
  if (showCount >= 0) {
    showScore();      // 最後に正解したときのスコアを表示する
    showCount = showCount - 1; // スコアを表示する残り時間を減らす
  }
}

// 背景を塗りつぶす
void clearBackground() {
  if (pose == null) {
    background(200); // ポーズが取れなかったら灰色
  } else {
    background(160, 216, 239); // 取れたら薄青
  }
}

// キャラクターを表示する
void showCharacter() {
  textFont(font);
  textAlign(CENTER);
  switch (goal) {
    case 0:
      image(left, 20, 80);
      showText("左手あげて!", 320, 640);
      break;
    case 1:
      image(right, 20, 80);
      showText("右手あげて!", 320, 640);
      break;
    case 2:
      image(none, 20, 80);
      showText("両手さげて!", 320, 640);
      break;
    case 3:
      image(both, 20, 80);
      showText("両手あげて!", 320, 640);
      break;
  }
}

// 文字を表示する
void showText(String text, int x, int y) {
  showText(text, x, y, color(255, 255, 255));
}
void showText(String text, int x, int y, color col) {
  fill(0);
  text(text, x + 1, y + 1);
  text(text, x + 2, y + 1);
  text(text, x + 1, y + 2);
  fill(col);
  text(text, x, y);
}

// スコアの合計を表示する
void showTotalScore() {
  textFont(smallFont);
  textAlign(LEFT);
  fill(0);
  text("合計スコア: " + score, 10, 40);
  if (count > 0) {
    int average = time / count;
    text("平均反応時間: " + (average / 10) + "." + (average % 10) + "秒", 10, 80);
  }
}

// 最後に正解したときのスコアを表示する
void showScore() {
  textFont(largeFont);
  textAlign(CENTER);
  showText("正解!" + lastScore + "点!!", 300, 320, color(255, 60, 60));
}

// スコアを計算する
void calcScore() {
  int end = getTime();
  if (start >= 0) {
    int lap = end - start;
    time += lap;
    lastScore = 100 - lap;
    if (lastScore < 0) {
      lastScore = 0;
    }
    score = score + lastScore;
    count = count + 1;
  }
  start = end;
}

// 次の正解ポーズを決める
void setNewGoal() {
  int newGoal = (int) random(0, 3);
  if (goal <= newGoal) {
    goal = newGoal + 1;
  } else {
    goal = newGoal;
  }
}

// 今の時刻を取得する
int getTime() {
  return ((hour() * 60 + minute()) * 60 + second()) * 10 + millis() / 100;
}

3/29/2013 Picodeワークショップ