phina.js を使って 100 行縛りでゲーム作ってみた
phina.js Advent Calendar 2015 - Qiita 14日目のエントリーです.
- 1日目 本日 JavaScript ゲームライブラリ『phina.js』をリリースしました! | phiary
- 2日目 ManagerSceneでゲームの流れを管理しよう | daishi blog
- 3日目 ゲーム開発 - 気鋭の新JSゲームライブラリ「phina.js」の概要を自分なりにまとめてみた - Qiita
- 4日目 【phina.js】Gridクラスを使いこなそう - Qiita
- 5日目 phina.js で Webフォント を使ってみるよ! - Qiita
- 6日目 [phina.js] Tweenerを使いこなそう! [Tweener 基本編] - Qiita
- 7日目 [phina.js] サンプルから覚えるphina.js - Qiita
- 8日目 とりあえず試してみたいって方のための phina.js 入門 | phiary
- 9日目 【phina.js】グループ管理の基本テクニック - Qiita
- 10日目 phina.jsでレイヤーと仲良くなろう | daishi blog
- 11日目 【phina.js】Physicalクラスを使ってみよう - Qiita
- 12日目 [phina.js]SpriteSheetを使ってみよう! - Qiita
自分で言うのもなんですが, phina.js を使えば恐ろしく簡単にゲームを作ることができます!
一見は百聞にしかずということで, 今回は, phina.js を使って 100 行縛りで簡単なゲームを作ってみようと思います.
ゲームは Runstant で作ってあるので, このページ内でプレイできます!
About phina.js
phina.js って何?って方はこちらを御覧ください.
『本日 JavaScript ゲームライブラリ『phina.js』をリリースしました! | phiary』
- Official ... http://phinajs.com
- Github ... https://github.com/phi-jp/phina.js
- Gitter ... https://gitter.im/phi-jp/phina.js
Runstant Demo
今回作ったゲームです.
制限時間内にどれだけサークルをタッチできるかを競うというシンプルなゲームです. 良い結果が出たらリザルト画面のシェアボタンから自慢してみてください♪
Code
実装コードです. コメント含めて 90 行程度で作りました!
ゲームロジック部分だけでなく, タイトル -> ゲーム -> リザルトへの基本的な流れも phina.js が内部で共通的なことをやってくれるのですごく楽にゲームを作ることができました.
/*
* runstant
*/
phina.globalize();
// constant
var SHARE_URL = 'http://phiary.me/phina-js-game-tie-up-100-line/';
var SHARE_MESSAGE = 'phina.js を使えばたったこれだけの\nコードで簡単にゲームを作れます!!\nSCORE:{score}';
var SHARE_HASH_TAGS = 'CircleTouch,phina.js';
var TIME = 10*1000; // 10秒
// main scene
phina.define('MainScene', {
superClass: 'CanvasScene',
// 初期化
init: function() {
this.superInit();
// timer
this.timer = TIME;
// score
this.score = 0;
// timerLabel
var timerLabel = Label('time:').addChildTo(this);
timerLabel.x = this.gridX.center();
timerLabel.y = this.gridY.span(2.5);
timerLabel.fontSize = 64;
timerLabel.text = 10*1000;
this.timerLabel = timerLabel;
// shape を生成
var shape = CircleShape().addChildTo(this);
shape.setInteractive(true, 'circle');
shape.onpointstart = function() {
this.score += 1;
this.setRandomPosition();
}.bind(this);
this.shape = shape;
},
// 開始時
onenter: function() {
this.setRandomPosition();
},
// 更新
update: function(app) {
this.timer -= app.deltaTime;
this.timerLabel.text = (this.timer/1000).toFixed(2);
if (this.timer <= 0) {
this.gameover();
}
},
// ランダムな位置にセット
setRandomPosition: function() {
var shape = this.shape;
var x = Math.randint(shape.width, this.gridX.width-shape.width);
var y = Math.randint(shape.height, this.gridY.width-shape.height);
var colorAngle = Math.randint(0, 360);
shape.fill = 'hsl({0}, 80%, 60%)'.format(colorAngle);
shape.setPosition(x, y);
},
// ゲームオーバー
gameover: function() {
// score を渡して終了
this.exit({
score: this.score,
message: SHARE_MESSAGE,
url: SHARE_URL,
hashtags: SHARE_HASH_TAGS
});
},
});
phina.main(function() {
// app 作成
var app = GameApp({
title: 'Circle Touch',
startLabel: 'title',
});
app.run();
});
Tips
簡単にいくつか tips 形式で解説したいと思います.
タッチに反応させよう
要素に対して
elm.setInteractive(true);
とすることで, タッチ判定を有効にすることができます. 有効になるとタッチ系のイベントが走るようになるので, 下記のようにすることでタッチ時に実行したい処理を登録することができます.
elm.setInteractive(true);
// タッチ時 or クリック時に呼ばれる
elm.onpointstart = function() {
// TODO: ...
}
今回のサンプルでは下記のように使っています.
// shape を生成
var shape = CircleShape().addChildTo(this);
shape.setInteractive(true, 'circle');
shape.onpointstart = function() {
this.score += 1;
this.setRandomPosition();
}.bind(this);
経過時間を取得しよう
要素の update に渡される app の変数 deltaTime で毎フレーム間の 経過ミリ秒を取得することができます.
これを scene のもつ timer から毎フレーム引くことでタイマー機能を実現しています.
update: function(app) {
this.timer -= app.deltaTime;
ランダムな数値を生成
本来の JavaScript では, Math.random() という 0~1 の浮動小数点を返すものしかありませんが, phina.js ではそれを拡張して最小値, 最大値を指定して乱数を生成する
Math.randint(min, max) という関数を定義しています.
今回のサンプルでは setRandomPosition() 部分で使用しています.
var x = Math.randint(shape.width, this.gridX.width-shape.width);
var y = Math.randint(shape.height, this.gridY.width-shape.height);
リザルト画面に様々なオプションを渡そう
MainScene の exit 時にオブジェクトを指定することで
ResultScene にオプションを渡すことができます.
今回のデモでは,
// score を渡して終了
this.exit({
score: this.score,
message: SHARE_MESSAGE,
url: SHARE_URL,
hashtags: SHARE_HASH_TAGS
});
とすることで, スコアの他にもメッセージや, twitter share 用の url と hastags も渡しています.
phina.js 勉強会
ちょっと勉強会というか phina.js ハッカソンを近々やろうと思っています.
きっと phina.js コントリビュータの方々も参加してくれると思うので phina.js の使い方だけではなくゲームプログラミングに関する様々な技術について学べるかと思います.
今回のエントリーのような 『100 行縛りでゲームプログラミングハッカソン』 とかやると面白いかもしれないですね.
良いアイディアなどありましたら気軽にご連絡下さい.
具体的な内容や日時など決まりましたらまたこのブログにて告知します. たまに覗いていただけると嬉しいです.
