p5.jsを使ってアプリを作ったら、ついに魔法の絨毯にのって空を飛べる日が来た

## 大人になって気づいてしまった ##

![スクリーンショット 2024-06-18 13.13.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3720831/77f2f3e5-1307-8c88-6e48-361b932e5774.png)

私は毎日夢を見ます。

ほとんどの夢は、私が主役の物語です（笑）
脇役の夢は見たことがないと言っていいくらい
**主役に憧れ**があるんでしょうね・・・


### 私がよく見る夢 ###

・魔法の絨毯にのって空を自由に飛びながら冒険する
・ヒーローになって困っている街のみんなを救う
・ほうきにのって登下校する　
→ 大体、授業中に悪役が現れるため、
　変身して悪役の心を救いにいく

など数え切れないほど様々な物語の夢を見ます。

しかし夢が覚めると気づいてしまうのです。
**数秒前まで使えてた魔法が
現実に戻った時には使えないということを。**



## 救世主が現れた！！ ##


最近、**p5.js**というものを知りました。
p5.js：https://editor.p5js.org/


これなら現実でも魔法が使えそう！！


<br>

仲良く**Chat GPT**と一緒に作成してみました！
![スクリーンショット 2024-06-18 13.43.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3720831/ad988737-5a99-0646-66c7-1ca8d3ce5c46.png)

⇩矢印キーを使って空飛べるよ！ぜひやってみてね！

https://editor.p5js.org/yuri.yanagisawa11/full/CsSd5kS8A

## 難易度が上がった！夜景バージョン ##
こちらから↓

https://x.com/riyu___11/status/1804063925920772103

https://editor.p5js.org/yuri.yanagisawa11/full/CsSd5kS8A


<br>

かなりシュールですが
今回は自由に動くことができる朝ver.を一緒に作ってみましょう！

## 作ってみよう！ ##

①　**Chat GPT**に作りたいことを伝えます

・魔法の絨毯にのって
　空を飛べるものを「p5.js」を使って作りたい
・絨毯の上に人を乗せたい
 ・雲を動かせるようにしたい
 

