たくさんのキャラクタを操作しよう (2/3)
作成:2012-09-30 15:49
更新:2012-09-30 15:49
更新:2012-09-30 15:49
■キャラクタの衝突判定
ゲームを作る時、重要になるのが「衝突判定」です。これは、2つのキャラクタが衝突したかどうかを調べる機能です。これを利用することで、例えば「敵キャラがタッチした」とか「発射したミサイルがぶつかった」とかいった処理が可能になります。
これには2つのメソッドが用意されています。「intersect」と「within」です。それぞれ以下のような働きをします。
キャラクタのグラフィックではなく、あくまで「領域」が重なっているかどうかでチェックする、という点に注意して下さい。グラフィックが描かれていない端っこの部分が重なっただけでもtrueが返されるので。
intersectは、領域がほんの少しでも触れていれば接触したとみなします。ですから、実際にやってみると「これ、まだ全然触ってないでしょ?」と思うものでも「触れた」と判断されることが多いでしょう。これに対し、withinは距離で判断するので、よりグラフィックとグラフィックの接触に近い判断ができます。ただし、これも機械的に距離で判断しますから、「グラフィックは触っているのに接触してると判断されない」というようなこともあります。
いずれにしても、これらの衝突判定は「グラフィックの内容は判断の基準にならない」という点を理解しておく必要があります。厳密にグラフィックとグラフィックが触れたかどうかを調べることはできない、という点を頭にいれておいて下さい。
では、実際の利用例を挙げておきましょう。下の例は、character.pngを読み込んだキャラクタを10個、ランダムに表示して動かすものです。これらは別のキャラクタに接触するとそこで停止します。ここでは、this.within(char_arr[i],50)というようにして、キャラクタどうしの中心が50ドット以内の距離にあれば接触したとみなしています。第2引数の数値を変更したり、あるいはwithinをintersectに変えたりして動きを確かめてみるとよいでしょう。
これには2つのメソッドが用意されています。「intersect」と「within」です。それぞれ以下のような働きをします。
《Sprite1》.intersect(《Sprite2》);Sprite1にSprite2が接触したかどうかを調べます。接触している場合はtrue、そうでない場合はfalseが返されます。「接触している」というのは、2つのSpriteの領域の一部が重なっているかどうかでチェックされます。キャラクタのグラフィックではなく、あくまで「領域」が重なっているかどうかでチェックする、という点に注意して下さい。グラフィックが描かれていない端っこの部分が重なっただけでもtrueが返されるので。
《Sprite1》.within(《Sprite2》, 距離 );これはSprite1とSprite2の中心地点の距離が第2引数の値より近づいたかどうかをチェックするものです。これもグラフィックとは関係なく、2つのSpriteの中心位置の距離を調べ、それによって衝突したかどうかを判断します。intersectは、領域がほんの少しでも触れていれば接触したとみなします。ですから、実際にやってみると「これ、まだ全然触ってないでしょ?」と思うものでも「触れた」と判断されることが多いでしょう。これに対し、withinは距離で判断するので、よりグラフィックとグラフィックの接触に近い判断ができます。ただし、これも機械的に距離で判断しますから、「グラフィックは触っているのに接触してると判断されない」というようなこともあります。
いずれにしても、これらの衝突判定は「グラフィックの内容は判断の基準にならない」という点を理解しておく必要があります。厳密にグラフィックとグラフィックが触れたかどうかを調べることはできない、という点を頭にいれておいて下さい。
では、実際の利用例を挙げておきましょう。下の例は、character.pngを読み込んだキャラクタを10個、ランダムに表示して動かすものです。これらは別のキャラクタに接触するとそこで停止します。ここでは、this.within(char_arr[i],50)というようにして、キャラクタどうしの中心が50ドット以内の距離にあれば接触したとみなしています。第2引数の数値を変更したり、あるいはwithinをintersectに変えたりして動きを確かめてみるとよいでしょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
enchant();
var char_arr = new Array();
window.onload = function(){
var game = new Game(1000, 700);
game.preload("character.png");
game.fps = 20;
game.onload = function(){
for(var i = 0;i < 10;i++){
var char1 = new Sprite(100, 100);
char1.image = game.assets["character.png"];
char1.x = Math.floor(Math.random() * 900);
char1.y = Math.floor(Math.random() * 600);
char1.dx = Math.floor(Math.random() * 10);
char1.dy = Math.floor(Math.random() * 10);
char1.flg = true;
char1.addEventListener(enchant.Event.ENTER_FRAME, function(){
if (this.flg){ this.frame = this.age % 2; }
this.x += this.dx;
this.y += this.dy;
if (this.x < 0 || this.x > game.width - 100){
this.dx *= -1;
}
if (this.y < 0 || this.y > game.height - 100){
this.dy *= -1;
}
for(var i = 0;i < 10;i++){
if (this != char_arr[i]){
if (this.within(char_arr[i],50)){
this.dx = 0;
this.dy = 0;
this.flg = false;
}
}
}
});
game.rootScene.addChild(char1);
char_arr[i] = char1;
}
game.rootScene.backgroundColor = "#ffaaaa";
}
game.start();
};
※関連コンテンツ
「初心者のためのenchant.jsゲームプログラミング入門」に戻る