消しました。Processingでフラッピーバードをつくろう(9):子供のプログラミング学習

<!--

# 9. タイトル画面をつくる

起動した時、リトライしたときに、すぐにゲームがスタートしてしまうと、遊ぶ人にとって優しくないですよね。
タイトル画面を出して、遊ぶ人のタミングでゲームをスタートできるようにしましょう。

## そのまえに
### 前回までのプログラムコード
```Java
float x = 100;
float y = 200;
float speed = 0;
float dx = 400;
float dy = 200;
int shibou = 0;
int score = 0;
void setup() {
  size(600, 400);
}
void draw() {
  background(0);
  // 死亡フラグがたっていなければ
  if(shibou == 0){
    // 土管のプログラム
    dokan();
    // プレイヤーのプログラム
    player();
  }
  // 死亡フラグがたっていれば
  if(shibou == 1){
    fill(255, 0, 0);
    textAlign(CENTER);
    text("GAME OVER", 300, 200); 
  }
  fill(255);
  textAlign(CENTER);
  textSize(48);
  text(score, width/2, 100);
}
void mousePressed() {
  speed = -10;
}
void dokan() {
  // 土管のdraw
  dx = dx - 5;
  if (dx + 50 < 0) {
    dx = 600;
    dy = random(200, 300);
    score = score + 1;
  }
  fill(255, 255, 255);
  rect(dx, dy, 50, 400 - dy);
  
  // 上の土管
  fill(255);
  rect(dx, 0, 50, dy - 150);
}
void player() {
  speed = speed + 1;
  y = y + speed;
  fill(255, 255, 255);

  // 下の土管と衝突しているか調べる
  int hit = isHit(x, y, 50, 50, dx, dy, 50, 400 - dy);
  if(hit == 1){
    fill(255, 0, 0);
    shibou = 1;
  }
  // 上の土管と衝突しているか調べる
  int hit02 = isHit(x, y, 50, 50, dx, 0, 50, dy - 150);
  if(hit02 == 1){
    fill(255, 0, 0); 
    shibou = 1;
  }
  rect(x, y, 50, 50);
}
int isHit(float px, float py, float pw, float ph, float ex, float ey, float ew, float eh) {
  if (px < ex + ew && px + pw > ex) {
    if (py < ey + eh && py + ph > ey) {
      return 1;
    }
  }
  return 0;
}
void init(){
  x = 100;
  y = 200;
  speed = 0;
  dx = 400;
  dy = 200;
  shibou = 0;
  score = 0;
}

void keyPressed(){
  // スペースが押されたら
  if(key == ' '){
    if(shibou == 1){
      init();
    }
  }
}
```


## 8-1 タイトルフラグを用意する
いまタイトル画面なのか、ゲーム画面なのか、を判定するために、またもやフラグを用意しましょう。
タイトルフラグが立っていればタイトル画面を表示し、タイトルフラグが降りていればゲーム画面を表示するようにしましょう。
死亡フラグとは違って、デフォルトでフラグを立たせておくことに注意してください。

```Java
float x = 100;
float y = 200;
float speed = 0;
float dx = 400;
float dy = 200;
int shibou = 0;
int score = 0;
// タイトルフラグを作る。初期値で立たせておく。
int title = 1;
```


## 8-2 タイトルフラグが立っていたらゲームを進行させないようにする
タイトルフラグが立っていたらゲームを進行しないようにします。

ここでは「**return**」という構文を使ってゲームの進行を止めます。

```Java
void draw() {
  background(0);
  // タイトルフラグが立っていたら
  if(title == 1){
    return;
  }
  // 死亡フラグがたっていなければ
  if(shibou == 0){
    // 土管のプログラム
    dokan();
    // プレイヤーのプログラム
    player();
  }
  // 死亡フラグがたっていれば
  if(shibou == 1){
    fill(255, 0, 0);
    textAlign(CENTER);
    text("GAME OVER", 300, 200); 
  }
  fill(255);
  textAlign(CENTER);
  textSize(48);
  text(score, width/2, 100);
}
```

