マリオの座る処理の実装

マリオのしゃがむ処理の実装(プログラミングでマリオを作る43回)

2週間ほど空いて、今回はしゃがみ処理の実装をします。

今回の実装結果は以下のようになります。

マリオのしゃがむ処理の実装

基本しゃがむ処理を割り当てるだけですが、

大きくなった時に、ドカンに入る際にしゃがむようになるので、下が離されても、しゃがみ状態を継続するような処理を取り入れないといけないなど、
細かい実装もあります。

では、今回実装する内容を確認していきましょう

今回実装する内容

1.しゃがみ画像を用意する

2.下ボタンを押した時にしゃがむようにする

3.ジャンプ中はしゃがめないなど、細かいフラグ処理

めんどくさい点は、画像と、あと画像を切り取る際のオフセットをどうやって処理するかという点のみですね。

では、実装に入ります。

今回用意する画像

以下のようにオフセットを開けた画像を用意しました。

マリオしゃがみ画像追加

しゃがみ画像を35の高さで作っていますが、当たり判定はマップチップサイズである32で取ります。

しゃがんでいるときは、切り取り高さ分のオフセット追加して、切りとるようにします。

mario.js

しゃがむ処理用の変数を新しく追加します。

// chapter43
this.isSit = false;					// offsetに利用したいので、0 1で管理する
this.textureHeight = MAP_SIZE;		// テクスチャを切り取る範囲Y	// テクスチャを切り取る範囲Y

描画関数を見ます。

Mario.prototype.draw = function(ctx,texture){
	let offsetY = this.isSit ? (29 + 64) : 0;
	ctx.drawImage(texture,this.starOffsetX + (this.animX * 32) + this.animOffsetX,((this.direction * 2) * this.textureHeight) + this.textureOffsetY + offsetY,32,this.height,this.posX,this.posY,32,this.height);
}

しゃがんでいる際はオフセットを追加して、しゃがみ画像が切り取られるようにします。

続いて、下ボタンが押されたときの処理を追加します。

// 下キーが押された
if(gDownPush){
	if(!this.keyDisable){
		this.sit();
		for(var i = 0;i < docans.length;++i){
			this.docanDownEnter(docans[i]);
		}
	}
}
else{
	this.sitRelease();
}

キー操作不能状態時もしゃがみ状態を解放する必要があるので、
if文を調整しています。

下が押されたときは、しゃがみ処理を実行して、そうでないときは、
しゃがみ解放処理を実行するようにします。

続いて、しゃがみ処理関数を実装します。

しゃがみ処理関数の実装

/**
 * chapter43
 * 
 * マリオが大きい状態ならば座る状態にする
 * 
 */
Mario.prototype.sit = function(){
	// 大きい状態のみ
	if(this.canSit()){
		this.isSit = true;
		this.height = MAP_SIZE;
		this.textureHeight = MAP_SIZE * 2;
		this.posY += MAP_SIZE;
		this.updateMapPositionY(this.posY);
	}
}

マリオの画像を上から描画しているので、マリオがしゃがんだ際には、
しゃがんだサイズ分下に移動させる必要があるので、posYをマップサイズ分だけずらして、マップチップ座標を更新しています。

マリオがしゃがむことができるか判定する関数を別で実装したので、
中身を確認します。

/**
 * chapter43
 * 座れるか判定を返す
 */
Mario.prototype.canSit = function(){
	// でかい かつ しゃがんでいない かつ ジャンプ中でない
	return (this.isBig() && !this.isSit && !this.isJump);
}

条件はコメントに書いてある通りですね。

続いて、ドカンに入るときに、しゃがんだままの状態にして、
出る時にしゃがみ状態を解消する処理を書きます。

ドカンの処理

最初のドカンから出た時に一回だけ呼ばれる箇所で、
しゃがみ状態を解消する処理を書きます。

// しゃがみを解除する
if(this.docanFirstMoveDirection == DOCAN_DOWN && this.isBig()){
	this.releaseSitParam();
}
Mario.prototype.releaseSitParam = function(){
	this.height = MAP_SIZE * 2;
	this.textureHeight = this.height;
	this.posY -= MAP_SIZE;
	this.updateMapPositionY(this.posY);
	this.isSit = false;
}

だいたいこんな感じです。

全体はgithubを参照してください。

まとめ

そもそも作る際にしゃがみ画像が追加されることを考慮してなかったので、
画像を新しく作る羽目になったし、どうやれば効率よく画像を切り取れるかなど
考えていたため、不要な時間がかかってしまったところがアホだなと思った。

モチベーションの問題もあります。

そして、しゃがみ画像を作るのにも、「なんかおかしい」「なんかおかしい」というのを繰り返していたので、かなり時間がかかってしまった。

自分のだめなところしか見えない制作だった。