当たり判定とゲームオーバー

プレイヤーと壁の当たり判定

プレイヤーと壁の当たり判定を入れます。
当たり判定はワクワクしますね。

当たり判定はプレイヤー側に入れます。
色の付いた行を追加・変更しましょう。

    // プレイヤー
    Crafty.sprite(70,78,"alien2.png",{Alien:[0,0]});
    Crafty.e('Alien,2D,Canvas,Twoway,Gravity,SpriteAnimation,Collision,WiredHitBox')
        .attr({x:50, y:50})
        .twoway(300, 300)       // 移動速度, jump力
        .reel('walk',300,[[0,0],[1,0]])
        .animate('walk', -1)
        .onHit('Wall', function () {  // 壁に当たったら
            Crafty.pause();           // ポーズする
        })
        .gravity('Ground');

 

壁 Wall との当たり判定を見て、当たったらポーズしています。

Collisionは当たり判定 onHit を有効にします。

WiredHitBoxは当たり判定の範囲を赤い枠で表示します。

 

プレイヤーの赤い枠で当たり判定が行われています。
よく観察してみると、プレイヤーと壁の絵が離れていても当たったことになっています。(一番右の絵)

壁とプレイヤーの当たり判定を観察する

 

今回のようなアクションゲームでは、当たり判定の粗さがプレイヤーを不快にさせます。
見た目でしっかりと当たっていることが大切です。

これはプレイヤーの当たりを小さくすることで対応できます。
絵とまったく同じ形の当たり判定でなくてもいいのです。
プレイヤーの当たりが小さい、つまり、プレイヤーが有利になることならば不満にならないからです。

 

 

当たりの範囲を指定

プレイヤーの当たり判定の範囲を変更します。
1行追加します。

    // プレイヤー
    Crafty.sprite(70,78,"alien2.png",{Alien:[0,0]});
    Crafty.e('Alien,2D,Canvas,Twoway,Gravity,SpriteAnimation,Collision,WiredHitBox')
        .attr({x:50, y:50})
        .twoway(300, 300)       // 移動速度, jump力
        .reel('walk',300,[[0,0],[1,0]])
        .animate('walk', -1)
        .collision(15,10, 55,10, 55,60, 15,60)     // 当たり判定の範囲を変更
        .onHit('Wall', function () {  // 壁に当たったら
            Crafty.pause();           // ポーズする
        })
        .gravity('Ground');

 

範囲を指定する方法では、対象となる壁側にも Collision 設定が必要になります。
ついでに WiredHitBox も入れましょう。

    // 壁
    function setWall(){
        const hh = Crafty.math.randomInt(40, 85);   // 壁の高さ
        wallCnt += Crafty.math.randomInt(25, 100);  // 次の発生タイミング
        Crafty.e('Wall, 2D, Canvas, Color, Collision, WiredHitBox')
            .attr({x:500, y:250-hh, w:40, h:hh})
            .color('#ffa500')
            .bind("EnterFrame", function(){
                this.x -= 4;
                if( this.x < -50 ){
                    this.destroy();
                }
            });
    }

 

確認してみましょう。

絵の中に赤い枠がある

上図のように、絵の中に赤い枠があれば、見た目の重なりもはっきり分かりますね。

 

範囲の座標指定は次のようになっています。

.collision(15,10, 55,10, 55,60, 15,60)

当たり範囲の座標指定

今回、四角になるように指定しましたが、もっと角を多くすることもできます。
x,y 座標の指定を増やすだけです。
ただし、右回り、または、左回りで指定します。
また、凹みができる形はダメなようです。

 

 

ゲームオーバーの表示

当たり判定ができたので、ゲームオーバーを表示します。

プレイヤーの中に入れます。

    // プレイヤー
    Crafty.sprite(70,78,"alien2.png",{Alien:[0,0]});
    Crafty.e('Alien,2D,Canvas,Twoway,Gravity,SpriteAnimation,Collision')
        .attr({x:50, y:50})
        .twoway(300, 300)       // 移動速度, jump力
        .reel('walk',300,[[0,0],[1,0]])
        .animate('walk', -1)
        .collision(15,10,  55,10,  55,60, 15,60)     // 当たり判定の範囲を変更
        .onHit('Wall', function () {  // 壁に当たったら
            Crafty.pause();           // ポーズする
            Crafty.e('2D, DOM, Text').attr({x:125, y:90, w:300})
                .text("GAME OVER").textColor('#00ff7f')
                .textFont({size:'36px', weight:'bold'});
        })
        .gravity('Ground');

 

WiredHitBoxはもういらないので外しました。
壁側の WiredHitBox も外しましょう。

壁に当たると次のように GAME OVER の表示が行われます。

壁と当たったらゲームオーバーを表示する

 

 

プレイヤーが画面外へ出ないように

プレイヤーが画面外へ出ないように変更します。

    // プレイヤー
    Crafty.sprite(70,78,"alien2.png",{Alien:[0,0]});
    Crafty.e('Alien,2D,Canvas,Twoway,Gravity,SpriteAnimation,Collision')
        .attr({x:50, y:50})
        .twoway(300, 300)       // 移動速度, jump力
        .reel('walk',300,[[0,0],[1,0]])
        .animate('walk', -1)
        .collision(15,10,  55,10,  55,60, 15,60)     // 当たり判定の範囲を変更
        .onHit('Wall', function () {  // 壁に当たったら
            Crafty.pause();           // ポーズする
            Crafty.e('2D, DOM, Text').attr({x:125, y:90, w:300})
                .text("GAME OVER").textColor('#00ff7f')
                .textFont({size:'36px', weight:'bold'});
        })
        .bind('EnterFrame', function () {
            if( this.x < 0 ) this.x = 0;
            if( this.x > 500 - this.w ) this.x = 500 - this.w;
        })
        .gravity('Ground');

 

画面外へ出ないかチェックしてみて下さい。
壁に当たってしまってチェックできない時は、壁の出現をコメントにしてから確認しましょう。

地面の処理の中の次の行をコメントにすれば、壁は出てきません。
if( Crafty.frame() > wallCnt ) setWall();

 

 

『壁を飛び越せ』

ゲームを作ってみよう

  1. 壁を飛び越せに挑戦
  2. 地面と壁のスクロール
  3. 当たりとGAMEOVER
  4. スコアとリトライ