enchant.jsを勉強する3 Map機能を使い迷路を作る
ゲームを作る際に詰まる点にたいてい画像関連が混じります。
画像の移動、衝突判定などを行ってきましたが、ゲームを作成する際にはマップというのが必要になります。
マップはRPGならフィールドを表示するのにつかいますし、アクションゲームでも面データとして必要です。
これはマップデータを読み込んで、そのデータを読み込んで画像を配置する必要があるのですが、enchant.jsではmapオブジェクトというので管理されています。
このMapについての詳しい情報はサンプルのRPGを見るとわかりやすいのですが、それを丁寧に解説しているサイトがあります。
enchant.jsのサンプルコードを解読する(RPG編その1)
マップという概念を丁寧に説明しているのでお勧めです。
丁寧な説明は上記サイトに任せてとりあえず簡単なマップの説明をします。
*簡単なマップ表示サンプル。
enchant(); window.onload = function() { var game = new Game(320, 320); game.preload('map1.gif'); game.onload = function() { var map = new Map(16, 16); //16*16pxのマップタイルでマップを作成 map.image = game.assets['map1.gif']; //マップの画像を読み込む map.loadData([ //マップの画像を読み込む [0,0,0,0,1], [0,0,0,0,1], [0,0,1,1,1], [0,0,1,0,1], [0,0,1,0,1] ]); game.rootScene.addChild(map); //マップを表示 } game.start(); }
サンプルとなるフォルダにenchant.js付属のmap1.gifをコピーしておいてください。
var map = new Map(16, 16);
という命令で一つのタイルが16*16に指定されたマップオブジェクトを作成しています。そしてそのマップに使う画像を
map.image = game.assets[‘map1.gif’];
で読み込んでいます。
ではマップデータを読み込みましょう。
map.loadData([ //マップの画像を読み込む
[0,0,0,0,1],
[0,0,0,0,1],
[0,0,1,1,1],
[0,0,1,0,1],
[0,0,1,0,1]
]);
loadDataという命令で、マップデータの配列を読み込んでいます。
これだけでマップの読み込みは終了です。簡単ですね。またこの配列は[Y座標][X座標]という形で読み込まれます。
中の数字がマップに使われるチップの番号です。今回は一番左とその隣のチップを使いました。
最後にgame.rootScene.addChild(map);で画面にマップを出力すれば完成です。
*本題。迷路を作る。
では実際に迷路を作ってみましょう。
今回は迷路作成として一番シンプルな棒倒し法という手法でマップを作ります。
*迷路自動作成(棒倒し法)
enchant(); window.onload = function() { var game = new Game(320, 320); game.preload('map1.gif'); game.onload = function() { var m_data = new Array(); //マップの初期化 for (i = 0; i < 19; i++){ m_data[i] = new Array(); for (ii = 0; ii < 19; ii++){ var flag=2; if(i>0 && i<18 && ii>0 && ii<18){ if(i%2 || ii%2){ flag=1; } } m_data[i][ii] = flag; } } //迷路作成 dx = [1,0,-1,0]; dy = [0,1,0,-1]; for(i = 2;i < 18; i+=2){ for(ii = 2;ii < 18; ii+=2){ var r=3; if(i==2){r=4;} //一番上のみ上の方向を追加。 var rand = Math.floor(Math.random()*r); m_data[i+dy[rand]][ii+dx[rand]] = 2; //指定した方向の通路を壁で埋める。 } } var map = new Map(16, 16); map.image = game.assets['map1.gif']; map.loadData(m_data); game.rootScene.addChild(map); } game.start(); }
まずマップデータをvar m_data = new Array();で初期化します。
さて、この後マップにデータを埋め込んでいきますが
//マップの初期化 for (i = 0; i < 19; i++){ m_data[i] = new Array(); for (ii = 0; ii < 19; ii++){ var flag=2; if(i>0 && i<18 && ii>0 && ii<18){ if(i%2 || ii%2){ flag=1; } } m_data[i][ii] = flag; } }
マップのサイズは19*19です。
まずはマップのX座標かY座標が0または18の場合は壁で埋めます(外周)
さらに、内側に2マス毎に壁を配置します。
//迷路作成 dx = [1,0,-1,0]; dy = [0,1,0,-1]; for(i = 2;i < 18; i+=2){ for(ii = 2;ii < 18; ii+=2){ var r=3; if(i==2){r=4;} //一番上のみ上の方向を追加。 var rand = Math.floor(Math.random()*r); m_data[i+dy[rand]][ii+dx[rand]] = 2; //指定した方向の通路を壁で埋める。 } }
そして次の部分で迷路を実際に作成しています。
内側の壁一つにつき、一番上のみ壁を中心とした上下左右のどこかに壁を配置します。一番上以外は下左右のいずれかに壁を配置します。
そうすると迷路が完成します。
サンプルのページを作成しました。読み込み直すたびに迷路が更新されます。
http://techblog.55w.jp/sample/maze/
では次回はこれに衝突判定をつけてみようかと思います。