スコアの表示
スコアを表示します。
このゲームには、敵を倒すなどの要素がありません。
なので、一定間隔で得点という形にします。
地中の四角が作られるタイミングで+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;
壁の発生タイミングに今のフレーム数を加算しています。
システムのフレーム数を使って壁を発生させていたので、変な初期化が必要になってしまいました。
壁発生用のカウンタを用意した方がスマートでした。
それでは実行して、ゲームオーバー後にリトライできるかテストしてみて下さい。
完成です
これで完成です。お疲れさまでした。
次は自分で考えたゲームを作っても良いですね。
当然、このゲームを改良してみるのも良いです。
コインを出して、ゲットしたら得点を表示するなど
色々とやってみましょう。