クリボとの当たり判定

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

敵キャラ(クリボ)トマップチップとの当たり判定のプログラムを組みます。

マップチップとの当たり判定なので、基本はマリオと変わりませんが、
クリボは自分で動くので、壁とされるマップチップと接触した時は、移動方向と逆の方向
に進むようなプログラムを書かないといけません。

マリオと違う部分はこの箇所だけになります。

解説

今回は、クリボとマップチップの当たり判定を行います。

まず、Kuribo.jsを開いてください。

Kuribo.js

マリオと同じようにマップチップ座標とマップチップ座標を更新する関数の定義をします。

// マップチップ座標
this.rightMapX = 0;
this.leftMapX = 0;
this.upMapY = 0;
this.downMapY = 0;

続いて関数の定義をしていきますが、この辺りはマリオと変わらないので、
マリオのコードをコピーして、必要な部分だけ書き換えます。

/**
	x軸方向のマップチップ座標の更新

	posX : マップチップ更新対象となるx座標
*/
Kuribo.prototype.updateMapPositionX = function(posX){
	// x座標
	this.leftMapX = Math.floor(posX / MAP_SIZE);
	this.rightMapX = Math.floor((posX + MAP_SIZE - 1) / MAP_SIZE);

	// 配列外チェック
	if(this.leftMapX >= MAX_MAP_CHIP_X){
		this.leftMapX = MAX_MAP_CHIP_X - 1;
	}
	if(this.leftMapX < 0){
		this.leftMapX = 0;
	}
	if(this.rightMapX >= MAX_MAP_CHIP_X){
		this.rightMapX = MAX_MAP_CHIP_X - 1;
	}
	if(this.rightMapX < 0){
		this.rightMapX = 0;
	}
}

/**
	chapter26
	Y軸方向のマップチップの更新
*/
Kuribo.prototype.updateMapPositionY = function(posY){
	// y
	this.upMapY = Math.floor(posY / MAP_SIZE);
	this.downMapY = Math.floor((posY + MAP_SIZE - 1) / MAP_SIZE);

	// 配列外チェック
	if(this.upMapY >= MAX_MAP_Y - 1){
		this.upMapY = MAX_MAP_Y - 1;
	}
	if(this.upMapY < 0){
		this.upMapY = 0;
	}
	if(this.downMapY >= MAX_MAP_Y - 1){
		this.downMapY = MAX_MAP_Y - 1;
	}
	if(this.downMapY < 0){
		this.downMapY = 0;
	}
}

/**
	chapter26
	マップチップ座標を更新する
*/
Kuribo.prototype.updateMapPosition = function(){
	this.updateMapPositionX(this.posX);
	this.updateMapPositionY(this.posY);
}

 

続いて、マップチップとの当たり判定を行う関数を書きます。

当たり判定自体のコードはマリオと変わりありませんが、
壁とされるマップに当たった時に移動方向を変えるようにコードを書きます。

/**
	chapter26
	オブジェクトとの当たり判定X
*/
Kuribo.prototype.collisionX = function(map,posX){
	this.updateMapPositionX(posX);
	// クリボの右側
	if(isObjectMap(map[this.downMapY][this.rightMapX]) || isObjectMap(map[this.upMapY][this.rightMapX])){
		// (加算される前の)中心点からの距離を取る
		var vecX = Math.abs((this.posX + HALF_MAP_SIZE) - ((this.rightMapX * MAP_SIZE) + HALF_MAP_SIZE));
		this.addPosX = Math.abs(MAP_SIZE - vecX);
		// 方向を変える
		this.direction = LEFT_DIR;
	}
	// クリボの左側
	else if(isObjectMap(map[this.downMapY][this.leftMapX]) || isObjectMap(map[this.upMapY][this.leftMapX])){
		// (加算される前の)中心点からの距離を取る
		var vecX = Math.abs((this.posX + HALF_MAP_SIZE) - ((this.leftMapX * MAP_SIZE) + HALF_MAP_SIZE));
		this.addPosX = -Math.abs(MAP_SIZE - vecX);
		// 方向変える
		this.direction = RIGHT_DIR;
	}
}

次にmove関数内にcollisionX関数を加えてマップチップとの当たり判定を行えるようにします。

マリオと同じように、マップチップと当たり判定がある場合に移動する加算量を
collisionX関数により調整しています。

/*
	動かす役割

	moveNum:移動量
*/
Kuribo.prototype.move = function(mapChip,moveNum){
	this.updateMapPosition();
	// 向きにより加算量を調整する
	moveNum = this.direction == LEFT_DIR ? -moveNum : moveNum;
	// 加算量を代入する
	this.addPosX = moveNum;
	// マップチップとの当たり判定
	this.collisionX(mapChip,this.posX + this.addPosX);
	this.posX += this.addPosX;

	// animation
	if(this.animCnt++ >= 12){
		this.animCnt = 0;
		// 一定以上に達したらアニメーションを更新する
		if(++this.animX > 3){
			this.animX = 0;
		}
	}
}

最後にマップチップとの当たり判定がわかるように地面にマップチップを置きます。

gKuribo = new Kuribo(160,384,LEFT_DIR);
var gMapChip = [
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,0,0,0,0,0,64,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,64,64,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,0,0,0,64,64,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,64,0,0,0,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,64,0,0,0,64,64,0,0,0,0,0,0,64,0,64,0,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,64,0,64,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,64,0,64,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,64,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,64,64,64,64,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,0,64,0,0,64,0,0,0,0,64,0,0,0,0,0,64,0,0,0,0,64,64,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,64,0,0,0,64,64,64,64,64,64,64,64,64,0,0,0,64,0,0,64,0,0,0,0,0,64,0,0,0,0,64,0,0,0,64,0,0,64,0,0,0,0,0,64,0,0,0,64,64,64,64,64,64,64,64,64,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,64,64,64,64,64,0,0,0,0,64,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,0,64,0,0,64,64,64,64,64,0,0,64,64,64,64,64,0,0,64,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,64,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,64,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,114],
  [128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,130],
];

これで、index.htmlを実行すれば、クリボがマップチップ壁にぶつかると向きを変えるようになります。