![](https://storage.googleapis.com/zenn-user-upload/a16c932a101b-20240618.png )

②　「index.html」と「sketch.js」のコードを
　　教えてもらいp5.js（https://editor.p5js.org/ ）に
 　　それぞれ入力します


<details><summary>index.htmlのコードはこちら</summary>

```html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Magic Carpet with Moving Clouds</title>
  <!-- p5.js ライブラリの読み込み -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
  <!-- 自作の JavaScript ファイルの読み込み -->
  <script src="sketch.js" defer></script>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>
<body>
</body>
</html>


```
</details>


<details><summary>sketch.jsのコードはこちら</summary>

```js
// 魔法のじゅうたんのインスタンス
let magicCarpet;
// 絨毯の移動速度
let carpetSpeed = 5;

// 雲の位置と速度
let cloud1X, cloud2X;
let cloudSpeed1 = 1;
let cloudSpeed2 = 2;

function setup() {
  createCanvas(windowWidth, windowHeight);
  magicCarpet = new MagicCarpet(width / 2, height / 2);

  // 雲の初期位置
  cloud1X = -200;
  cloud2X = width + 100;
}

function draw() {
  drawBackground();

  // 雲を動かす
  cloud1X += cloudSpeed1;
  cloud2X -= cloudSpeed2;

  // 雲が画面外に出たら反対側から再度表示する
  if (cloud1X > width + 200) {
    cloud1X = -200;
  }
  if (cloud2X < -200) {
    cloud2X = width + 100;
  }

  // 矢印キーの入力を受け取り、絨毯を移動させる
  if (keyIsDown(LEFT_ARROW)) {
    magicCarpet.move(-carpetSpeed, 0);
  } else if (keyIsDown(RIGHT_ARROW)) {
    magicCarpet.move(carpetSpeed, 0);
  } else if (keyIsDown(UP_ARROW)) {
    magicCarpet.move(0, -carpetSpeed);
  } else if (keyIsDown(DOWN_ARROW)) {
    magicCarpet.move(0, carpetSpeed);
  }

  magicCarpet.display();
}

// 背景を描画する関数
function drawBackground() {
  // 空の描画
  let skyColor = color(135, 206, 235);
  background(skyColor);

  // 雲の描画
  fill(255);
  noStroke();
  ellipse(cloud1X, 150, 100, 60);
  ellipse(cloud1X + 60, 130, 120, 70);
  ellipse(cloud1X + 120, 150, 100, 60);

  ellipse(cloud2X, 100, 150, 80);
  ellipse(cloud2X - 100, 130, 120, 70);
  ellipse(cloud2X - 200, 100, 150, 80);

  // 街の風景を描画
  fill(50);
  rect(0, height - 100, width, 100); // 地面
  fill(100);
  rect(100, height - 200, 80, 100); // ビル1
  rect(300, height - 300, 120, 200); // ビル2
  rect(500, height - 250, 100, 150); // ビル3
  rect(700, height - 350, 150, 250); // ビル4
}

// 魔法のじゅうたんのクラス
class MagicCarpet {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.width = 150; // じゅうたんの幅
    this.height = 100; // じゅうたんの高さ
    this.mainColor = color(138, 43, 226); // 紫色
    this.edgeColor = color(255, 255, 0); // 黄色
  }

  move(dx, dy) {
    // 絨毯を移動する
    this.x += dx;
    this.y += dy;

    // 画面端に到達したら反対側から出てくるようにする
    if (this.x > width) {
      this.x = 0;
    } else if (this.x < 0) {
      this.x = width;
    }

    if (this.y > height) {
      this.y = 0;
    } else if (this.y < 0) {
      this.y = height;
    }
  }

  display() {
    // 絨毯の基本形状
    noStroke();
    fill(this.mainColor);
    rect(this.x, this.y, this.width, this.height, 10); // 角を丸めた四角形

    // 絨毯の外側の縁
    strokeWeight(5);
    stroke(this.edgeColor);
    noFill();
    rect(this.x - 5, this.y - 5, this.width + 10, this.height + 10, 15); // 外側の縁

    // 絨毯の柄
    noStroke();
    fill(255, 0, 0);
    rect(this.x + 10, this.y + 10, this.width - 20, this.height - 20, 5); // 内側の四角形
    fill(0, 0, 255);
    ellipse(this.x + this.width / 2, this.y + this.height / 2, 20, 20); // 中央の円

    // 人の描画
    this.displayPerson();
  }

  displayPerson() {
    // 顔
    fill(255, 224, 189); // 肌色
    ellipse(this.x + this.width / 2, this.y + this.height / 2 - 20, 30, 30); // 頭
    fill(0);
    ellipse(this.x + this.width / 2 - 7, this.y + this.height / 2 - 25, 5, 5); // 左目
    ellipse(this.x + this.width / 2 + 7, this.y + this.height / 2 - 25, 5, 5); // 右目
    ellipse(this.x + this.width / 2, this.y + this.height / 2 - 15, 10, 5); // 鼻
    ellipse(this.x + this.width / 2, this.y + this.height / 2 - 10, 15, 7); // 口
    rect(this.x + this.width / 2 - 10, this.y + this.height / 2 - 5, 20, 40); // 体
    fill(0, 102, 153);
    rect(this.x + this.width / 2 - 15, this.y + this.height / 2 + 35, 10, 20); // 左足
    rect(this.x + this.width / 2 + 5, this.y + this.height / 2 + 35, 10, 20); // 右足
    fill(255, 204, 0); // 黄色
    rect(this.x + this.width / 2 - 25, this.y + this.height / 2 - 5, 10, 30); // 左腕
    rect(this.x + this.width / 2 + 15, this.y + this.height / 2 - 5, 10, 30); // 右腕
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

```
</details>

<br>

③　▶️を押したら **完成‼️**

矢印キーを使って
魔法の絨毯を自由に動かすことができます。

空飛べちゃいましたね！！

## リアリティを求めて ##

シュール過ぎますよね。思います。

このシンプルな作りから、
より現実に近づけるために
今後こだわりたい点がたくさんあります。

<br>


⇩NG集や今後の成長はこちらから見られます。

https://zenn.dev/riyu/scraps/dcbcf39137a8a2

**みんなで一緒に、空を飛べる日が来ますように！**