マリオステージ切り替え処理

マリオとステージ移動の実装(プログラミングでマリオを作る第51回)

今回は、ステージクリア後のステージ間移動処理の実装をしたいと思います。

実行結果は以下のようになります。

マリオステージ移動処理

ステージ名表示画面は、コンティニュー画面と同じなので、ステージを移動した時に、次のステージ用のマップチップや敵の設定をするのみになります。

今回実装する内容

1.ゴール後の得点処理から、ステージ移行画面へと移動する

2.敵やマップオブジェクトを次のステージのものに変更する

ステージ移行処理をどうやって実装するかがポイントですね。

では、実装していきます。

実装

const.js

constに必要な定数を書き込みます。

// chapter51
let GOAL_WAIT_CNT = 180;
let STAGE_TIMES = [(60 * 60 * 4),(60 * 60 * 4)];

ゴール後のスコア換算から次のステージ移動を行うまでに、時間があるので、
その定数を定義するのと、ステージ2を新しく実装するので、ステージ2の時間を新しく追加します。

mario.js

ステージ遷移を行うためにマリオクラスを修正します。

まず、ゴールスコア加算処理から、ステージ表示画面に移るまでの時間を管理するメンバー変数を定義します。

// chapter51
// ゴールアニメーションのためのタイマー
this.goalCnt = 0

おわび

chapter50のinit関数の中を間違えていたので、修正してください。

変数名と値が間違っていました。

// chapter50
// ゴールアニメーション状態を管理する	
this.goalAnimationState = INACTIVE;
// 重力など行動を止めるフラグ
this.isMarioStop = false;
this.goalPosX = 32 * 36;

// chapter51
this.goalCnt = 0

ゴール処理が終了した時の分岐の中身を追加します。

3秒待ったらステージ表示処理に入るようにします。

case GOAL_ANIMATION_END:
	if(this.goalCnt++ >= GOAL_WAIT_CNT){
		this.moveNextStage();
	}
	break;

分岐の中のmoveNextStage関数を書きます

/**
 * ステージクリア時に次のステージに遷移させる
 */
Mario.prototype.moveNextStage = function(){
	// とりあえず、これでいい
	gTotalStageNumber++;
	gSubWorldNumber++;
	// ステージ切り替え画面に遷移させる
	gState = PRE_STAGE;
}

gState変数を変更することで、mainの描画が切り替わるように処理を書いているので、そのままPRE_STAGEを代入します。

ステージ数は原作のマリオでは、ステージ1-4からはステージ2-1に切り替わりますが、とりあえず今は気にしないということで。

最後に、ステージによってゴールの位置(ゴールにマリオが吸い込まれる位置)が変更されるので、ゴール位置をセットする関数を作ります。

/**
 * マリオがゴールで消える位置を代入する
 * @param {*} goalPosX 
 */
Mario.prototype.setGoalPosition = function(goalPosX){
	this.goalPosX = goalPosX + (MAP_SIZE * 6);
}

マップチップを記録するファイルを用意する

ステージ2や3用のマップチップを変数として定義する必要がありますが、const定義ファイルであるconst.jsに定義すると中身が乱雑になるので、
新しくmap.jsを定義して、その中にマップチップを記録することにします。

map.js

let gMap12 = [
    [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,255,255,-1,-1,255,255,255,255,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,-1,-1,-1,255,255,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,48,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,255,255,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,48,48,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],
    [255,255,255,255,255,255,255,255,-1,-1,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,82,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,48,48,48,255,255,255,255,255,255,255,255,255,255,255,255,140,141,142,143],
    [255,255,255,255,-1,-1,-1,-1,80,80,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,33,33,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,33,33,33,255,255,255,255,255,255,255,255,255,80,80,80,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,48,48,48,48,255,255,255,255,255,255,255,255,255,255,255,255,156,157,158,159],
    [255,255,255,255,255,255,255,255,255,255,255,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,48,48,48,48,48,48,48,255,255,255,255,255,255,255,255,255,255,255,171,172,173,174,175],
    [255,255,255,255,255,255,255,255,255,255,255,-1,-1,-1,-1,-1,-1,62,63,-1,-1,-1,-1,-1,-1,-1,-1,62,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,62,63,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,63,255,48,48,48,48,48,48,48,48,255,255,255,255,255,255,255,255,255,255,255,187,188,189,190,191],
    [255,255,255,255,255,255,255,255,255,255,255,-1,-1,-1,-1,-1,-1,78,79,-1,-1,-1,-1,-1,-1,-1,-1,78,79,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,255,255,78,79,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,78,79,48,48,48,48,48,48,48,48,48,255,255,255,255,255,255,255,48,255,255,255,203,204,205,206,207],
    [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,-1,-1,113,113,113,113,113,113,113,113,113,113,113,113,113,-1,-1,-1,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,-1,-1,129,129,129,129,129,129,129,129,129,129,129,129,129,-1,-1,-1,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],
];

