読み書きプログラミング

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

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

イタリアのウェブデザイナーのSpinelliさんのブログ記事"BUILD AND PUBLISH AN HTML5 GAME FOR IPAD"を訳してみました。(Spinelliさんにも事後承諾いただきました。)


これは私が現在手がけているプロジェクト/実験についての一連の投稿の最初のものです。目標はiPad用に(canvasを使わない)純粋なHTMLゲームを作り、Apple Store(原文のまま)で公開することです。私の日々の経験や示唆、コードの断片を見ることになるでしょう。

This is the first of a series of posts about a project/experiment I’m currently working on. The challenge is to build a pure HTML game (no canvas) for iPad and publish it to the Apple Store. Here you’ll find my day to day experience, suggestions and pieces of code.

この実験の目的はフルスクリーンのcanvasの中ではなくDOM上で作られたHTMLゲームを開発することです。HTMLだけを使って100%ネイティブに感じるまずまずのゲームを得られるか見いだしたいのです。また、Androidでバイスや古いiDevice, iOSへの扉を開けておきたいのです。それらは特にcanvasが良くありません。

The purpose of this experiment is to develop an HTML game built on DOM and not inside a full screen canvas. I want to find out if you can get a decent game that feels 100% native using just HTML. Also I want to keep the door open to Android devices and older iDevices and iOS versions, and none of them are particularly good at canvas.


私はゲームを選びました。ゲームは標準的なアプリケーションより複雑になる傾向があるからです。基本的にゲームができればなんでもできます。

I choose a game because they tend to be more complex than standard applications. Basically if you can do a game you can do anything.


ゲームはApple Storeに提出されて、$0.99レンジで販売される予定です。
そんなに売れないと思いますが、販売統計は実験の一部です。

The game will be submitted to the Apple Store and will be sold in the $0.99 range.
I know I’m not going to sell much, but sales statistics are part of the experiment.

アプリはまだ完成していませんが、いまの段階で落ち着いて開発プロセスの最初のステップをレポートします。

The app is not finished yet, but at this stage I feel comfortable at reporting the first steps of the development process.

ステップ 1: ゲームのアイデアと技術的制約

ネイティブコードを使っていないので、アイデアは簡単でなければいけませんし、多大な処理能力を要求してはいけません。特に、たくさんのスプライト、エフェクト、複雑な物理を使うアクションゲームは避けたかった。パズルゲームを、特に単語パズルを選びました。iTunes storeでざっと検索してみると、そんなゲームが大量に見つかりましたが同じロジックを使ったものはたった1つで、正直に言えば言及に値さえしないものでした。

I am not using native code, so the idea must be simple and mustn’t require too much processing power. Notably I wanted to avoid action games with too many sprites, effects and complex physics. I opted for a puzzle game and specifically a word puzzle. A quick search on the iTunes store revealed a plethora of such games but only one with the same logic and sincerely it’s not even worth a mention.

最初それは完璧なアイデアに見えました…でもそうではなかった。単語ゲームは明らかに辞書に基づいたもので、辞書は巨大になる悪い傾向があります。単語はウェブSQLデータベースに保存され、sqliteクエリーは遅く、少なくともゲームの速さではありません。うまくインデックスされたデータベースを使うとそこそこのパフォーマンスは得られますが、2MBの項目はインデックスされたdbでは簡単に8MBになり、ウェブSQLの5MB制限を遥かに越えてしまいます。

Initially it seemed the perfect idea… It wasn’t. Word games are obviously based on a dictionary, and dictionaries have the bad habit of being huge. Words are injected into a web sql database and sqlite queries are slow, at least they are not game-fast. You can reach decent performance with a well indexed database, but 2mb of terms easily becomes 8mb of indexed db, well beyond the web sql 5mb limit.

Mobile Safariは、ユーザーの確認が要求されますが5MBを越えられることに注意してください―しかし、私はアプリをWebViewに埋め込むつもりで、私の知る限りこのシナリオの中で5MB制限を越える方法はありません。Objective-CでネイティブのSQLiteデータベース用ラッパーを作るのが解かもしれませんが、それでは純粋なHTMLゲームにはならなく、Android互換性も失われます。

Please note that mobile Safari can go over 5mb –even though an user confirmation is required– but I’m going to embed the app into a WebView and to my knowledge there’s no way to overcome the 5mb limit in this scenario. The solution might be to build a wrapper for the native sqlite database in object-c, but it wouldn’t be a pure HTML game that way, and I’d loose Android compatibility.

ゲームのアイデアを変えるには遅過ぎたので、私はこれを事前計算されたスキーマと切り詰めたAIで解決しました。(これについては次回の投稿でくわしく)

It was too late to change the game idea so I decided I would have solved this with pre-calculated schemas and reduced AI (more on this in the next post).

ステップ 2: コールバック(別名 PhoneGap)

アプリはApple Storeに提出されるのでネイティブアプリの内部にラップする必要があります。PhoneGapは使いたくありませんでした。最終的に必要なものはuiWebViewだけでしたが、JSよりもObjective-Cに時間を費やすことになり、HTMLゲーム製作としてはよくありませんでした。

The app will be submitted to the Apple Store so I need to wrap it inside a native app. I didn’t want to use PhoneGap, at the end all I needed was an uiWebView, but I found myself investing more time on Object-C than on JS, and that’s not good for an HTML game.

オーディオはモバイルブラウザのキメラです。もし応答性がよく多重チャンネル音が必要なら、ネイティブ

