# へびゲーム

## 体験入学会プログラミング体験教材

### はじめに

本日は体験入学会にお越しいただきありがとうございます。  
プログラミング初心者向けの体験授業として、C++を使った「スネークゲーム」を完成させます。  
<span style="white-space: pre-wrap;">コード中の </span>`<span class="editor-theme-code">TODO</span>`<span style="white-space: pre-wrap;"> マークに沿って穴埋めし、動くゲームを作りましょう。</span>

## ＨＥＢＩＧＡＭＥを動かしてみよう

##### まずはいったん遊んでみよう

- スペースキーでスタート
- キーボードのアローキー（⬆️⬇️⬅️➡️）で方向転換
- エサを食べると成長するよ！
- 自分の体を食べちゃったり、壁に当たるとゲームオーバー
- スペースキーでリスタート

---

### Step 1: 背景色を設定しよう（TODO ＃1 ） 62行目付近

<span style="white-space: pre-wrap;">ゲーム画面の最初に呼ばれる </span>`<span class="editor-theme-code">Stage</span>`<span style="white-space: pre-wrap;"> クラスのコンストラクタ(初期化処理)内で、</span>  
`<span class="editor-theme-code">SetBackgroundColor</span>`<span style="white-space: pre-wrap;"> 関数を使って画面の背景色を設定します。</span>

```cpp
// TODO ＃1: ここに背景色を設定するRGBを入れてください
SetBackgroundColor( ____, ____, ____ );
```

- 各値は 0〜255 の範囲で指定します。
- 見やすい色（例：空色など）を選びましょう。

#### ヒント

`<span class="editor-theme-code">SetBackgroundColor(132, 255, 255);</span>`<span style="white-space: pre-wrap;"> は淡いシアン（空色）です。</span>

---

### Step 2: ステージを描画しよう（TODO ＃2） 148行目付近

`<span class="editor-theme-code">Stage::Draw()</span>`<span style="white-space: pre-wrap;"> 内で、先ほど作ったグリッド状ステージを描画する関数を呼び出します。</span>

```cpp
void Stage::Draw()
{
    // TODO #2: ここにステージ描画関数を呼び出すコードを追加してください
    ____();
    
    if (!snake || !food)
        return;
    // 以下、蛇とフード、スコア描画...
}
```

#### ヒント

`<span class="editor-theme-code">DrawStageGrid()</span>`<span style="white-space: pre-wrap;"> を呼び出します。</span>

---

### Step 3: スネークを作成しよう（TODO ＃3） 63行目付近

<span style="white-space: pre-wrap;">コンストラクタ内で </span>`<span class="editor-theme-code">snake</span>`<span style="white-space: pre-wrap;"> ポインタに新しい </span>`<span class="editor-theme-code">Snake</span>`<span style="white-space: pre-wrap;"> オブジェクトを生成します。</span>

```cpp
// TODO ＃3: Snakeオブジェクトを生成しよう
snake = ____;
```

#### ヒント

`<span class="editor-theme-code">new Snake()</span>`<span style="white-space: pre-wrap;"> でインスタンス化します。</span>

---

### Step 3.5: 移動タイマーを設定しよう（TODO ＃3．５） 19行目付近

スネークの移動間隔を決めるタイマーを設定します。

```cpp
// TODO ＃3.5: スネークの移動間隔を設定しよう
SetMoveTimer( ____ );
```

#### ヒント

<span style="white-space: pre-wrap;">定数 </span>`<span class="editor-theme-code">MOVETIME</span>`<span style="white-space: pre-wrap;"> を使いましょう。</span>

---

### Step 4: フードを作成しよう（TODO ＃4） 64行目付近

<span style="white-space: pre-wrap;">コンストラクタ内で </span>`<span class="editor-theme-code">food</span>`<span style="white-space: pre-wrap;"> ポインタに新しい </span>`<span class="editor-theme-code">Food</span>`<span style="white-space: pre-wrap;"> オブジェクトを生成します。</span>

```cpp
// TODO ＃4: Foodオブジェクトを生成しよう
food = ____;
```

#### ヒント

`<span class="editor-theme-code">new Food()</span>`<span style="white-space: pre-wrap;"> を使います。</span>

---

### Step 5: キーボード入力を処理しよう（TODO ＃5）120行目付近

`<span class="editor-theme-code">Stage::Update()</span>`<span style="white-space: pre-wrap;"> 内で矢印キーを押したときにスネークの進行方向を変更します。</span>

```cpp
if (Input::IsKeyDown(KEY_INPUT_UP))
    snake->SetDirection( ____ );
if (Input::IsKeyDown(KEY_INPUT_DOWN))
    snake->SetDirection( ____ );
if (Input::IsKeyDown(KEY_INPUT_LEFT))
    snake->SetDirection( ____ );
if (Input::IsKeyDown(KEY_INPUT_RIGHT))
    snake->SetDirection( ____ );
```

