はじめに
- 同期的な書き方を減らそうと頑張った痕跡をメモった記事です。
- 私はゲーム設計に関して右も左も分からない人間です。
- クソコードで恥ずかしいですが勇気を出して。
tmlibで昔さくっと作ったゲーム
- Wave Fever (jsdoit)
- github
- ネイティブで出ていた「Wave Weaver」をリバエンしたゲームです。
早速Before-Afterいきましょ
Before (Game Sceneのみ)
before
tm.define("GameScene", {
superClass: "tm.app.Scene",
pattern: null, // Patternインスタンス
level: 0, // ゲームレベル(初回0。徐々に上がる)
init: function() {
.....
window.player = Player().addChildTo(this);
this.timer = Timer().addChildTo(this);
this.levelLabel = levelLabel().addChildTo(this);
// 初回パターン生成
this.createPattern(this);
},
update: function(app) {
// 一連のパターンが判定終了したら、インターバルを置いた後、次のパターンへ。
if (this.pattern && this.pattern.ended_flag) {
this.pattern = null;
setTimeout(this.createPattern, NEXT_PATTERN_INTERVAL, this);
}
// 一定時間毎にレベルアップ
if (this.timer.label.text > this.level * 15 + 15) {
this.level = this.level + 1;
this.levelLabel.levelUp(this.level);
}
// ゲームオーバーチェック
if (window.player.playerIcon.isDead){
// 間違った色に接触した瞬間にタイマーをストップする
this.timer.sleep();
}
if (window.player.playerIcon.isGameOver){
app.replaceScene(GameOverScene(this.level, this.timer.label.text));
}
},
createPattern: function(obj) {
obj.pattern = Pattern(obj.level).addChildTo(obj);
}
});
After (Game Sceneのみ)
after
tm.define("GameScene", {
superClass: "tm.app.Scene",
level: 0, // ゲームレベル(初回0。徐々に上がる)
init: function() {
.....
window.player = Player().addChildTo(this);
player.playerIcon.on('collision', function() {
player.playerIcon.off('collision');
self.timer.off('levelUp');
// 間違った色に接触した瞬間にタイマーをストップし、レベルアップカウントも停止
self.timer.sleep();
clearInterval(self.timer.intervalID);
});
player.playerIcon.on('dieAnimationEnd', function(e) {
player.playerIcon.off('dieAnimationEnd');
self.app.replaceScene(GameOverScene(self.level, self.timer.label.text));
});
this.timer = Timer().addChildTo(this).on('levelUp', function() {
self.level = self.level + 1;
self.levelLabel.levelUp(self.level);
});
this.levelLabel = levelLabel().addChildTo(this);
this.pattern = Pattern().addChildTo(this).on('popEnd', function(e) {
// 一連のパターンが終了したら、インターバルを置いた後、次のパターンへ。
setTimeout(_.bind(self.createPattern, self), NEXT_PATTERN_INTERVAL);
});
// 初回パターン生成
this.createPattern();
},
update: function(app) {
/* nothing to do */
},
createPattern: function() {
var patternNum = tm.util.Random.randint(0, 2);
var popPosition = tm.util.Random.randint(POP_POS_LEFT, POP_POS_RIGHT);
switch(patternNum){
case PATTERN_NORMAL:
this.pattern.createNormal(this.level, popPosition);
break;
case PATTERN_NARROW:
this.pattern.createNarrow(this.level, popPosition);
break;
case PATTERN_RUSH:
this.pattern.createRush(this.level, popPosition);
break;
}
}
});
何が変わったのか
- Playerクラスのgameoverに関する処理をイベント駆動っぽくした。(以前は
update()
を使ったかなり同期的な書き方になっていた。) - Patternクラスのインスタンス生成を1度だけにして、こちらもイベント駆動っぽい書き方に直した。
- 参考: [tmlib.js]tmlibで学ぶ、イベント駆動型のクラス設計
- 追記: Timerもイベント駆動にして、遂に
update()
を空に出来ました。やった。
無知は罪である
- このゲームを作っていた際は、Beforeのような同期的な書き方しか知らなかった。フラグを大量に使う書き方しか知らなかった。
- それから数ヶ月、相対的に少しは見るに堪える書き方が出来つつあるのではないか。
timer部分もupdate()から外に出したい。(済)。出来ればフラグ数を0にしたい。クラスのプロパティもより減らしたい。
おわりに
- Afterもクソな部分ばかりです、多分。ので、間違いや改善案があった際はご指摘頂けると幸いです。
- 設計は本当に難しい。まとまった情報が欲しい。