前回の投稿からよりゲームっぽくする為に、ゲームのクリア条件とスコアを設定しました。
既存のプログラムから取れるスコアとして、「タッチ回数」と「全消しまでの時間」がゲームスコアとして最適かと思い、それぞれ取得できるよう改変。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// ゲームメイン phina.define('MainScene', { superClass: 'DisplayScene', init: function() { this.superInit(); this.tap = 0; this.time = 0; this.count = 0; this.balloonGrooup = DisplayElement().addChildTo(this); this.scrapGrooup = DisplayElement().addChildTo(this); this.label = MyLabel(SCREEN_WIDTH / 2, 50, 40, 'center', this.time).addChildTo(this); for (i = 0; i < startpop; i++) { Balloon(this.scrapGrooup).addChildTo(this.balloonGrooup); } }, update: function(app) { this.collisionGroups(this.scrapGrooup, this.balloonGrooup); this.label.text = this.time.toFixed(2); // クリア判定 if (this.balloonGrooup.children.length === 0) { this.count++; if (this.count > 30) { // 余韻 this.exit({ tap: this.tap, time: this.time }); this.count = 0; } } else { // クリアしていなければ時間を加算 this.time += app.deltaTime / 1000; } }, onpointstart() { this.tap++; }, collisionGroups: function(scrap, balloon) { scrap.children.some(function(scrap) { balloon.children.some(function(balloon) { if (Collision.testRectRect(scrap, balloon)) { if (balloon.life > 0) { scrap.hit(); balloon.hit(); } } }); }); } }); |
これで一応、ゲームっぽい形になったので、ついでにタイトルシーンとリザルトシーンも追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// ゲームタイトル phina.define('TitleScene', { superClass: 'DisplayScene', init: function() { this.superInit(); this.subtitle = MyLabel(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 5, 60, 'center', 'Balloon\nExplosion').addChildTo(this); let guid = '【遊び方】\n'; guid += ' 風船をタップすると弾けて破片が飛ぶよ!\n'; guid += ' 破片が風船に当たっても弾けるよ!\n'; guid += ' すべての風船が弾けるとクリア!\n'; guid += ' 少ない手数で素早くすべてを消してね!'; this.tap = MyLabel(15, SCREEN_HEIGHT / 2 - 40, 30, 'left', guid).addChildTo(this); this.playbtn = MyButton(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 4 * 3, 'スタート').addChildTo(this) .onpointstart = function () { this.parent.exit(); }; }, }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// ゲームリザルト phina.define('ResultScene', { superClass: 'DisplayScene', init: function(score) { this.superInit(score); this.subtitle = MyLabel(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 7, 50, 'center', '--- ゲームクリア! ---').addChildTo(this); this.tap = MyLabel(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 - 40, 40, 'center', 'TAP : ' + score.tap + ' 回').addChildTo(this); this.time = MyLabel(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 + 40, 40, 'center', 'TIME : ' + score.time.toFixed(2) + ' 秒').addChildTo(this); this.replaybtn = MyButton(SCREEN_WIDTH / 4 * 3, SCREEN_HEIGHT / 4 * 3, 'もう一回').addChildTo(this) .onpointstart = function () { this.parent.exit(); }; this.sharebtn = MyButton(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4 * 3, '結果をつぶやく').addChildTo(this) .onpointstart = function () { let url = phina.social.Twitter.createURL({ text: score.tap + '回 / ' + score.time.toFixed(2) + '秒\n', hashtags: 'Javascript, phina_js, Balloon_Explosion', url: phina.global.location && phina.global.location.href, }); window.open(url, 'share window', 'width=480, height=320'); }; }, }); |
おまけでphina.js初期のリザルト画面にあったシェアボタンも改変しちゃいました。
ここまでの進捗状況
ひとまずはゲームとしての形になったかと思います。ですがまだまだ世に出せる状態ではないので、今後もちょこちょこイジる必要がありますね…。
今思いつく点で改変しなければならないのは、
- タイトル&リザルトの装飾
- 無音からの脱却
- さらなるゲーム性
課題がたくさんありますが、とりあえず形になったので肩の力が抜けました。
もし遊んでもらえたなら結果をシェアしてもらえたら嬉しいです。
参考にしたサイト
大変お世話になりました。この場を借りてお礼申し上げます。

旧 phina.js Tips集 - Qiita
コンテンツは以下のzennのbookに移行しました。
今後はzennの方を更新する予定です。
phina.js Tips集
javascriptのゲーム作成用ライブラリphina.jsに関するTipsについて書いています...

phina.js room - ほろほろりドットコム
ゲームライブラリ『phina.js』について今までに書いた記事一覧や、ほろほろりがphina.jsを使って作った作品を紹介しているページです。記事の方は、ただ図形を描画させるだけの基本的なものから、入力関連、少し突っ込んでゲーム作成について、他のライブラリと連携に関しての記事等、色々置いています。

「phina.jsプログラミングまとめ」 vistanさんの公開マイリスト - ニコニコ
phina.jsによる10分間プログラミング マイリスト
特にお世話になっているのが @alkn203 様。本当に感謝しています。
コメント