#### ヒント

`<span class="editor-theme-code">Direction::UP</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">DOWN</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">LEFT</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">RIGHT</span>`<span style="white-space: pre-wrap;"> を使います。</span>

---

### Step 6: ヘビを伸ばそう（TODO ＃6） 131行目付近

スネークがフードを食べたら、体を伸ばすメソッドを呼び出します。

```cpp
if (snake->GetHeadPos() == food->GetPosition()) {
    // TODO ＃6: ヘビを伸ばす関数を呼び出そう
    snake->____();
    food->SpawnRandom();
    // スコア加算へ（TODO #8）
}
```

#### ヒント

`<span class="editor-theme-code">Snake</span>`<span style="white-space: pre-wrap;"> クラスの </span>`<span class="editor-theme-code">Grow()</span>`<span style="white-space: pre-wrap;"> メソッドを呼び出します。</span>

---

### Step 7: スコアを描画しよう（TODO ＃7） 155行目付近

`<span class="editor-theme-code">Stage::Draw()</span>`<span style="white-space: pre-wrap;"> 内で画面上にスコアを表示します。</span>

```cpp
// TODO ＃7: スコアを描画しよう
DrawScore();
```

#### ヒント

<span style="white-space: pre-wrap;">すでに用意した </span>`<span class="editor-theme-code">DrawScore()</span>`<span style="white-space: pre-wrap;"> を呼び出します。</span>

---

### Step 8: スコアを加算しよう（TODO ＃8） 136行目付近

フードを食べたときにスコアを増加させます。

```cpp
if (snake->GetHeadPos() == food->GetPosition()) {
    // ヘビを伸ばす
    // TODO ＃8: スコアを加算しよう
    Score::AddScore( ____ );
    food->SpawnRandom();
}
```

#### ヒント

<span style="white-space: pre-wrap;">1 回のフード取得につき </span>`<span class="editor-theme-code">1</span>`<span style="white-space: pre-wrap;"> 点加算しましょう。</span>

---

### Step 9: 壁との当たり判定をしよう（TODO ＃9） 110行目付近

`<span class="editor-theme-code">Stage::Update()</span>`<span style="white-space: pre-wrap;"> 内でスネークがステージ外に出たらゲームオーバーにします。</span>

```cpp
ivec3 pos = snake->GetBody()[0].GetPosition();
// TODO ＃9: 壁に当たったかチェックして、当たったら死亡処理を呼ぼう
if ( CheckHitWall( vec3(pos.x, 0, pos.z) ) ) {
    snake->SetDeath();
}
```

#### ヒント

`<span class="editor-theme-code">CheckHitWall()</span>`<span style="white-space: pre-wrap;"> を使って判定します。</span>

---

### Step 10: フードをスポーンしよう（TODO ＃4.5） 92行目付近

ステージ読み込み後にフードをランダムな位置に配置します。

```cpp
if (food) {
    // TODO ＃4.5: フードをランダムにスポーンさせよう
    food->____();
}
```

#### ヒント

`<span class="editor-theme-code">SpawnRandom()</span>`<span style="white-space: pre-wrap;"> メソッドを呼び出します。</span>

---

### Step 11: フードを更新しよう（TODO ＃11） 142行目付近

`<span class="editor-theme-code">Stage::Update()</span>`<span style="white-space: pre-wrap;"> 内でフードのアニメーション更新を呼び出します。</span>

```cpp
// TODO ＃11: フードの更新処理を呼び出そう
food->____();
```

#### ヒント

`<span class="editor-theme-code">Update()</span>`<span style="white-space: pre-wrap;"> メソッドを呼び出します。</span>

---

以上でスネークゲームの基本機能が完成します！  
コードをビルドして、動作を確認してみましょう。1 つずつクリアしながら進めてください。

### Step 12: ゲームオーバー時のシーン切り替え（TODO ＃12） 117行目付近

スネークが死亡したときに、別のシーンへ切り替えます。

```
if (!snake->IsAlive())
{
    // TODO ＃12: 死亡時にシーンを切り替えるコードを追加しよう
    SceneManager::ChangeScene();
}
```

#### ヒント

- `<span class="editor-theme-code">SceneManager</span>`<span style="white-space: pre-wrap;"> クラスの </span>`<span class="editor-theme-code">ChangeScene()</span>`<span style="white-space: pre-wrap;"> メソッドを呼び出します。</span>
- 遷移先のシーンはあらかじめ設定されていることを確認してください。

以上で、全 12 ステップの穴埋め教材が完成です！ コードをビルドし、ゲームオーバー時にも正しくシーンが切り替わるか確認してみましょう。 コードをビルドして、動作を確認してみましょう。1 つずつクリアしながら進めてください。

##### URL

https://github.com/youetsux/HEBIGAME\_TAIKEN.git