間違い探しゲーム

10x10のマスの中で微妙に色が違う場所を探してください。見つけるまでにかかる時間を計測して表示する、そんなゲームをProcessing(Java)を使って作ってみましょう。

ステップ1

10x10の四角を描画してください。
findit1
行と列のような表現を行う場合、for文の2重ループが適しています。

for(int y = 0 ; y < 10; y++){
   for(int x = 0 ; x < 10 ; x++){
      // ここに処理を記述
   }
}

ステップ2

一つのマスだけ微妙に異なる色にしてください。
10行×10列であれば100マス(0~99)あることになります。乱数を使って0~99の数を生成するには以下のように記述します。

int r = (int)random(100);

random(100)は100未満のランダムな数を生成します。これを整数に変換するには(int)と記述します。変数rは0~99までの値を保持することになります。

ステップ3

該当のマスがクリックされたときにprintln命令でその旨をコンソールに表示してください。マウスクリックを検出するにはmousePressed関数を定義します。この関数が定義されていると、マウスがクリックされたときに呼び出されます。マウスの座標は(mouseX, mouseY)という変数で取得できます。この値をマスのサイズで割れば何マス目か計算で求めることができます。整数に変換するための(int)を忘れないようにしてください。

ステップ4

正しいマスがクリックされるまでに要した時間(もしくはフレーム数)を表示してください。
findit3

#解答例

ステップ1

void setup(){
  size(500, 500);
}
void draw(){
  for(int y = 0 ; y < 10 ; y++){
    for(int x = 0 ; x < 10 ; x++){
      rect(x*50, y*50, 50, 50);
    }
  }  
}

一つのマスを50x50のサイズとしています。xが水平方向、yが垂直方向の変数として使用しています。

ステップ2

このステップのポイントは乱数の使い方です。Processingではrandom関数でランダムな数を生成することができますが、生成する数値は小数点です。これを整数に変換するには(int)でキャスト(変換)する必要があります。

int r = (int)random(100);

void setup(){
  size(500, 500);
}
void draw(){
  for(int y = 0 ; y < 10 ; y++){
    for(int x = 0 ; x < 10 ; x++){
      if (y*10+x == r){
        fill(255, 255, 0);
      } else {
        fill(255, 245, 0);
      }
      rect(x*50, y*50, 50, 50);
    }
  }  
}

乱数はプログラム実行時の最初に生成しています。rはグローバル変数です。
drawの中でforの2重ループを使用していますが、x列目・y行目のどこがrに相当するのか計算で求める必要があります。
findit2

縦方向のyの値に列数(今回の例では10)を掛け合わせ、それに横方向の値xを足したものが(x,y)の番号とします。この番号がrと等しい時だけ塗りつぶす色を微妙に変化させています。

ステップ3

int r = (int)random(100);

void setup(){
  size(500, 500);
}
void draw(){
  for(int y = 0 ; y < 10 ; y++){
    for(int x = 0 ; x < 10 ; x++){
      if (y*10+x == r){
        fill(255, 255, 0);
      } else {
        fill(255, 245, 0);
      }
      rect(x*50, y*50, 50, 50);
    }
  }  
}

void mousePressed(){
  int x = (int)(mouseX / 50);
  int y = (int)(mouseY / 50);
  if (r == y*10+x) {
    println("HIT");
  }
}

ステップ4

int r = (int)random(100);
boolean found = false;
int time = 0;

void setup(){
  size(500, 500);
  textSize(50);
  textAlign(CENTER);
}

void draw(){
  for(int y = 0 ; y < 10 ; y++){
    for(int x = 0 ; x < 10 ; x++){
      if (y*10+x == r){
        fill(255, 255, 0);
      } else {
        fill(255, 245, 0);
      }
      rect(x*50, y*50, 50, 50);
    }
  }
  if (found) {
    fill(0, 0, 255);
    text("FOUND!", 250, 250);
    text("Your Time=" + time, 250, 300);
  }
}

void mousePressed(){
  int x = (int)(mouseX / 50);
  int y = (int)(mouseY / 50);
  if (r == y*10+x) {
    found = true;
    time = frameCount;
  }
}

文字を表示するのでsetup関数でtextSize, textAlignを使って文字の描画スタイルを初期化しています。
今回は時間をフレーム数で計測することにしました。frameCountは描画を行う都度(=draw関数を実行する都度)自動で増加する変数です。

mousePressed関数で、正しい場所がクリックされたときに変数foundをtrueに、変数timeを現在のフレーム数に設定しています。draw関数ではfoundがtrueの時に、所要時間timeを描画しています。