4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

tmlib.jsAdvent Calendar 2014

Day 14

昔作ったゲームをJSっぽくリファクタリングした結果【tmlib.js】

Last updated at Posted at 2014-12-14

はじめに

  • 同期的な書き方を減らそうと頑張った痕跡をメモった記事です。
  • 私はゲーム設計に関して右も左も分からない人間です。
  • クソコードで恥ずかしいですが勇気を出して。

tmlibで昔さくっと作ったゲーム

ss2.png

早速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もクソな部分ばかりです、多分。ので、間違いや改善案があった際はご指摘頂けると幸いです。
  • 設計は本当に難しい。まとまった情報が欲しい。
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?