前回(enchant.jsで熊が動くまでをより理解するためのTips)の熊が横にスライドするサンプルにさらに基礎的な要素を追加していきます。
やること
それぞれ両端に二体の熊を配置し中心に移動させ、衝突後振り向いて前進し画面外へ消えていくようにする。
前回のサンプルに加えること
・キャラクターの複数配置
・キャラクターの初期位置
・2体のキャラクターに見た目の違いをつける
・キャラクターの反転
・キャラクター同士の衝突判定
・イベントの削除
キャラクターの複数配置
Spriteを2個生成して配置するだけ。
enchant();
window.onload = function(){
var core = new Core(320,320);
core.preload("chara1.png");
core.onload = function(){
//一体目の熊
var chara = new Sprite(32,32);
chara.image = core.assets["chara1.png"];
//二体目の熊
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
core.rootScene.addChild(chara);
core.rootScene.addChild(chara2);
}
core.start();
}
熊の初期位置(x,y)
このままだと熊2体が重なってしまいよくわからないので熊の初期位置を変更します。
x,yプロパティでそれぞれx軸の位置、y軸の位置を指定できます。
以下のように指定します。
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
chara2.x = 300;//x座標の位置指定設定
2体の熊に見た目の違いをつける(frame)
同じ色、同じ形の熊だと個性がないので一体の熊を色違いにします。
今利用しているのは下画像の一番左上の熊です。
1枚の絵に何体も熊が描いてあります。
ここから左上を基準として32*32のサイズ分を切り取ってキャラクター画像として使用しています。
var chara2 = new Sprite(32,32);
左上の熊以外を使いたい時にはframeプロパティを利用してフレームインデックスの設定を行います。
Spriteと同じ横幅と高さを持ったフレームがenchant.Sprite#imageプロパティの画像に左上から順に 配列されていると見て, 0から始まるインデックスを指定することでフレームを切り替える. 数値の配列が指定された場合、それらを毎フレーム順に切り替える。 ループするが、null値が含まれているとそこでループをストップする。
frameプロパティの初期値は0なのでこれを以下のように指定することで画像を切り替えることができます。
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
chara2.x = 300;
chara2.frame = 5;//フレームインデックスの設定
一番左上を0とした時に5番目は白い熊になるので、二体目の熊の見た目は白くなります。
熊の反転(scaleX,scaleY)
お互いの熊を向き合う形で配置したいので一体を逆方向に向かせます。
scaleX,scaleYはそれぞれスプライトの横幅、縦幅を指定するプロパティですが以下のように値をマイナスに設定することで画像の反転も行うことができます。
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
chara2.x = 300;
chara2.frame = 5;
chara2.scaleX = -1;//Spriteの反転設定
中央に向かって二体の熊を歩かせる
二体の熊にそれぞれ前進するイベントを加えます。
一体目は前回と同じ、二体目は逆方向なので加算ではなく減算して移動させます。
enchant();
window.onload = function(){
var core = new Core(320,320);
core.preload("chara1.png");
core.onload = function(){
//一体目の熊
var chara = new Sprite(32,32);
chara.image = core.assets["chara1.png"];
//二体目の熊
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
chara2.frame = 5;//わかりやすいようにキャラ色変更
chara2.x = 300;//スプライトの初期位置(x座標)
chara2.scaleX = -1;//スプライトの横幅を変更する。マイナスを設定することでスプライト反転
//熊の配置
core.rootScene.addChild(chara);
core.rootScene.addChild(chara2);
//動かす
chara.addEventListener("enterframe", function(){
this.x += 1;
});
chara2.addEventListener("enterframe", function(){
this.x -= 1;
});
}//core.onload
core.start();
}//window.onload
これで二体の熊が中央に向かって前進しそのまますれ違って画面外へ消えていくようになります。
二体の熊の衝突判定
今のままではすれ違ったまま通過してしまうので二体が衝突した時にイベントを発生させるようにします。
衝突判定には二種類 intersect(矩形),within(円形) がありますが今回はintersectを利用します。
衝突判定はイベントリスナとして以下のように追加します。
obj.addEventListener("enterframe",function(){
if(obj.intersect(obj2)) {//主体となるSprite(obj1)と衝突対象となるSprite(obj2)、逆になっても同じです。
//衝突した時の処理
}else{
//衝突してない時の処理
}
});
現在のサンプルを利用した時、具体的には下記のようになります。
chara.addEventListener("enterframe",function(){
chara.x += 1;
if(chara.intersect(chara2)) {
chara.x = 0;//衝突したら初期位置に戻る
}
});
衝突後のイベント変更(イベントの削除・追加)
衝突後、お互いにそっぽを向いて逆方向に歩かせたい場合、現在の前進イベントを
一度解除しなくてはいけません。
イベントの追加はaddEventListenerで行いますが削除はremoveEventListenerでおこないます。
removeEventListenerで現在動いているイベントの削除を行うには引数にイベントタイプと変数に登録された関数(イベントリスナ)を渡します。
実行対象.removeEventListener("何をきっかけに消す?",削除対象を含んだイベントリスナ)
よって、予め実行するイベント(ここでは前進するイベント)の関数を変数に代入しておく必要があります。
常に実行する前進する設定と、ある一定のタイミングで発動するイベント削除の設定を変数内に格納し、この動作をaddEventListenerで呼びます。
※ここ勉強不足ですごめんなさい。追記できるようにします。
具体的には以下のようになります。
//熊1の動き関数
var chara_move = function(){
chara.x += 1;//前進
if(chara.intersect(chara2)) {//衝突した際の処理
chara.removeEventListener("enterframe",chara_move);//実行中のイベントの削除を行う
chara.scaleX = -1;//削除後に振り向く
chara.addEventListener("enterframe",function(){
chara.x -= 1;//逆走する新たなイベントを実行
});
}
}
//イベントの実行
chara.addEventListener("enterframe",chara_move);
例の熊さん同士を衝突させて不仲にさせる
enchant();
window.onload = function(){
var core = new Core(320,320);
core.preload("chara1.png");
core.onload = function(){
//一体目の熊
var chara = new Sprite(32,32);
chara.image = core.assets["chara1.png"];
core.rootScene.addChild(chara);
//二体目の熊
var chara2 = new Sprite(32,32);
chara2.image = core.assets["chara1.png"];
chara2.frame = 5;//わかりやすいようにキャラ色変更
chara2.x = 300;//スプライトの初期位置(x座標)
chara2.scaleX = -1;//スプライトの横幅を変更する。マイナスを設定することでスプライト反転
core.rootScene.addChild(chara2);
//熊1の動き関数
var chara_move = function(){
chara.x += 1;
if(chara.intersect(chara2)) {
chara.removeEventListener("enterframe",chara_move);
chara.scaleX = -1;
chara.addEventListener("enterframe",function(){
chara.x -= 1;
});
}
}
//熊2の動き関数
var chara2_move = function(){
chara2.x -= 1;
if(chara.intersect(chara2)) {
chara2.removeEventListener("enterframe",chara2_move);
chara2.scaleX = 1;
chara2.addEventListener("enterframe",function(){
chara2.x += 1;
});
}
}
chara.addEventListener("enterframe",chara_move);
chara2.addEventListener("enterframe",chara2_move);
}//core.onload
core.start();
}//window.onload