コンテンツにスキップ

間違い探しゲーム

チュートリアルを始める前に

今回作るもの

25個の色ブロックの中から、違う色を見つけるゲーム。 シンプルだけど結構難しい間違い探しゲーム。

このチュートリアルの対象者

Processingの課題集1を終えた人

チュートリアルを始める前に必要な知識

  • 変数
  • 繰り返し処理(for)
  • 条件分岐(if)

ではチュートリアル開始!

1) まずは基本の型

基本の型を書きます。

void setup(){
size(600, 400);
}
void draw(){
background(255);
}

2) 黒いブロックを1つ描く

いきなり完成形を目指して作るのではなく、少しずつ作るのがコツです。

まずは黒いブロックを1つ描きましょう。

img01.png

void setup(){
size(600, 400);
}
void draw(){
background(255);
noStroke();
rectMode(CENTER);
fill(0);
rect(140, 80, 50, 50); // 左から140、上から80の場所に、四角形を描く。
}

3) 黒いブロックを横に5個並べる

横80の間隔を空けて配置します。

img02.png

void setup(){
size(600, 400);
}
void draw(){
background(255);
noStroke();
rectMode(CENTER);
fill(0);
rect(140, 80, 50, 50);
rect(140 + 80, 80, 50, 50);
rect(140 + 80 * 2, 80, 50, 50);
rect(140 + 80 * 3, 80, 50, 50);
rect(140 + 80 * 4, 80, 50, 50);
}

4) 繰り返し処理を使って横に5個描く

繰り返し処理(for)を使った書き方に直していきます。

void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 5;
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * i;
fill(0);
rect(x, 80, 50, 50);
}
}

5) 今度は縦に5個並べる

繰り返し処理を使って、縦に5個並べます。縦の間隔は60にします。

img03.png

void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 5;
for(int i=0; i<loopCount; i++){
int y = 80 + 60 * i;
fill(0);
rect(140, y, 50, 50);
}
}

6) 5x5のブロックを描く

横と縦の繰り返し処理を組み合わせて、25個のブロックを描きます。

img04.png

void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 25; // 変更
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * (i % 5); // 「%」を使ってiの値から「0〜4」の数値を作る
int y = 80 + 60 * (i / 5); // 「/」を使ってiの値から「0〜4の数値を作る
fill(0);
rect(x, y, 50, 50);
}
}

7) 色をランダムにする

黒いブロックしか表示されていないため、色を変えます。

起動するたびに色がランダムになります。

img05.png

float r;
float g;
float b;
void setup(){
size(600, 400);
// 色の要素「r, g, b」の値をランダムで作る
r = random(255);
g = random(255);
b = random(255);
}
void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 25;
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * (i % 5);
int y = 80 + 60 * (i / 5);
fill(r, g, b); // ここを変えた
rect(x, y, 50, 50);
}
}

8) 1個目のブロックだけ色を変える

透明度を指定して色を変えます。

透明度は「アルファチャンネル」と呼びます。

img06.png

void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 25;
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * (i % 5);
int y = 80 + 60 * (i / 5);
fill(r, g, b);
// 条件分岐(if)を使います。
if(i == 0){
fill(r, g, b, 255 / 2); // 透明度を半分に。
}else{
fill(r, g, b, 255);
}
rect(x, y, 50, 50);
}
}

9) 色が変わるブロックをランダムにする

色が変わるブロックをランダムにします。

どれくらいの透明度になるか、をランダムにします。

img07.png

float r;
float g;
float b;
float a; // アルファチャンネル用の変数を用意。
int seikai; // 色が変わるブロックが何番目かの変数を用意。
void setup(){
size(600, 400);
r = random(255);
g = random(255);
b = random(255);
// アルファチャンネルを100〜200の範囲でランダムにする
a = random(100, 200);
// 少し難しいですが、0〜24のランダムな「整数」を作っています
seikai = (int)random(0, 25 - 1);
}
void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 25;
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * (i % 5);
int y = 80 + 60 * (i / 5);
fill(r, g, b);
if(i == seikai){
fill(r, g, b, a); // アルファチャンネルを適用
}else{
fill(r, g, b, 255);
}
rect(x, y, 50, 50);
}
}