// 背景用のマップチップ
var gBackGroundMapChip12 = [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
  ];

ステージ切り替え処理

ステージ切り替え処理をmain.jsに書いていきますが、

まず、敵の切り替え処理を考えます。

ステージごとの敵の切り替え処理

はじめに敵のオブジェクトを作る時に多めに定義しておき、
多めに設定した、敵クラスを使わない場合は、処理フラグをオフにしておき、
処理させない
ようにします。

もちろん、ステージごとに敵のオブジェクトを生成してもokですが、
メモリを考えてこちらの実装にしました。

まず、敵の初期化関数で、stateを引数に持たせるようにします。
stateの引数にDeadを入れることで非活性にすることができます。

kuribo.js

/**
 * 初期化関数
 * @param {*} posX 
 * @param {*} posY 
 * @param {*} dir 
 * @param {*} state 
 */
Kuribo.prototype.init = function(posX,posY,dir,state = NORMAL_STATE){
	this.posX = posX;
	this.posY = posY;
	// chapter25敵の移動
	this.addPosX = 0;
	// chapter37
	this.addPosY = 0;
	// どのタイミングでアニメーションを切り替えるか
	this.animCnt = 0;
	// 切り出す始点のX座標
	this.animX = 0;
	this.animY = 0;
	this.direction = dir;
	// マップチップ座標
	this.rightMapX = 0;
	this.leftMapX = 0;
	this.upMapY = 0;
	this.downMapY = 0;
	// chapter27
	this.state = state;
	this.height = 16;
	this.deadCnt = 0;
	// chapter47
	this.score = 100;
}

stateをdefault引数にして、NORMAL_STATEを代入します。

こうすることで、他の部分を変更しなくて済みます。

nokonoko.jsも同様に変更してください。

main.js

stage2用の初期化分岐にて、ステージ2固有の初期化処理を行うことで、
ステージごとで敵の配置を変えることができます。

/**
 * ステージ2の敵の初期化
 */
function initStage2Enemy(){
  // kuribo
  gKuribos[0][0].init(1024,384,LEFT_DIR);
  gKuribos[0][1].init(1088,384,LEFT_DIR);
  // nokonoko
  gNokos[0][0].init(384,396,RIGHT_DIR);
  gNokos[0][1].init(192,396,LEFT_DIR);
}

マップチップの変更

マップチップの変更は、ステージ1から土管に入って別のステージに遷移した時と同様の処理でいけます。

/**
 * stage2用の初期化
 */
function initStage2(){
  // 敵の初期化
  initStage2Enemy();
  // 隠しブロックの出現を保存する
  if(gMario.hideBlockX != -1){
    replaceEmptyBoxMap(gMapChipCopy,gMario.hideBlockX,gMario.hideBlockY);
  }
  // マップ初期化
  gMapChip = JSON.parse(JSON.stringify(gMap12));
  gBackGroundMapChip = JSON.parse(JSON.stringify(gBackGroundMapChip12));
  gMario.init(0,384);
  
  // ゴール
  gGoal.init(91 * MAP_SIZE);
  gMario.setGoalPosition(91 * MAP_SIZE);
}

ゴール処理対応

ゴールの位置もステージによって異なるので、ゴールの位置も変更する必要があります。

goal.jsに初期関数を定義します。

goal.js

/**
 * 初期化
 * @param {*} posX 
 */
Goal.prototype.init = function(posX){
    this.posX = posX;
    this.flagY = 64;
    this.score = 0;
    this.castleFlagY = 273;
}

間違いとおわび

前回の書いた、flagAnimation関数が間違っていたので、修正してください。

変数名が間違っており、入れなければいけない値も違いました。

Goal.prototype.fragAnimation = function(mario){
    if(mario.goalAnimationState != INACTIVE){        
        // 地面まで達した場合
        if(this.flagY + 26 < 384){
            this.flagY += 3;    
        }
        else{
            this.flagY = 358;
        }
    }
}

これで、ゴール初期化処理は終わりです。

最後にステージ初期化処理の分岐の部分にstage2用の初期化関数を埋め込むことで、完成です。

/**
 * ステージ毎の初期化を行う
 */
function initStage(){
  switch(gTotalStageNumber){
    case 1:
      initStage1();
      break;
    case 2:
      initStage2();
      break;

  }
  initStageTimes(gTotalStageNumber);
}

まとめ

ステージの切り替えをどうするのかが、悩みどころです。

まぁ今回は一例ということで。

全体のcodeはgithubで確認してください。

感想

マップを作らないといけないので、少し時間がかかること以外をのぞいて、
ステージ遷移画面既に作ってあるので、実装自体は楽でした。

ステージの切り替え処理の実装は、ちゃんと考えないと後々困るところです。

次はタイトル画面を作って、マリオのステージ1をコピーすれば、目標としていたものが完成するはず!

Pocket
LINEで送る

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です