enchant.jsを勉強する5 得点アイテムと敵の配置
前回までで迷路をプレイヤーが動くことができるようになりました。
今回はゲームらしくアイテムの配置と敵の配置を行います。
このゲームの基本コンセプトは敵をよけながらポイントアイテムを取っていくということにしましょう。
ソース
*得点アイテムと敵エネミーを配置する。
enchant(); window.onload = function() { var game = new Game(320, 400); var tile = 16;//タイルのサイズ var point_num = 3; //得点アイテムの数 var enemy_num = 3; //エネミーの数 var enemy_spd = 1; //エネミーの初期スピード game.preload('map1.gif','chara0.gif','pad.png','icon.gif'); game.onload = function() { var m_data = new Array(); //表示用マップ領域 var m_hit = new Array(); //衝突判定用マップ領域 //マップの初期化 for (i = 0; i < 19; i++){ m_data[i] = new Array(); m_hit[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; m_hit[i][ii] = flag-1; //壁の時1、壁以外の時0を入れる。 } } //迷路作成 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; m_hit[i+dy[rand]][ii+dx[rand]] = 1; //指定した方向の通路を壁で埋める。 } } var map = new Map(16, 16); map.image = game.assets['map1.gif']; map.loadData(m_data); map.collisionData = m_hit; game.rootScene.addChild(map); //Pad設定 var pad = new Pad(); // Padを追加 pad.x = 0; // x座標 pad.y = 305; // y座標 game.rootScene.addChild(pad); // シーンに追加 //プレイヤーの初期化 var player = new Sprite(16, 24); player.image = game.assets['chara0.gif']; player.x = tile*1; player.y = 8; game.rootScene.addChild(player); player.direction = 0; player.walk=0; var p_spd = 2; //プレイヤーの移動スピード var a_spd = 3; //プレイヤーのアニメーションスピード player.addEventListener('enterframe', function(e) { this.xx = this.x; this.yy = this.y; if (game.input.left){this.xx = this.x - p_spd;this.direction = 1;} if (game.input.right){this.xx = this.x + p_spd;this.direction = 2;} if (game.input.up) {this.yy = this.y - p_spd;this.direction = 3;} if (game.input.down){ this.yy = this.y + p_spd;this.direction = 0;} //移動予定地this.xx,this.yyが壁かどうかを調べる。 var asobi = 4; //遊び幅 if(!map.hitTest(this.xx+asobi,this.yy+8+asobi)&&!map.hitTest(this.xx+15-asobi,this.yy+8+asobi)&&!map.hitTest(this.xx+asobi,this.yy+23-asobi)&&!map.hitTest(this.xx+15-asobi,this.yy+23-asobi)){this.x=this.xx;this.y=this.yy;} if (!(game.frame % a_spd)){this.walk++;} if(this.walk == 3){this.walk = 0;} this.frame = this.direction*6 + this.walk; }); var score = 0; //点数の初期化 var state = new Label(); state.text = "Score:0"; state.color = "#000000"; state.x = 200; state.y = 310; game.rootScene.addChild(state); state.addEventListener('enterframe', function(e) { state.text = "Score:" + score; }); //得点アイテム作成関数 var create_point = function(e){ var point = new Sprite(16, 16); point.image = game.assets['icon.gif']; point.frame = 10; var check = 1; while(check){ point.x = Math.floor(Math.random()*17+1) * 16; //X座標を乱数で入力 point.y = Math.floor(Math.random()*17+1) * 16; //Y座標を乱数で入力 if(!map.hitTest(point.x+8,point.y+8)){check=0;} //指定した座標が壁だったらやりなおす。 } //プレイヤーが接触したときの処理 point.addEventListener('enterframe', function(e) { if(this.intersect(player)){ score += 1; var check = 1; while(check){ this.x = Math.floor(Math.random()*17+1) * 16; //X座標を乱数で入力 this.y = Math.floor(Math.random()*17+1) * 16; //Y座標を乱数で入力 if(!map.hitTest(this.x+8,this.y+8)){check=0;} //指定した座標が壁だったらやりなおす。 } } }); return point; } //エネミー作成関数 var create_enemy = function(e){ var enemy = new Sprite(16, 16); enemy.image = game.assets['icon.gif']; enemy.frame = 11 enemy.direction = Math.floor(Math.random()*4); //初期の移動方向を指定 var check = 1; while(check){ enemy.x = Math.floor(Math.random()*17+1) * 16; //X座標を乱数で入力 enemy.y = Math.floor(Math.random()*17+1) * 16; //Y座標を乱数で入力 if(!map.hitTest(enemy.x+8,enemy.y+8)){check=0;} //指定した座標が壁だったらやりなおす。 } //エネミーの行動処理 enemy.addEventListener('enterframe', function(e) { if(this.intersect(player)){ score = 0; } this.xx = this.x; this.yy = this.y; if(this.direction == 0){this.yy = this.y+enemy_spd;} if(this.direction == 1){this.xx = this.x-enemy_spd;} if(this.direction == 2){this.xx = this.x+enemy_spd;} if(this.direction == 3){this.yy = this.y-enemy_spd;} if(!map.hitTest(this.xx+1,this.yy+1)&&!map.hitTest(this.xx+14,this.yy+14)){ this.x = this.xx; this.y = this.yy; }else{ this.direction = (this.direction + Math.floor(Math.random()*3))%4; } }); return enemy; } for (var i = 0; i < point_num; i++) { //得点アイテム表示準備。 var point = create_point(); game.rootScene.addChild(point); } for (var i = 0; i < enemy_num; i++) { //エネミー表示準備。 var enemy = create_enemy(); game.rootScene.addChild(enemy); } //難易度調整 一定時間毎に敵の速度を上げる。 game.addEventListener('enterframe', function(e) { if(this.frame == 900){enemy_spd++;} if(this.frame == 1800){enemy_spd++;} if(this.frame == 5400){enemy_spd++;} }); } game.start(); }
var check = 1; while(check){ point.x = Math.floor(Math.random()*17+1) * 16; //X座標を乱数で入力 point.y = Math.floor(Math.random()*17+1) * 16; //Y座標を乱数で入力 if(!map.hitTest(point.x+8,point.y+8)){check=0;} //指定した座標が壁だったらやりなおす。 }
アイテムを配置します。
外壁の内側から無作為のXY座標を選びます。
このXY座標が壁意外になるまで同じ処理を繰り返します。
//プレイヤーが接触したときの処理 point.addEventListener('enterframe', function(e) { if(this.intersect(player)){ score += 1; var check = 1; while(check){ this.x = Math.floor(Math.random()*17+1) * 16; //X座標を乱数で入力 this.y = Math.floor(Math.random()*17+1) * 16; //Y座標を乱数で入力 if(!map.hitTest(this.x+8,this.y+8)){check=0;} //指定した座標が壁だったらやりなおす。 } } });
プレイヤーが接触したときの処理です。
プレイヤーが接触するとスコアが一点増えます。
また、再びランダムでアイテムを画面のどこかに配置します。
for (var i = 0; i < point_num; i++) { //得点アイテム表示準備。 var point = create_point(); game.rootScene.addChild(point); }
アイテムを実際に配置します。
アイテムの数はpoint_numで設定します。
if(this.intersect(player)){ score = 0; }
エネミーがプレイヤーと接触した場合の処理です。ここでは暫定的にスコアを0にしています。
if(!map.hitTest(this.xx+1,this.yy+1)&&!map.hitTest(this.xx+14,this.yy+14)){ this.x = this.xx; this.y = this.yy; }else{ this.direction = (this.direction + Math.floor(Math.random()*3))%4; }
移動予定先が壁かどうかチェックをしています。
移動先が壁ではい場合移動します。壁だった場合は、ランダムに現在向いている方向以外の3方向のいずれかを向きます。
//難易度調整 一定時間毎に敵の速度を上げる。 game.addEventListener('enterframe', function(e) { if(this.frame == 900){enemy_spd++;} if(this.frame == 1800){enemy_spd++;} if(this.frame == 5400){enemy_spd++;} });
ゲームが進む毎に難易度が上昇します。
ゲーム開始から900フレーム(30秒)経過すると敵のスピードが1段階上昇します。
1分後と3分後にも同様の処理を行います。
次回は敵に衝突したときにゲームオーバーの画面を出したいと思います。
今回のサンプルはこちら