ゴブリンを倒す
当たり判定を取得する
PlayCanvasの物理エンジンを利用して、"当たった瞬間"を取得します。enemy.jsを以下のように上書きしてください
var Enemy = pc.createScript('enemy');
/*attributesに右、左それぞれの移動量を定義*/
Enemy.attributes.add("RIGHT_MOVE",{type:"number",default:0.01});
Enemy.attributes.add("LEFT_MOVE",{type:"number",default:-0.01});
// initialize code called once per entity
Enemy.prototype.initialize = function() {
/*カウンタ初期化*/
this.count = 0;
/*左右移動を変更するインターバル*/
this.change_interval = parseInt(50 + Math.random() * 20,10);
/*どちらに進むか*/
this.movefor = (Math.random() > 0.4)? this.RIGHT_MOVE : this.LEFT_MOVE;
/*衝突した際のイベントハンドラ*/
this.entity.collision.on("collisionstart",this._colstart,this);
};
// update code called every frame
Enemy.prototype.update = function(dt) {
/*毎フレーム加算する*/
this.count ++;
/*インターバルごとに向きをランダムで変更する*/
if(this.count % this.change_interval === 0){
this.movefor = (Math.random() > 0.4)? this.RIGHT_MOVE : this.LEFT_MOVE;
}
/*指定した方向へ移動*/
this.entity.translate(this.movefor,0,0);
/*移動方向に合わせてspriteの向きを変更*/
this.setDirection(this.movefor);
};
/*ベクトルに応じてspriteの向きを変更するメソッド 引数:x軸の移動量*/
Enemy.prototype.setDirection = function(accu) {
this.entity.sprite.flipX = (accu < 0);
};
/*衝突した瞬間に呼ばれるコールバック*/
Enemy.prototype._colstart = function(ev){
if(ev.other.tags.has("player")){//衝突したentityが"player"tagを所持していたら
console.log("hit");//コンソールにhitと表示
}
};
[コードの解説]
16行目で、collisionコンポーネント内のon()メソッドから、衝突時のイベントハンドラを設定します。
第一引数はイベント名、第二引数はコールバック関数、第三引数はコールバック関数でのスコープを渡します。
"collisionstart"イベントは衝突した瞬間呼び出されます。
呼び出されたコールバック関数は42行目以降に記述してあり、引数は衝突してきたエンティティを返します。
エンティティがSandyちゃんの場合、"player"というtagが付与してあるため、43行目のif文で分類可能です。
衝突したらコンソールにhitと出力します
保存して実行し、launchの画面でブラウザのコンソールを開いてください。
参考:ブラウザコンソールを開く
コンソールを起動したら、ゴブリンに衝突するたびに、コンソールに"hit"と表示されることを確認してください
ここまで出来たら、enemy.jsの44行目を以下のように書き換えてみましょう
this.entity.destroy();
保存して実行してみましょう
衝突後、ゴブリンは正しく消滅したでしょうか?
アニメーションを再生してから消滅させる
先ほど作成したゴブリンのアニメーションを再生してからdestroyするような処理に書き換えましょう
enemy.jsを以下のように書き換えます
var Enemy = pc.createScript('enemy');
/*attributesに右、左それぞれの移動量を定義*/
Enemy.attributes.add("RIGHT_MOVE",{type:"number",default:0.01});
Enemy.attributes.add("LEFT_MOVE",{type:"number",default:-0.01});
// initialize code called once per entity
Enemy.prototype.initialize = function() {
/*カウンタ初期化*/
this.count = 0;
/*左右移動を変更するインターバル*/
this.change_interval = parseInt(50 + Math.random() * 20,10);
/*どちらに進むか*/
this.movefor = (Math.random() > 0.4)? this.RIGHT_MOVE : this.LEFT_MOVE;
/*衝突した際のイベントハンドラ*/
this.entity.collision.on("collisionstart",this._colstart,this);
/*死んだかどうか*/
this.isdie = false;
};
// update code called every frame
Enemy.prototype.update = function(dt) {
if(!this.isdie){//生きている状態
/*毎フレーム加算する*/
this.count ++;
/*インターバルごとに向きをランダムで変更する*/
if(this.count % this.change_interval === 0){
this.movefor = (Math.random() > 0.4)? this.RIGHT_MOVE : this.LEFT_MOVE;
}
/*指定した方向へ移動*/
this.entity.translate(this.movefor,0,0);
/*移動方向に合わせてspriteの向きを変更*/
this.setDirection(this.movefor);
}else{//死んでいる状態
if (!this.entity.sprite._currentClip._playing){//現在再生しているclipの再生が終了したら
/*自分自身を削除する*/
this.entity.destroy();
}
}
};
/*ベクトルに応じてspriteの向きを変更するメソッド 引数:x軸の移動量*/
Enemy.prototype.setDirection = function(accu) {
this.entity.sprite.flipX = (accu < 0);
};
/*衝突した瞬間に呼ばれるコールバック*/
Enemy.prototype._colstart = function(ev){
if(ev.other.tags.has("player")){//衝突したentityが"player"tagを所持していたら
this.die();
}
};
/*自分自身が死ぬときの処理 */
Enemy.prototype.die = function(){
/*isdieフラグを立たせる*/
this.isdie = true;
/*RigidbodyとCollisionを切る*/
this.entity.rigidbody.enabled = false;
this.entity.collision.enabled = false;
/*deathのアニメーションクリップを再生*/
this.entity.sprite.play("death");
};
[コードの解説]
Scriptコンポーネントのメンバに、isdieという死んでいるかどうかを表す変数を追加しました。
衝突した際にisdieをtrueにし、rigidbody,collisionの機能をoffにします。
また、衝突した瞬間にdeathアニメーションの再生も行います。
update内ではisdieの値を監視しており、死亡したときは移動処理等は停止します。
spriteコンポーネント内のcurrentClipより、現在再生しているanimation clipの情報を取得し、アニメーションの再生が終了したところで自分自身を削除します。
保存して実行してみましょう
正しくアニメーションが動いた後に消滅したことが確認出来たらOKです
コメント
0件のコメント
サインインしてコメントを残してください。