ChatGPTを使って簡単なゲームを作る③: ChatGPTにブロック崩しゲームを作ってもらう編


# とりあえずやってみる

それでは、GPT-4を使って簡単なブロック崩しゲームを作成してみましょう。以下にHTML、CSS、およびJavaScriptのコードを示します。このコードをCodePenに入力して、実際にゲームが動くのを確認してください。

プロンプト例
```

あなたは、ゲームプログラマーとして振る舞ってください。
これからHTMLゲームを作成します。HTMLファイル内部にCSS、Javascript全て書いてください。

ゲームのテーマはブロック崩しゲームです！
```

```HTML: sample 
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ブロック崩しゲーム</title>
  <style>
    body {
      text-align: center;
      font-family: Arial, sans-serif;
    }
    canvas {
      border: 1px solid #000;
      display: block;
      margin: 0 auto;
    }
  </style>
</head>
<body>
  <h1>ブロック崩しゲーム</h1>
  <canvas id="gameCanvas" width="480" height="320"></canvas>
  <script>
    const canvas = document.getElementById("gameCanvas");
    const ctx = canvas.getContext("2d");

    const ballRadius = 10;
    let x = canvas.width / 2;
    let y = canvas.height - 30;
    let dx = 2;
    let dy = -2;

    const paddleHeight = 10;
    const paddleWidth = 75;
    let paddleX = (canvas.width - paddleWidth) / 2;

    let rightPressed = false;
    let leftPressed = false;

    const brickRowCount = 3;
    const brickColumnCount = 5;
    const brickWidth = 75;
    const brickHeight = 20;
    const brickPadding = 10;
    const brickOffsetTop = 30;
    const brickOffsetLeft = 30;

    const bricks = [];
    for (let c = 0; c < brickColumnCount; c++) {
      bricks[c] = [];
      for (let r = 0; r < brickRowCount; r++) {
        bricks[c][r] = { x: 0, y: 0, status: 1 };
      }
    }

    document.addEventListener("keydown", keyDownHandler, false);
    document.addEventListener("keyup", keyUpHandler, false);

    function keyDownHandler(e) {
      if (e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = true;
      } else if (e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = true;
      }
    }

    function keyUpHandler(e) {
      if (e.key == "Right" || e.key == "ArrowRight") {
        rightPressed = false;
      } else if (e.key == "Left" || e.key == "ArrowLeft") {
        leftPressed = false;
      }
    }

    function collisionDetection() {
      for (let c = 0; c < brickColumnCount; c++) {
        for (let r = 0; r < brickRowCount; r++) {
          const b = bricks[c][r];
          if (b.status == 1) {
            if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
              dy = -dy;
              b.status = 0;
            }
          }
        }
      }
    }

    function drawBall() {
      ctx.beginPath();
      ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }

    function drawPaddle() {
      ctx.beginPath();
      ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
      ctx.fillStyle = "#0095DD";
      ctx.fill();
      ctx.closePath();
    }

    function drawBricks() {
      for (let c = 0; c < brickColumnCount; c++) {
        for (let r = 0; r < brickRowCount; r++) {
          if (bricks[c][r].status == 1) {
            const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
            const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
            bricks[c][r].x = brickX;
            bricks[c][r].y = brickY;
            ctx.beginPath();
            ctx.rect(brickX, brickY, brickWidth, brickHeight);
            ctx.fillStyle = "#0095DD";
            ctx.fill();
            ctx.closePath();
          }
        }
      }
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      drawBricks();
      drawBall();
      drawPaddle();
      collisionDetection();

      if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
        dx = -dx;
      }
      if (y + dy < ballRadius) {
        dy = -dy;
      } else if (y + dy > canvas.height - ballRadius) {
        if (x > paddleX && x < paddleX + paddleWidth) {
          dy = -dy;
        } else {
          document.location.reload();
        }
      }

      if (rightPressed && paddleX < canvas.width - paddleWidth) {
        paddleX += 7;
      } else if (leftPressed && paddleX > 0) {
        paddleX -= 7;
      }

      x += dx;
      y += dy;
      requestAnimationFrame(draw);
    }

    draw();
  </script>
</body>
</html>

```


# 上記のHTMLを動かしてみる。


簡単なブロック崩しゲームをCodePenで動かす方法はこんな感じです。

- CodePenにログイン:
    - CodePenにアクセスし、アカウントにログインします。

- 新しいペンを作成:
    - ログイン後、右上の「New Pen」ボタンをクリックして新しいペンを作成します。

- HTMLコードを貼り付け:
    - 作成されたペンのエディター画面に移動します。
    - 「HTML」セクションに以下のコードを貼り付けます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/11382172-fcee-e928-710a-b39650f76074.png)

ちゃんと動きました。

![image.gif](https://i.gyazo.com/1c2d250fedd84c75b05bbe31097e6eb1.gif)




# コードの内容を理解するために、ChatGPTに説明を求める　（optional）

説明してもらいましょう。


```
<canvas>要素を使用してゲーム画面を表示します。
<style>タグ内で基本的なスタイルを設定します。
JavaScript:

キャンバス要素を取得し、2Dコンテキストを設定します。
ボール、パドル、ブロックのパラメータを定義します。
ボールの移動、パドルの移動、ブロックとの衝突検出を実装します。
requestAnimationFrameを使用して、アニメーションを繰り返し描画します。
```



さらに、図解をして、パーツごとに見てみる。ChatGPT先輩に、「このゲームの処理を、UMLで表現して。」とか、「Mermaidで記述して」というと、図解をして教えてくださいます。
Mermaidというのは、Markdownの図式やUMLの図式を書いてくれるオンラインサービスです。


[https://mermaid.live/](https://mermaid.live/ "Mermaid Live")

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/2cbe79cb-d27a-489c-83be-45455cc35bf1.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/a598e42b-7dbc-b009-fffc-e62fe3039014.png)






## リンク
今日の、箸休めコンテンツ：ゲーム制作をChatGPTでやってみるシリーズです。
 

### ChatGPTを使って簡単なゲームを作る①: ゲーム作成・全体概要
https://qiita.com/dms-matthew/items/ecd447bf7ae10468f41e


###  ChatGPTを使って簡単なゲームを作る②: CodePenの利用開始
https://qiita.com/dms-matthew/items/e97eb3d9ffe9d36a765a



###  ChatGPTを使って簡単なゲームを作る③: ChatGPTにブロック崩しゲームを作ってもらう編
https://qiita.com/dms-matthew/items/ac8f2b5086f710d20b98


###  ChatGPTを使って簡単なゲームを作る④: ChatGPTに「ちーかわ」ゲームを作ってもらう編
https://qiita.com/dms-matthew/items/e635d57597ddd87a9b5b　


###  ChatGPTを使って簡単なゲームを作る⑤: ChatGPTに「ベンゼン環・神経衰弱」ゲームを作ってもらう編
https://qiita.com/dms-matthew/items/631111698f7d322194da