0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プレイヤーキャラクターの物理挙動設計【MM2025 開発記 # 10】

Last updated at Posted at 2025-12-24

はじめに

この記事は 「MM2025 開発記」 シリーズ第10回です。

前回の記事では、ゲームの毎フレーム処理を行うgameLoopについて解説しました。

今回は、プレイヤーキャラクターの物理挙動設計について解説します。

GamePlayerクラス

プレイヤーが操作するキャラクターを表すクラス。
構成は以下のようになっている。

index.js
class GamePlayer {
  constructor() { ... }
  update() { ... }
  draw(ctx) { ... }
}
  • constructor:プレイヤーキャラクターの初期状態を設定
  • update:物理挙動と状態更新を行う
  • draw:Canvas にプレイヤーを描画する

それぞれのメソッドで行っている処理について解説していく。

constructor

ここで定義している値は、大きく分けると以下の4つになる。

  • 位置・サイズに関する情報
  • 物理挙動(重力・ジャンプ)
  • 接地状態の管理
  • アニメーション制御用の変数

位置・サイズ

index.js
this.x = 400;
this.y = 0;
this.width = 128;
this.height = 128;
  • x:プレイヤーの横位置(今回は画面左寄りに固定)
  • y:縦位置(後で地面の高さから計算するため初期値は 0)
  • width/height:キャラクターの当たり判定サイズ
index.js
this.groundYPercent = 80; // 地面の高さをパーセンテージで指定(75% = 画面の3/4の位置)

地面の高さをパーセンテージで管理すれば、

  • 画面サイズが変わっても位置が崩れにくい
  • リサイズ時の処理が簡単

というメリットがある。

重力・ジャンプ

index.js
this.vy = 0;
this.gravity = 0.65;
this.jumpStrength = -15;
this.isOnGround = true;
  • vy:Y方向の速度
  • gravity:毎フレーム加算される重力
  • jumpStrength:ジャンプ時に与える初速
  • isOnGround:地面に接しているかどうか

直接座標をいじるのではなく、速度を変えて動かすのが自然な物理挙動にするポイントである。

アニメーション制御

index.js
this.frame = 0;
this.frameCount = charaImgs.length;
this.frameInterval = 4;
this.frameTimer = 0;
  • frame:現在表示している画像番号
  • frameCount:アニメーション枚数
  • frameInterval:フレーム切り替え間隔
  • frameTimer:経過時間のカウンタ

update

毎フレーム呼び出される処理。キャラクターの動き方が計算される。
やっている処理は以下のようになる。

  • 重力による落下処理
  • 地面・足場との衝突判定
  • 接地状態の更新
  • アニメーションフレームの更新

重力と移動

index.js
this.vy += this.gravity;
this.y += this.vy;

毎フレーム重力を加え、その速度分だけ位置を更新する。
これにより、自然なジャンプと落下が再現できる。

地面との衝突判定

index.js
if (this.y >= groundY - this.height) {
  this.y = groundY - this.height;
  this.vy = 0;
  this.isOnGround = true;
}

地面にめり込んだら位置を補正する。
着地時に速度をリセット&接地フラグを true にする

アニメーションの更新

index.js
if (!this.isOnGround) {
  this.frame = 0;
} else {
  this.frameTimer += scrollSpeed / 7;
}
  • 空中:アニメーションを固定
  • 地上:ゲーム速度に応じてアニメーションを進める

物理状態と見た目を一致させるための処理。

draw

index.js
// ゲームプレイヤーの描画
draw(ctx) {
  // プレイヤーの描画
  ctx.drawImage(
    charaImgs[this.frame],
    this.x,         // X座標
    this.y,         // Y座標
    this.width,             // 幅(キャラのサイズに合わせて調整)
    this.height              // 高さ(キャラのサイズに合わせて調整)
  );

  const groundY = this.getGroundY();  // 地面のY座標をパーセンテージから取得
  const tileSize = 128;
  const tilesX = Math.ceil((canvas.width + scrollX) / tileSize);
  const tilesY = Math.ceil((canvas.height - groundY) / tileSize);

      
for (let j = 0; j < tilesY; j++) {
  for (let i = 0; i < tilesX; i++) {
    ctx.drawImage(
      groundImg,
      i * tileSize - scrollX % tileSize,
      groundY + j * tileSize,
      tileSize,
      tileSize
    );
  }
}
}

updateで計算した座標・フレームを使って現在の状態をそのまま描画する。

さいごに

今回は、GamePlayerクラスで行っている物理挙動系の処理について解説しました。

次回は、歌詞に連動したコインの生成について紹介します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?