読者です 読者をやめる 読者になる 読者になる

読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

「iPad用HTML5ゲームを作り公開する – PART 3」

http://cubiq.org/build-and-publish-an-html5-game-for-ipad-part-3


ハードディスク破損のせいでロードマップ上少し遅れましたが、サーガの第三篇をお届けします。今回短いスクリーンキャストをお見せする予定です。ゲームがどんなものかついに知ることになるでしょう。

A bit late on the roadmap due to an hard disk failure, here comes the third episode of the saga. This time I’m going to show you a quick screencast and you’ll finally discover what the game will be about.

バックアップ、たくさんバックアップ、しばしばバックアップ

先週、不幸な出来事に続いてゲーム用グラフィックスの開発版とバックアップファイルを失いました。

Last week, following to an unfortunate series of events, I lost both the development version and the backup files of the graphics for the game.


コード自体は大丈夫、私は地球上にある複数レポジトリ複数のコピーを持っています。その代わり、2,3ギガ以上のファイルは「たった」2箇所にしか保存していません…そのうち1つはRAID1 NAS。でも、この世ってやつは強烈なユーモアのセンスを持っていて、仕事のバックアップコピーについて安全だと間違った感覚を持つことよりも悪いことはありません。

The code itself is safe, I have multiple copies on multiple repositories spread all over the globe. I keep files bigger than a couple of gigas on “just” two locations instead… one of them being a RAID1 NAS. But life has a vivid sense of humor and there’s nothing worst than a false sense of safety regarding backup copies of your work.


話せば長くなりますが手短かに言うと、「外部ハードディクを信用するな。」Time MachineはHDと同じぐらいフェイルセーフです。(つまり、全く安全ではありません。)同じことがDropboxやほとんどのクラウドサービスにも言えます。

To make a long story short: don’t trust your external hard drive. Time Machine is as fail safe as your HD (ie: not safe at all). The same goes for DropBox and most cloud services.


私の提案は、RAID1 NASから始めること、そして同じファイルの複数のコピーも取ることです。それから地理的な冗長性をサポートするオンラインバックアップサービスを探してください。(私はrsync.netを選択しました。)

My suggestion is to start from a RAID1 NAS, and make multiple copies of the same file too. Then search an online backup service that supports geographic redundancy (my weapon of choice is rsync.net).


とにかく一からデザインを始めなければいけませんでした。そしてあまり驚くことではありませんが、第一版より大変よく仕上がりました。もし時間があるなら、好きなデザインができた時、一旦それを閉じて空ページからもう一度デザインしてみてください。新版は顕著によくなるでしょう。

Anyway I had to start the design from scratch and not so surprisingly it came up much better than the first version. If you have time, when you find the design you like, close it and redo it from blank page, the new version will be noticeably better.

ゲーム

以上お節介でした。さて以下は待ちに待ったゲームのお忍びプレビューです。すべてCSS/JSで、canvasは使っていないことをどうか思い出してください!

Sorry for the rant. Here below the long awaited sneak preview of the game in all its alpha stage glory. Please remember that it’s all CSS/JS, no canvas has been harmed!


ゴールは隣のタイルをタップして単語を組み立てることです。もちろん、さらにポイントを稼ぐことができるボーナスタイルやゲームの難易度を上げる「特殊機能」もあります。3レベル毎に種類を加えるためにボーナスステージに進むことになります。ボーナスステージは与えられた8文字から可能なかぎりの単語を見つけるミニゲーム(スクラブルの一種)です。

The goal is to compose words tapping adjacent tiles. Of course you’ll also have bonus tiles granting you more points and “special abilities” just to spice up the gameplay. To add some variety every 3 levels you’ll end up in a bonus stage, a mini-game where you’ll be asked to find the more words possible given a set of 8 letters (kinda Scrabblish).


これですべてです。これ以上でもこれ以下でもありません。気に入ってもらえると嬉しいです。

That’s it. Nothing more, nothing less. Hope you’ll like it.

スコアボード


スコアボードが好きなら、私がそれをただで提供していると知って喜んでもらえるでしょう。他のライブラリに依存しないとても簡単なjavascriptライブラリです。jsOdometerと呼んでいます。githubで入手可能で、ライブデモがここで見えます。(Chromeでも動きます。)

If you like the scoreboard you’ll be happy to know that I’m giving it away for free. It’s a very simple dependency-free javascript library called jsOdometer. You find it on github and you can see a live demo here (works on Chrome too).


拡大する必要があれば、多分、odometer.jsの21行目のtranslateZ()の値を変更しないといけないでしょう。

If you need it bigger you’ll probably have to change the translateZ() value in the odometer.js file at line 21.


これは確かにベータ段階で、安定したものにするにはまだいくつか仕事する必要がありますが、一からプログラミングするよりはまだましでしょう。

Admittedly it is in beta stage and some more work is needed to make it rock solid, but still better than programming it from scratch.

iPad 表示

iPadでの表示は、特に赤オレンジ帯域で幾分過飽和のようです。デモで見る素敵な木目のテクスチャは実機では散漫な赤の背景に変わります。iPadに搭載する前に8-10%赤を不飽和化することを覚えておくこと。

It seems that the iPad display is a bit over-saturated, especially in the red-orange spectrum. That nice wooden texture you see in the demo turns into a distracting red background on the real device. Remember to desaturate by 8-10% your reds before deploying to iPad.

