スコアとリトライ

スコアの表示

スコアを表示します。

このゲームには、敵を倒すなどの要素がありません。
なので、一定間隔で得点という形にします。

地中の四角が作られるタイミングで+100とします。
変数scoreを作ります。

    let wallCnt = 100;          // 壁発生タイミングカウント
    let score = 0;
    // 地面
    Crafty.e('Ground, 2D, Canvas, Color')
        .attr({x:0, y:250, w:500, h:50})
        .bind("EnterFrame", function(){
            if( Crafty.frame() %40 == 0 ){
                // 地中の四角
                Crafty.e('2D, Canvas, Color')
                    .attr({x:500, y:this.y, w:20, h:this.h})
                    .color('#a0826c')
                    .bind("EnterFrame", function(){
                        this.x -= 4;
                        if( this.x < -30 ){
                            this.destroy();
                        }
                    });
                score += 100;
                Crafty("Score").text("score: "+score);
            }
            if( Crafty.frame() > wallCnt ) setWall();
        })
        .color('#a0522d');
    // スコア
    Crafty.e("Score, DOM, 2D, Text")
        .attr({ x:10, y:3, w:280, h:20 })
        .textFont({size:'20px', weight:'bold'})
        .textColor('#eeeeee')
        .text("score: 0");

 

もう毎度おなじみの処理ですね。
問題がなければ次のように表示されます。

スコアを表示する

 

 

ポーズの切り替え

ゲームオーバーで処理を止めるために使っているポーズ機能をゲーム中に使ってみます。

Crafty.pause()は処理を止めます。
しかし、もう一度使うとポーズを解除します。
Z キーでポーズの ON/OFF をしてみましょう。

    // プレイヤー
    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;
        })
        .bind('KeyDown', function(e) {
            if( e.key == Crafty.keys.Z ) {
                console.log(Crafty.isPaused());
                Crafty.pause();     // ポーズする。ポーズ中なら解除
            }
        })
        .gravity('Ground');

 

好きなタイミングで Z キーを押してみましょう。
処理が止まりますね。
スクリーンショットを撮りたい時や動作チェックに使えます。
仕事でゲームを作っていた時には、コマ送り機能まで入れていました。

ポーズで処理を止める

 

ポーズの状態はCrafty.isPaused()で調べることができます。
ポーズ中なら true、違うなら false を返します。
何度か切り替えた結果をコンソールで見てみましょう。

ポーズの状態を調べる

true false で状態を取得できています。
1つ目の undefined はまだ一度もポーズを使っていないため、状態を保存する変数が作られていないのだと思います。

 

 

リトライを入れる

さあ、これで最後です。
ゲームオーバー後に Z キーを押すことでリトライさせます。

最後なので game.js の全コードです。
変更は3箇所あります。

Crafty.init(500,300, document.getElementById('game'));
Crafty.background('#101010');

Crafty.scene("main", function() {
    // プレイヤー
    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'});
            Crafty.e('2D, DOM, Text').attr({x:125, y:150, w:300})
                .text("Z キーを押してください").textColor('#00ff7f')
                .textFont({size:'18px'});
        })
        .bind('EnterFrame', function () {
            if( this.x < 0 ) this.x = 0;
            if( this.x > 500 - this.w ) this.x = 500 - this.w;
        })
        .bind('KeyDown', function(e) {
            if( e.key == Crafty.keys.Z ) {
                if( Crafty.isPaused() ){     // true:ポーズ中の時
                    Crafty.pause(); // ポーズ解除
                    Crafty.scene("main");
                }
            }
        })
        .gravity('Ground');
    let wallCnt = Crafty.frame() +100;    // 壁発生タイミングカウント
    let score = 0;
    // 地面
    Crafty.e('Ground, 2D, Canvas, Color')
        .attr({x:0, y:250, w:500, h:50})
        .bind("EnterFrame", function(){
            if( Crafty.frame() %40 == 0 ){
                // 地中の四角
                Crafty.e('2D, Canvas, Color')
                    .attr({x:500, y:this.y, w:20, h:this.h})
                    .color('#a0826c')
                    .bind("EnterFrame", function(){
                        this.x -= 4;
                        if( this.x < -30 ){
                            this.destroy();
                        }
                    });
                score += 100;
                Crafty("Score").text("score: "+score);
            }
            if( Crafty.frame() > wallCnt ) setWall();
        })
        .color('#a0522d');
    // スコア
    Crafty.e("Score, DOM, 2D, Text")
        .attr({ x:10, y:3, w:280, h:20 })
        .textFont({size:'20px', weight:'bold'})
        .textColor('#eeeeee')
        .text("score: 0");
    // 壁
    function setWall(){
        const hh = Crafty.math.randomInt(40, 85);   // 壁の高さ
        wallCnt += Crafty.math.randomInt(25, 100);  // 次の発生タイミング
        Crafty.e('Wall, 2D, Canvas, Color, Collision')
            .attr({x:500, y:250-hh, w:40, h:hh})
            .color('#ffa500')
            .bind("EnterFrame", function(){
                this.x -= 4;
                if( this.x < -50 ){
                    this.destroy();
                }
            });
    }
});
Crafty.scene("main");

 

「Z キーを押してください」のテキスト表示はもう慣れたものです。
新しいことは何もありません。

if( Crafty.isPaused() ){

ポーズの状態を調べています。
ポーズをするのはゲームオーバーの時だけです。
ですから、ゲームオーバー中はポーズされた状態です。
これを調べ、ポーズ中ならリトライの処理を行います。

Crafty.scene(“main”);

シーンの切り替えをしています。
といってもシーンは main しかありません。
つまり一度リセットをして再起動しているようなものです。

let wallCnt = Crafty.frame() +100;

壁の発生タイミングに今のフレーム数を加算しています。
システムのフレーム数を使って壁を発生させていたので、変な初期化が必要になってしまいました。
壁発生用のカウンタを用意した方がスマートでした。

 

それでは実行して、ゲームオーバー後にリトライできるかテストしてみて下さい。

ゲームオーバー後にリトライできるかテストする

 

 

完成です

これで完成です。お疲れさまでした。

次は自分で考えたゲームを作っても良いですね。
当然、このゲームを改良してみるのも良いです。

コインを出して、ゲットしたら得点を表示するなど
色々とやってみましょう。

 

 

『壁を飛び越せ』

ゲームを作ってみよう

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