10) クリックされる度に、問題が変わるようにする

mousePressed()を使うと、クリックしたときの処理が書けます。

void mousePressed(){
r = random(255);
g = random(255);
b = random(255);
a = random(100, 200);
seikai = (int)random(0, 25 - 1);
}

11) 同じ処理を1つにまとめる

クリックされた時の処理と、setupの処理、どちらも同じことをしている処理があることに気付きましたか?(ランダムの処理)

同じ処理は書かないようにしましょう。

DRY = Don’t Repeat Yourself。同じことを書かないのがプログラマの腕の見せ所です。

void setup(){
size(600, 400);
shuffle(); // 定義した命令を呼び出す
}
void mousePressed(){
shuffle(); // 定義した命令を呼び出す
}
// 命令を定義する。ここでは「シャッフル」という名前の命令にしました
void shuffle(){
r = random(255);
g = random(255);
b = random(255);
a = random(100, 200);
seikai = (int)random(0, 25 - 1);
}

12) 正解のブロックをクリックしたときだけ問題が変わるようにする

ブロックをクリックしたかは、ブロックの表示座標と、マウスの座標を比較します。

void mousePressed(){
int seikai_x = 140 + 80 * (seikai % 5);
int seikai_y = 80 + 60 * (seikai / 5);
// 横の位置を比較
if(mouseX > seikai_x - 25 && mouseX < seikai_x + 25){
// 縦の位置を比較
if(mouseY > seikai_y - 25 && mouseY < seikai_y + 25){
// 正解の処理
shuffle();
}
}
}

13) スコアを表示する(完成)

正解ごとにスコアが1増えるようにしましょう。

img08.png

float r;
float g;
float b;
float a;
int seikai;
int score; // スコア用の変数
void setup(){
size(600, 400);
shuffle();
}
void draw(){
background(255);
noStroke();
rectMode(CENTER);
int loopCount = 25;
for(int i=0; i<loopCount; i++){
int x = 140 + 80 * (i % 5);
int y = 80 + 60 * (i / 5);
fill(r, g, b);
if(i == seikai){
fill(r, g, b, a);
}else{
fill(r, g, b, 255);
}
rect(x, y, 50, 50);
}
// スコアを表示する処理
fill(0);
textSize(32);
textAlign(CENTER);
text(score, width/2, 40);
}
void mousePressed(){
int seikai_x = 140 + 80 * (seikai % 5);
int seikai_y = 80 + 60 * (seikai / 5);
if(mouseX > seikai_x - 25 && mouseX < seikai_x + 25){
if(mouseY > seikai_y - 25 && mouseY < seikai_y + 25){
// seikai
score += 1;
shuffle();
}
}
}
void shuffle(){
r = random(255);
g = random(255);
b = random(255);
a = random(100, 200);
seikai = (int)random(0, 25 - 1);
}

チュートリアル終了!

どうでしたか?無事に動いたでしょうか? 今回覚えたことを、きちんと身につけるようにしましょう。

もう一度自分一人だけで作ってみましょう。

もう一度、自分一人で作ってみてください。 チュートリアルを見ずに作って、理解を確実なものにしましょう。

それから、機能を追加して面白くしましょう。例えば、

  • タイムトライアルモード
  • 最初は簡単、だんだん難しくなるようにする
  • ブロックの数を増やす
  • BGMを入れてみる
  • 間違えたときのペナルティを入れてみる

カスタマイズしたサンプルゲーム「ぬめ」

「め」を探そう。

img09.png

このように自分でカスタマイズして、面白いオリジナルゲームにカスタマイズしてみましょう。