音声

音声と音楽についての仕事はとてもたくさんの理由からあれこれひどいものです。

Working with sound and music is a mess for so many reasons.


まずiPadスピーカが最低。サウンドエフェクトで特にひどい。いつもクリアでシンプルで短く、低音エフェクトをほとんどいれないように選ぶこと。何十のファイルを試したようやく酔ったリスのように聞こえないものを見つけました。

First of all, the iPad speaker sucks. It is especially bad at sound effects. Always choose clear, simple, short and with few basses effects. I’ve tried dozens files before finding the ones that don’t sound like a drunk squirrel.


二番目に、WebViewラッパのネイティブコードが遅い。音声が実際に再生される前に100-200ms掛かります。これはゲームには無限に長い時間です。それだけでなくこの時間枠の間、インターフェースが遅延します。PhoneGapは素晴らしいMedia APIを提供してくれますが、遅延を減らすには頭を使わないといけません。(完全に取り除けるわけではありません。)

Secondly, the native code to WebView wrapper is slow. It takes 100-200ms before the sound is actually played, an infinitely long time for a game. Not only that, the interface lags during this timeframe. PhoneGap provides the great Media API but to reduce (but not completely remove) the lag you have to be smart.


再生 > 停止 > 再生のシークエンスはデバイスが扱うには大変過ぎることに気づきました。BGMには機能しますが、1分間に複数回再生する必要のあるサウンドエフェクトではうまく機能しません。解はオーディオファイルを決して停止しないことです。

I noticed that the play > stop > play sequence is too much to handle for the device. It works for background music, but not for sound effects that need to be played multiple times per minute. The solution is to never stop the audio file.


「音声スプライト」ファイルを作成してください。サウンドエフェクトすべてを一緒に1つのファイルにマージして、ファイルの頭とそれぞれのエフェクトの終わりに1秒間の沈黙を加えてください。

Build an “audio sprite” file. Merge together all your sound effects into a single file and add one second of silence at the end of each effect and at the beginning of the file.


起動時に音声ファイルを再生してすぐにポーズしてください。(停止ではありません。ただポーズです。)音声が必要な時、seekTo(ms)を先に使って必要な音声の先頭に音声「ヘッド」を移動させなければいけません。そして音声を再生した時、再びポーズします。音声ファイルは基本的に決して停止させません。

At startup play the sound file and immediately pause it (it’s not a stop! Just a pause). When you need a sound you have to position the audio “head” at the beginning of the needed sound with seekTo(ms) first, then when the sound is played you pause it again. The audio file is basically never stopped.


以下は、音声関数がどんな風になるか、手っ取り早いですが汚い例です:

The following is a quick and dirty example of how your sound function might look like:

var sound = (function () {
	var hasSound = false,

		fx,
		fxTimer;

	function init () {
		hasSound = 'Media' in window;

		fx = new Media('audio/fx.m4a');

		seekPlay(0,100);
	}

	function seekPlay (from, to) {
		if (!hasSound) return;

		clearTimeout(fxTimer);

		to = to || 500;

		fx.pause();
		fx.seekTo(from);
		fx.play();

		fxTimer = setTimeout(function () {
			fx.pause();
		}, to);
	}

	function boom () {
		seekPlay(1000);
	}

	function clank () {
		seekPlay(2205);
	}

	function kapow () {
		seekPlay(3380)
	}

	return {
		init: init,
		boom: boom,
		clank: clank,
		kapow: kapow,
	};
})();

この段階でsound.boom()をコールできて、すべてを処理するはずです。

At this point you can call sound.boom() and your code should take care of everything.


インターフェースはまだエフェクトを再生するたびに小さな遅延に閉口します。今回の解は音声関数のコールを延期することです。

The interface is still plagued by a small lag each time you play an effect. The solution this time is to defer the call to the sound function.

setTimeout(function() { sound.boom(); }, 0);

ブラウザにelement.offsetHeightを使って再描画を強制するトリックも機能するようです。オリジナルのiPad上では音声パフォーマンスに完全には満足していません。(iPad2では十分いいです。)ゲームのロジックが完成した後、きっとこのトピックについて更に時間を費やすでしょう。

Forcing the browser repaint with the element.offsetHeight trick also seems to work. I’m not completely satisfied by the audio performance on the original iPad (iPad2 is good enough) and I will surely spend more time on this topic later when the game logic will be completed.

音楽

私のようにピアノとチェロの違いがわからない人なら、たくさんのロイヤルティーフリーの音楽サイト上でサウンドトラックを探さざるを得ないでしょう。ライセンスアグリーメントをよく読んでください。楽曲の使い方にたくさんの制約があります。

If like me you can’t say the difference between a piano and a cello you are pretty much forced to look for a soundtrack on one of the many royalty free music sites around. Read the license agreement carefully, there are many limitations in score usage.


とてもいいリソースはPremiumbeat, Neosounds, Soundrangersです。

Very good resources are Premiumbeat, Neosounds and Soundrangers.


KB量を可能なかぎり抑えなければいけないことを思い出してください。短くて繰り返し再生可能な曲を選びましょう。

Remember that you have to take the KB count as low as possible, so try to pick a short loopable track.