マリオみたいなゲームを作ろうその3(p5.js)

p5.js

今回は敵を出します。
でも今回は動きません。
とりあえず上からぶつかったら消滅、それ以外からぶつかったら自機が死ぬという処理を作ります。
あと、インベーダーゲームと同じ様に自機、敵、そしてブロックをクラスで管理します。
それではやっていきましょう。

まず、index.htmlを以下の様に書きましょう。(インベーダーゲームと同じです)

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    <script src="sprite.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>

そしてsprite.jsファイルを作って以下のコードを書いてください。
クラスで自機とブロックと敵を管理します。

class Mine {
  constructor(x, y, vy, gridSize) {
    this.x = x;
    this.y = y;
    this.w = gridSize;
    this.h = gridSize;
    this.vy = vy;
    this.isJumping = false;
    this.isAlive = true;
  }

  show() {
    fill(255, 0, 0);
    rect(this.x, this.y, this.w, this.h);
  }

  move() {
    if (keyIsDown(LEFT_ARROW)) {
      this.x -= 5;
    }

    // 右の矢印キーが押されている場合
    if (keyIsDown(RIGHT_ARROW)) {
      this.x += 5;
    }
  }
}

// 敵クラス
class Enemy {
  constructor(x, y, gridSize) {
    this.x = x;
    this.y = y;
    this.w = gridSize;
    this.h = gridSize;
    this.isAlive = true;
  }

  // 敵を描画
  show() {
    fill(0, 0, 255);
    rect(this.x, this.y, this.w, this.h);
  }
}

// ブロッククラス
class Block {
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }
  
  //ブロックを表示
  show() {
    fill(139, 69, 19);
    rect(this.x, this.y, this.w, this.h);
  }
}

ここからsketch.jsファイルを書いていきます。
sketch.jsは主な処理を書きます。
自機と敵の当たり判定は上からぶつかると敵は消滅します。(そして少し跳ねます)
上以外からぶつかると自機が消滅します。

let player;
let blocks = [];
let enemies = [];

let gridSize = 40;

function setup() {
  createCanvas(800, 400);

  // プレイヤー初期設定
  player = new Mine(50, 300, 0, gridSize);

  // ブロック(地面を含む)を配置
  blocks = [
    new Block(200, 250, 100, 20),// 通常ブロック
    new Block(400, 200, 100, 20),// 通常ブロック
    new Block(600, 300, 100, 20),// 通常ブロック
    new Block(0, height - 50, width, 50),// 地面
  ];
  
  // 敵を追加
  enemies = [
    new Enemy(300, 210, gridSize),
    new Enemy(500, height - 90, gridSize),
  ];
}

function draw() {
  background(135, 206, 250);

  // プレイヤーの重力処理
  if (player.isAlive) {
    player.show();
    player.move();
  }
  
  player.vy += 1; // 重力
  let futureY = player.y + player.vy; // 次のフレームのY位置

  // 衝突判定
  let onBlock = false;
  for (let block of blocks) {
    if (
      player.x < block.x + block.w && // 水平方向の重なり
      player.x + player.w > block.x && // 水平方向の重なり
      player.y + player.h <= block.y && // プレイヤーがブロックの上面にいる
      futureY + player.h >= block.y // 次のフレームでブロックを通過しない
    ) {
      futureY = block.y - player.h; // プレイヤーをブロックの上に移動
      player.vy = 0; // 縦方向の速度をリセット
      player.isJumping = false; // ジャンプ状態を解除
      onBlock = true;
    }
  }

  // プレイヤー位置を更新
  player.y = futureY;
  
  // 敵との衝突判定
  for (let enemy of enemies) {
    if (
      enemy.isAlive && // 敵が生存中
      player.x < enemy.x + enemy.w && // 水平方向の重なり
      player.x + player.w > enemy.x && // 水平方向の重なり
      player.y + player.h <= enemy.y && // プレイヤーが敵の上面にいる
      player.y + player.h + player.vy >= enemy.y // 次のフレームで敵を踏む
    ) {
      // 敵を倒す
      enemy.isAlive = false;
      player.vy = -10; // プレイヤーを跳ね返す
    } else if (
      enemy.isAlive && // 敵が生存中
      player.x < enemy.x + enemy.w && // 水平方向の重なり
      player.x + player.w > enemy.x && // 水平方向の重なり
      player.y + player.h > enemy.y // プレイヤーが敵の上面以外に触れる
    ) {
      player.isAlive = false;
    }
  }
  

  // ブロックの描画
  for (let block of blocks) {
    block.show();
  }
  
  // 敵の描画
  for (let enemy of enemies) {
    if (enemy.isAlive) {
      enemy.show();
    }
  }
  
}

function keyPressed() {
   if (keyCode === 32 && !player.isJumping) { // スペースキーでジャンプ
    player.vy = -15;
    player.isJumping = true;
  }
}

上からぶつかったら消滅、それ以外からぶつかったら自機が死ぬ処理以外はクラスを使って短縮している以外、前のコードと変わりません。
どこが変化しているか前の記事と見比べてみましょう。

次は敵を動かしたりします。
それではまた次回。

コメント


タイトルとURLをコピーしました