Audio is the mobile browser chimera, there’s no way to use native

Canvasのかわり

代替の解を追ううちに、AppMobiを見つけました。これはとても興味深いプロジェクトで、私の理解では彼らは要素をハードウェアアクセラレートするカスタムのSafari互換ブラウザ作りました。デフォルトのWebViewと比較して5倍のパフォーマンス強化を彼らは主張します。(小さな強化に見えますが、1秒当たり10フレームの代わりに50フレームを意味します。) Impact フレームワークと合わせてウェブ開発者の手で強力なツールです。

In the hunt for alternative solutions I’ve found AppMobi. This is a very interesting project, from what I understand they’ve built a custom Safari compatible browser that gives hardware acceleration to the element. They claim a 5x performance enhancement in canvas games compared to default WebView (it may seem a small upgrade but it means 50fps instead of 10!). Together with Impact framework it is a powerful tool in the hands of the web developer.

簡単にAppMobiをテストしましたが、快適とは感じません。ChromeプラグインはJavaサービスに接続するものですが、私のMac上で少し不安定です。ところで私のプロジェクトのゴールは素の古いHTMLを使うことでした。

I briefly tested AppMobi and I don’t feel comfortable with it. The Chrome plugin, connected to some Java service, is a little unstable on my Mac and by the way my project goal was to use plain ol’ HTML.

次のプロジェクトでsecond spinに使おうと決めました。

I promised myself I’d take it for a second spin for the next project.

ステップ 3: JS フレームワーク

そんな風に目標設定されたアプリケーションのため、肥大化したJSフレームワークを使う理由は全く見当たりませんでした。土台が豚だとゲームロジックの超最適化は無駄です。

For such a targeted application I see no reason on Earth to use a bloated JS framework. It’s useless to uber-optimize the game logic if the foundation is a hog.

以前に書きましたが、jQueryとその仲間に対して異論ありません。それらは重要な目的を果たしますが、モバイルアプリケーションでは私はそれらを重荷と見ています。

I’ve already talked about it, I have nothing against jQuery and company, they serve an important cause, but on mobile applications I see them as cumbersome luggage.

自分の必要性に適応できる軽快なコアフレームワークを作りました。ゲームを扱っていることを思い出すように。節約したCPUサイクルすべてを数え上げます。

I’ve build a light core framework that I can shape to my needs. Remember that we are dealing with a game, every spared CPU cycle counts.

例を1つ上げると、以下は私が使ったノードの集合にプロパティを適用する方法です。

Just to make an example the following is my way to apply a property to a set of nodes:

function forEach (el, fn) {
	el = document.querySelectorAll(el);
	for (var i=0, l=el.length; i<l; i++) {
		fn.call(el[i]);
	}
}

速し猛烈。

Fast and furious.

ステップ 4: 乱数生成器

ゲーム開発のまさに底辺にはいい乱数生成器があります。JSゲーム開発のチュートリアルの中で言及しているものは滅多に見ないものです。しかしデフォルトのMath.random()は2つの大きな欠陥があります: 1) シードを与えられない; 2) 出力が範囲内を一様に分布していない。セッション間で同じゲームスキーマを使いたいなら#1は重大です。#2は一つの行で10回同じ数が繰り返されるようないらいらを避けるため重要です。この振る舞いは実際には「ランダム」だと言われてきましたが、ゲームのために必要としているものではありません。

At the very bottom of game development there’s a good Random Number Generator. It’s something I rarely see mentioned in JS game dev tutorials, but the default Math.random() has two major flaws: 1) it can’t be seeded; 2) the output is not evenly spread inside the range. #1 is crucial if you want to regenerate the same game schema between sessions. #2 is important to avoid the annoyance of having the same number repeated 10 times in a row. I’ve being said that this behavior is actually “random”, but this is not what I need for the game.

幸い、javascriptでの乱数生成についてたくさんのリソースが見つけられます。[http://baagoe.org/en/wiki/Better_random_numbers_for_javascript:title=Johannes
Baagøeによる非常にいい記事]から始めることを推薦します。

Fortunately you can find lots of resources about random number generation in javascript, I suggest you to start from the very good piece wrote by Johannes Baagøe.

ステップ 5: デバッグ

やけになって頭痛の種を探しているのでない限り、X Codeで開発しないこと、PhoneGapラッパの中でデバッグしないこと。

Don’t develop under X Code and don’t debug inside the PhoneGap wrapper, unless you’re desperately looking for daily migraine.

アプリケーションの70%はデスクトップブラウザ SafariかChrome上で開発します。20%は実際のデバイス(今回iPad)上で。残りはPhoneGap上で。これはタッチイベントとマウスイベント両方をフックする必要があることを意味しますが、信じてください。それは小さな犠牲で後悔しないでしょう。そしてひょっとしたら、あなたは遅かれ早かれデスクトップバージョンを公開したくなるかもしれません。

70% of the application is done on desktop browser, Safari or Chrome. 20% on the actual device (iPad in this case). The remaining on PhoneGap. This means that you need to hook to both touch and mouse events, believe me, it’s a small sacrifice that you won’t regret doing! And who knows, you may want to release a desktop version sooner or later.

準備完了!

この序文チュートリアルを楽しんでもらえたでしょうか。次回はもっと技術的な側面を記事にします。チャンネルはそのまま。そしてベータテストのご準備を。

Hope you enjoyed this introductory tutorial. Next time I’ll cover more technical aspects, so stay tuned and prepare for beta testing.