タイトルフラグが1で立っていたら「return」というものを使いました。
簡単に言うと、returnするとそれ以降のプログラムをスキップすることができます。
これ以上処理を進めて欲しくないときなどにreturnを使うと良いでしょう。


## 8-3 タイトルフラグが立っていたらタイトルとなるテキストを表示する
returnだけしてしまうと、真っ黒な画面になってしまうので、タイトルテキストを表示しましょう。

```Java
void draw() {
  background(0);
  if(title == 1){
    fill(255);
    textSize(48);
    textAlign(CENTER);
    text("Cubic Bird",  width/2, height/2);
    return;
  }
  // 省略...
}
```

ここでは「Cubic Bird」という名前にしてみました。好きな名前をつけましょう。
ちなみに日本語を使いたいときはちょっと一工夫が必要です。
文字の大きさを変更した状態で日本語を使うと「□□□□□□□□」こんな感じに文字化けしてしまいます。
それを避けるためには、setup内で、

```Java
void setup() {
  size(600, 400);
  // おまじない
  textFont(createFont("Arial", 48));
}
void draw() {
  background(0);
  if(title == 1){
    fill(255);
    textSize(48);
    textAlign(CENTER);
    text("キュービックバード",  width/2, height/2);
    return;
  }
  // 省略...
}
```

このおまじないを入れてあげましょう。
このおまじないは、Arialという書体のフォントを使います、ということを明示的に命令しています。
日本語が使えるArialフォントを使います、と明確にしてあげることで日本語の文字化けを解決できます。


## 8-4 スペースキーでタイトルフラグをおろす

タイトルが表示できました。
タイトルからゲーム画面に遷移するために、スペースキーが押されたときにタイトルフラグをおろすようにしましょう。


```Java
void keyPressed(){
  // スペースが押されたら
  if(key == ' '){
    // 死亡時の処理
    if(shibou == 1){
      init();
    }
    // タイトル画面での処理
    if(title == 1){
      title = 0;
    }
  }
}
```

ゲームオーバー時にスペースキーでリトライする機能がありました。
今回のゲーム画面への遷移も、同じスペースキーが押された条件の中で同居することになります。

タイトル画面でスペースキーを押すとゲームがスタートするようになりました。

## 8-5 ゲームオーバー時にタイトルフラグをたてる

これは好みの問題ですが、ゲームオーバーからリトライした時に、タイトル画面をスキップしてすぐにリトライしてしまいます。
これはこれで良いのですが、今回はタイトル画面へ戻るようにしましょう。

初期化するinit関数の中でタイトルフラグを立ててあげればよいでしょう。

```Java
void init(){
  x = 100;
  y = 200;
  speed = 0;
  dx = 400;
  dy = 200;
  shibou = 0;
  score = 0;
  // タイトルフラグをたてる
  title = 1;
}
```

init関数の中でタイトルフラグを立てました。
これでゲームオーバーからリトライした時にタイトル画面が・・・。あれ、でませんね。すぐにゲーム画面になってしまいます。

### 実行の順番に気をつける
なぜかというと、ここに原因があります。

```Java
void keyPressed(){
  // スペースが押されたら
  if(key == ' '){
    if(shibou == 1){
      init();
    }
    if(title == 1){
      title = 0;
    }
  }
}
```

死亡フラグが立っている時に、スペースキーが押されると、init関数が呼び出されます。
init関数の中ではタイトルフラグが立ちます。
ですが、keyPressed関数の中で、init関数のあとに、タイトルフラグが立っていたらならばという処理が入っています。

直前のinit関数でタイトルフラグを立てたので、このif(title == 1)はすぐさま条件に合致してしまします。

これを避けるために順番を入れ替えてしまいましょう。

```Java
void keyPressed() {
  // スペースが押されたら
  if (key == ' ') {
    if (title == 1) {
      title = 0;
    }
    if (shibou == 1) {
      init();
    }
  }
}
```

init関数を呼び出す前に、タイトルフラグのチェックをするように、前後入れ替えました。
これでリトライ時にタイトル画面に戻るようになりました。


-->