前回マップの作成は完了しました。
今回はマップの障害物の判定について説明します。
前回作ったマップを元に説明をしていきますので
もし前回マップを作っていない方はマップを作るところから
行いましょう。
マップには移動できるところと移動できないところがあります。
RPGでも壁にぶつかるとキャラクターは壁の前から先へは移動できませんが、
マップ上の草にぶつかってもキャラクターはその先へ移動することができます。
この判断をゲーム内に組み込む必要があります。
コリジョンデータ
コリジョンデータ(collisionData)コリジョンというのは
「衝突」という意味があります。
前回enchant map editorで生成したマップデータに[collisionData]
のデータがあります。
この部分が衝突の有無を表します。
0の場合は「衝突なし」つまり通り抜けることができます。
1の場合は「衝突あり」で通り抜けることができません。
前回作ったマップの画像がこれ
コリジョンデータはこれです。
うっすらマップの画像がみて取れるのでわかりやすいと思います。
1の立っている部分が衝突判定有りのブロックです。
今回は地面とブロックの山は障害物に設定して有ります。
では実際にクマを配置して確認してみます。
※左右の矢印キーで動きます。
クマ移動サンプル 普通にブロックをすり抜けていきますね。
実は、衝突の判定(1)を設定しただけでは障害物にはならないのです。
実際通り抜けしないようにするためには、
「通り抜けができないブロックと当たった場合にクマの移動を制限する」
という処理が必要になります。
上の処理を実現するために、hitTest関数を利用します。
この関数は指定された座標に通り抜けできないブロックがあるかどうか
判定することができます。
実際の使い方は次の通りです。
1 2 3 |
if(map名.hitTest(x座標 , y座標 )){ //console.log("ここは通れない"); } |
map名は作成したmap名を指定します。
前回作ったマップの場合はbackgroundMapですね。
x座標、y座標は左上角を0としたゲーム画面の座標を指定します。
この関数を使ってクマの移動を制限すると
処理の流れは、次の処理になります。
- 移動キーが押される
- クマを移動させる前に移動先に障害物がなく、移動可能か確認
移動できる場合 :通常通り移動させる
移動できない場合:移動の処理を実施しないこれで壁を通り抜けできないようになります。
マップ衝突判定サンプル
実際のサンプルは次の通りです。
プログラムの内容は以下の通りです。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171// code.9leap.net default template// based on enchant.js v0.7.1enchant();window.onload = function(){var game = new Core(320, 320);game.preload('chara1.png');game.preload('map1.gif');game.fps = 15;//マップとの接触判定function bottom_collisionCheck(mapName,splite){if(mapName.hitTest(splite.x+32 ,splite.y + 16 )){console.log("通れない:"+ (splite.x + 32));return true;}else{return false;}}//クマ(男)Kuma_man = Class.create(Sprite,{initialize:function(x, y){Sprite.call(this, 32, 32);this.image = game.assets['chara1.png'];this.x = x;this.y = y;this.prey = y;this.ay = 15;this.frame = 0;this.jumpFlg = false;this.jumpingFlg = false;this.jumpPower = 10;this.walk = [0,1,0,2];game.rootScene.addChild(this);},//キーボード操作受け取り用onenterframe:function(){if (game.input.up && this.jumpingFlg === false) {this.jumpFlg = true;}if (game.input.right) {//→キーif(backgroundMap.hitTest(this.x+32 ,this.y + 17 )){}else{this.frame = this.walk[this.age%4];this.x += 3;this.scaleX = 1;}}if (game.input.left) {//←キーif(backgroundMap.hitTest(this.x-1 ,this.y + 17 )){}else{this.frame = this.walk[this.age%4];this.x -= 3;this.scaleX = -1;}}//=============//ジャンプ処理//=============if(this.jumpFlg){if(!this.jumpingFlg){this.jumpingFlg = true;this.prey = this.y;}else{//y座標を決める処理this.y = this.prey - this.jumpPower--;//y座標が衝突する場合while(backgroundMap.hitTest(this.x+16 ,this.y + 32 )){this.y = this.prey - (++this.jumpPower);if(!backgroundMap.hitTest(this.x+16 ,this.y + 32 )){this.y++;this.jumpingFlg = false;this.jumpFlg = false;this.jumpPower = 10;break;}}this.prey = this.y;}}//===========================================//足元に地面がない場合はジャンプ中とみなす//ただし上には飛べないのでjumpPowerは0とする//===========================================if(!backgroundMap.hitTest(this.x+16 ,this.y + 32 ) && this.jumpingFlg !== true){this.jumpFlg = true;this.jumpPower = 0;}}});game.onload = function(){//「M」キーを[aボタン]として使用するgame.keybind( 'M'.charCodeAt(0), 'a' );//========================// マップデータ//========================backgroundMap = new Map(16, 16);backgroundMap.image = game.assets['map1.gif'];backgroundMap.loadData([[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,35,2,35,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,35,2,2,2,35,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,35,2,2,2,2,2,35,35,35,35,35,35,35,35],[35,35,35,35,35,35,2,2,2,2,2,2,2,35,35,35,35,35,35,35],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[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,1,1,1,1,1,1,1,1,1,1,1,1]]);backgroundMap.collisionData = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0],[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,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,1,1,1,1]];//========================// マップを画面に表示//========================game.rootScene.addChild(backgroundMap);//========================// くまを画面に表示//========================kuma_man = new Kuma_man(240,240);};game.start();};
1. 前回作成したマップに障害物を追加して、接触判定を追加してみよう
1 .新しくマップを作成して、壁や障害物に赤初期判定を追加して、動作を確認しよう。