敵キャラ(クリボ)とマリオの当たり判定(プログラムでマリオを作る第27回)

敵キャラ(クリボ)とマリオの当たり判定を行います。

クリボとマリオが当たり判定を起こした場合に、マリオを死亡させるような処理を書きます。
クリボ・マリオ共に四角形なので、四角形と四角形の当たり判定を行うようなコードを書きます。

解説

今回は、クリボとマリオとの当たり判定をやります。
マリオがクリボに当たった時にマリオを死亡させるアクションを実装します。

まず、const.jsを開いてキャラクタの状態を表す定数を定義します。

const.js

// chapter27
var NORMAL_STATE = 1;
// 死んだ時のアニメーション
var DEAD_ACTION = 100;
// 死んでいる状態
var DEAD = 101;

次にkuribo.jsを開いて状態を表す変数と高さを示す変数を定義します。

kuribo.js

function Kuribo(posX,posY,dir){
	// chapter27
	this.state = NORMAL_STATE;
	this.height = 16;
}

次にクリボにマリオとの当たり判定を行う関数の実装をします。

マリオとクリボの判定は四角形と四角形との当たり判定を行なっています。
四角形と四角形の当たり判定はこちらを参照してください。

/**
	chapter27
	キャラクタとの当たり判定
	mario:キャラクタクラス
*/
Kuribo.prototype.collisionWithMario = function(map,mario){
	// マリオが生きている状態
	if(!mario.isDead()){
		// x軸
		if(mario.moveNumX < this.posX + 32 && mario.moveNumX + 32 > this.posX){
			// マリオの上とクリボの下
			if(mario.posY < this.posY + this.height){
				// マリオの下とクリボの上
				if(mario.posY + mario.height > this.posY){
					mario.collisionWithEnemy(map);
				}
			}
		}
	}
}

続いて、クリボの更新関数の定義をします。
毎フレーム実行される処理でこの関数を実行します。

/**
	chapter27
	クリボの更新処理
*/
Kuribo.prototype.update = function(map,mario,moveNum){
	this.move(map,moveNum);
	this.collisionWithMario(map,mario);
}

続いて、マリオクラスに敵キャラとの当たり判定用の関数を実装していきます。

mario.jsを開いてください。

mario.js

新しくメンバー変数を追加します。

function Mario(posX,posY){
	// chapter27
	this.state = NORMAL_STATE;
	this.height = 32;
}

続いて、敵と当たった時の関数を実装します。
stateにDEAD_ACTIONを代入し、それをトリガーにして
死亡アニメーションをあとで行います。

/**
	敵と当たった時のアクション
*/
Mario.prototype.collisionWithEnemy = function(){
	this.state = DEAD_ACTION;
	this.addPosY = 14;
}

つづいて、死亡演出アニメーションを実施する関数です。

state変数が死亡演出アニメーションだった場合に実行されます。
マリオが画面外に出た場合に死亡フラグを立てます。

/**
	死亡演出
*/
Mario.prototype.deadAction = function(){
	if(this.state == DEAD_ACTION){
		this.posY -= this.addPosY;
		if(this.addPosY >= -MAX_GRAVITY){
			this.addPosY -= 1;
		}
		if(this.posY > 480){
			this.state = DEAD;
		}
	}
}

次に、先ほどクリボで呼びだした死亡しているかどうかを返す関数を実装します。

/**
	マリオの死亡判定を返す
*/
Mario.prototype.isDead = function(){
	if(this.state >= DEAD_ACTION){
		return true;
	}
	return false;
}

続いて、マリオの更新関数です。
main.jsから引っ張ってきましょう

/**
	マリオの更新関数
*/
Mario.prototype.update = function(mapChip){
	if(!this.isDead()){
		// マップ座標の更新
	  this.updateMapPosition();
		// 左キーが押されている状態
		if(gLeftPush){
	    if(gSpacePush){
	        this.setIsDash(true);
			    this.moveX(mapChip,-DASH_SPEED);
	    }
	    else{
	      this.setIsDash(false);
	      this.moveX(mapChip,-NORMAL_SPPED);
	    }
		}
		// →キーが押されている状態
		if(gRightPush){
	    if(gSpacePush){
	        this.setIsDash(true);
			    this.moveX(mapChip,DASH_SPEED);
	    }
	    else{
	      this.setIsDash(false);
	      this.moveX(mapChip,NORMAL_SPPED);
	    }
		}

	  // ジャンプ動作
	  if(gUpPush){
	    // ジャンプ設定をオンにする
	    this.setJumpSettings(gSpacePush);
	  }
	  // ジャンプ処理
	  this.jumpAction(gUpPush,mapChip);

	  // scroll処理
	  this.doMapScrollX();
	}
	// 死亡後の処理
	this.deadAction();
}

最後のmain.jsを変更します。

main.js

まず、update関数に毎フレーム実行すべき関数をまとめたので、
今までの書いていた部分を消します。

function move(){
  gMario.update(gMapChip);
  enemyMove();
}

enemyMove関数に書いたクリボの処理も一つにまとめます。

function enemyMove(){
  gKuribo.update(gMapChip,gMario,1);
}

これで、クリボとマリオとの当たり判定のコードを書きました。
次回はクリボの踏みつけ処理を書きたいと思います。

githubはこちらから