キャンディとスコア

ゲームオーバーを作る

サクッとゲームオーバーを作ります。
ダメージが 100 以上になったらゲームオーバーにします。

隕石を落とす処理を変更します。

<script>
    // 隕石を落とす
    function obj_drop(){
        Crafty.e("meteor, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                //Crafty.pause();     // すべてを止める
                damage += 10;
                Crafty("Damage").text("DAMAGE: "+damage);   // ダメージ表示更新
                if( damage >= 100 ){
                    Crafty.pause();
                    Crafty.e('2D, DOM, Text')
                        .attr({x:130, y:150, w:300})
                        .text("GAME OVER").textColor('#00ff7f')
                        .textFont({size:'40px', weight:'bold'});
                }
            })
            .bind('EnterFrame', function () {
                this.y += 10;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
</script>

 

次のようになります。

ダメージが100以上でゲームオーバー

 

追加したところを見てみましょう。
ダメージが 100 以上になったらすべての処理を止め
ゲームオーバーを表示しているだけです。

ゲームオーバーの変更点

今まで何度もしてきたことなので説明は省きます。
あえて言うなら、このテキストには名前を付けていません。
そのため、他の処理から呼び出して使うことはできません。

 

 

キャンディを落とす

キャンディを落とします。
隕石の処理とほぼ同じです。

次のプログラムをダメージの表示処理の下に追加しましょう。

<script>
    // キャンディ落とす
    Crafty.sprite(50,50,"candy.png",{Candy:[0,0]});
    Crafty.bind("EnterFrame", function(){
        if (Crafty.frame() % 120 == 0) dropCandy();
    });
    function dropCandy(){
        Crafty.e("Candy, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                this.destroy();
            })
            .bind('EnterFrame', function () {
                this.y += 5;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
</script>

 

処理は隕石と同じなので違う点だけ見ていきます。

まず、絵のサイズと参照用の名前は違います。当たり前ですね。
それから、落とす間隔を 120 フレームにしています。

キャンディを落とす処理

this.y += 5;

落ちる速度は隕石の半分です。

キャンディがエイリアンに当たった時、キャンディを消しています。
消すことでゲットした感を作っています。

しかし、何か足りない感じです。そうそう、スコアがないですね。

 

 

スコアの表示

キャンディをゲットしたら得点というゲームにします。

スコアの表示と得点の仕組みを作ります。
前回の変更部分を下のようにします。

<script>
    // スコアの表示
    let score = 0;
    Crafty.e("Score, DOM, 2D, Text")
        .attr({ x:20, y:50, w:180, h:20 })
        .textFont({size:'20px', weight:'bold'})
        .text("SCORE: 0");
    // キャンディ落とす
    Crafty.sprite(50,50,"candy.png",{Candy:[0,0]});
    Crafty.bind("EnterFrame", function(){
        if (Crafty.frame() % 120 == 0) dropCandy();
    });
    function dropCandy(){
        Crafty.e("Candy, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                score += 50;
                Crafty("Score").text("SCORE: "+score);
                this.destroy();
            })
            .bind('EnterFrame', function () {
                this.y += 5;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
</script>

 

次のようになります。

スコアを表示する

 

変更箇所です。

スコアを表示する仕組み

やっていることはダメージ処理と同じです。
なので一点だけ。参照用の名前は Score です。
変数の score、文字列の SCORE
この3つは別物であることを理解しましょう。

スコアテキストを参照するための名前

 

 

文字の色を変える

ほぼ完成です。
しかし、以前やった処理と同じことばかりで退屈です。
何か違うことをしてみましょう。

ダメージが 60 以上になったら、下図のようにテキストを赤くしてみます。

ダメージを沢山受けたら文字を赤くする

 

ダメージの表示は隕石を落とす処理の中にありましたね。
次のように変更しましょう。

<script>
    // 隕石を落とす
    function obj_drop(){
        Crafty.e("meteor, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                //Crafty.pause();     // すべてを止める
                damage += 10;
                Crafty("Damage").text("DAMAGE: "+damage);   // ダメージ表示更新
                if( damage >= 60 ){
                    Crafty("Damage").textColor('#dc143c');  // 文字の色を変更
                }
                if( damage >= 100 ){
                    Crafty.pause();
                    Crafty.e('2D, DOM, Text')
                        .attr({x:130, y:150, w:300})
                        .text("GAME OVER").textColor('#00ff7f')
                        .textFont({size:'40px', weight:'bold'});
                }
            })
            .bind('EnterFrame', function () {
                this.y += 10;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
</script>

 

変更点です。3行追加しました。

ダメージを沢山受けたら文字を赤くする

Crafty(“Damage”).textColor(’#dc143c’);

textColor を使ってテキストの色を変えるだけでした。

 

 

完成です

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

今までの学習だけでも、ちょっとしたミニゲームは作れます。
ゲームの案を思い付いたら、当講座のように1つずつ組み込んでいきましょう。
何度か繰り返すうちにプログラミングスキルも上がっていきますよ。

 

今回の全プログラムです。

<script>
    Crafty.init(500,400, document.getElementById('game'));
    Crafty.background('#f0fff0');
    // エイリアン
    Crafty.sprite(70,78,"alien2.png",{alien:[0,0]});
    Crafty.e('2D, Canvas, alien, Gravity, Twoway, SpriteAnimation')
        .attr({x:5, y:50})   // 左端は安全エリア
        .twoway(300)
        .jumper(0)      // ジャンプさせない
        .reel('walk',300,0,0,2) // アニメ設定
        .animate('walk', -1)    // アニメ再生
        .bind('KeyDown', function(e) {
            if( e.key == Crafty.keys.LEFT_ARROW ){
                this.flip("X"); // 絵をx軸反転させる
            }
            if( e.key == Crafty.keys.RIGHT_ARROW ){
                this.unflip("X");
            }
        })
        .bind('EnterFrame', function () {
            if( this.x < 0 ) this.x = 0;
            if( this.x > 500 - this.w ) this.x = 500 - this.w;
        })
        .gravity('Floor');
    // 地面
    Crafty.e('Floor, 2D, Canvas, Color')
        .attr({x:0, y:350, w:500, h:10})
        .color('#a0522d');
    // 隕石の絵を用意
    Crafty.sprite(45,40,"meteor.png",{meteor:[0,0]});
    // 隕石の発生
    Crafty.bind("EnterFrame", function(){
        if (Crafty.frame() % 20 == 0) obj_drop();
    });
    // 変数
    let damage = 0;
    // 隕石を落とす
    function obj_drop(){
        Crafty.e("meteor, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                //Crafty.pause();     // すべてを止める
                damage += 10;
                Crafty("Damage").text("DAMAGE: "+damage);   // ダメージ表示更新
                if( damage >= 60 ){
                    Crafty("Damage").textColor('#dc143c');  // 文字の色を変更
                }
                if( damage >= 100 ){
                    Crafty.pause();
                    Crafty.e('2D, DOM, Text')
                        .attr({x:130, y:150, w:300})
                        .text("GAME OVER").textColor('#00ff7f')
                        .textFont({size:'40px', weight:'bold'});
                }
            })
            .bind('EnterFrame', function () {
                this.y += 10;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
    // ダメージの表示
    Crafty.e("Damage, DOM, 2D, Text")
        .attr({ x:20, y:20, w:180, h:20 })
        .textFont({size:'20px', weight:'bold'})
        .text("DAMAGE: 0");
    // スコアの表示
    let score = 0;
    Crafty.e("Score, DOM, 2D, Text")
        .attr({ x:20, y:50, w:180, h:20 })
        .textFont({size:'20px', weight:'bold'})
        .text("SCORE: 0");
    // キャンディ落とす
    Crafty.sprite(50,50,"candy.png",{Candy:[0,0]});
    Crafty.bind("EnterFrame", function(){
        if (Crafty.frame() % 120 == 0) dropCandy();
    });
    function dropCandy(){
        Crafty.e("Candy, 2D, Canvas, Gravity, Collision")
            .attr({x:Crafty.math.randomInt(80, 500-55), y:-50})
            .checkHits("alien")
            .bind("HitOn", function (hitData) {
                score += 50;
                Crafty("Score").text("SCORE: "+score);
                this.destroy();
            })
            .bind('EnterFrame', function () {
                this.y += 5;
                if( this.y > 500 ){
                    this.destroy();
                }
            });
    }
</script>

 

 

『隕石を避けて』

ゲームを作ってみよう

  1. 避けるゲームに挑戦
  2. エイリアンと隕石
  3. 当たり判定とダメージ
  4. キャンディとスコア