<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>あんどう やすし &#8211; HTML5Experts.jp</title>
	<atom:link href="/technohippy/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>Firebaseで作る簡単リアルタイムウェブアプリケーション（前編 補）</title>
		<link>/technohippy/21196/</link>
		<pubDate>Tue, 18 Oct 2016 02:00:20 +0000</pubDate>
		<dc:creator><![CDATA[あんどう やすし]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Firebase]]></category>

		<guid isPermaLink="false">/?p=21196</guid>
		<description><![CDATA[前回の記事は前編と称してFirebaseの機能を簡単に紹介しました。その続きである今回の記事は後編として何かアプリケーションを作りながら個々の機能を詳細に説明するはずでした。 しかし、前編からすでに10ヶ月が過ぎ、途中に...]]></description>
				<content:encoded><![CDATA[<p><a href="https://html5experts.jp/technohippy/18040/" target="_blank" data-wpel-link="internal">前回の記事</a>は前編と称してFirebaseの機能を簡単に紹介しました。その続きである今回の記事は後編として何かアプリケーションを作りながら個々の機能を詳細に説明するはずでした。<br>
しかし、前編からすでに10ヶ月が過ぎ、途中にGoogle I/Oを挟んだこともあって、すでに全体像が大幅に変更されています。そこで今回は「前編 補」として、いまさらではありますがGoogle I/O前後でFirebaseがどのように変わったのかをざっくりと説明します。</p>

<h2>新旧Firebaseの違い</h2>

<p>2016年5月のGoolge I/Oのキーノート、そしてそれに続く各セッションでFirebaseの大幅な拡張が発表されました。いったいどのような拡張が行われたのか、それはその発表前後のトップページの文言を比較すると分かりやすいでしょう。</p>

<table style="margin:10px;width:70%">
  <tr>
    <th style="text-align:center;font-weight:bold;background:#ffffcc">旧Firebase</th>
  </tr>
  <tr>
    <td style="text-align:center;margin:10px">
      <a href="https://html5experts.jp/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-300x219.png" alt="https://www.firebase.com/" width="300" height="219" class="size-medium wp-image-18079" srcset="/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-300x219.png 300w, /wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2.png 640w, /wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-207x151.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><br />
      <strong>素晴らしいアプリを開発</strong><br />
      モバイル／ウェブアプリのための強力なプラットフォーム
    </td>
  </tr>
</table>

<table style="margin:10px;width:70%">
  <tr>
    <th style="text-align:center;font-weight:bold;background:#ffffcc">新Firebase</th>
  </tr>
  <tr>
    <td style="text-align:center;margin:10px">
      <a href="https://html5experts.jp/wp-content/uploads/2016/10/d70d00af1a84922022b83aa54e5c82f1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/10/d70d00af1a84922022b83aa54e5c82f1-300x247.png" width="300" height="247" class="alignnone size-medium wp-image-21199" srcset="/wp-content/uploads/2016/10/d70d00af1a84922022b83aa54e5c82f1-300x247.png 300w, /wp-content/uploads/2016/10/d70d00af1a84922022b83aa54e5c82f1.png 640w, /wp-content/uploads/2016/10/d70d00af1a84922022b83aa54e5c82f1-207x170.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><br />
      <strong>アプリビジネス成功への近道</strong><br />
      質の高いアプリを作成し、ビジネスを成功に導く<br />ために必要なツールとインフラストラクチャ
    </td>
  </tr>
</table>

<p><br /></p>

<p>どうでしょう。新旧の立ち位置の違いが明確に表れていると思いませんか。</p>

<p>つまり、以前のFirebaseは単純にアプリのバックエンド開発／運用の省力化が目的でしたが、新しいFirebaseはアプリビジネスに関わるすべての領域をサポートして、その成功を目指すものになった、ということです。</p>

<h2>新しいFirebase</h2>

<p>新しいFirebaseの謳い文句は「アプリビジネス成功への近道」でした。それでは、Googleの考える「アプリビジネスの成功」とは何で、そのために拡張された機能にはどういうものがあるのでしょうか。これもFirebaseのトップページに分かりやすい説明があります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/10/e702734ff6ac2845310894d93b5b3bd2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/10/e702734ff6ac2845310894d93b5b3bd2-300x248.png" width="300" height="248" class="alignnone size-medium wp-image-21206" srcset="/wp-content/uploads/2016/10/e702734ff6ac2845310894d93b5b3bd2-300x248.png 300w, /wp-content/uploads/2016/10/e702734ff6ac2845310894d93b5b3bd2.png 640w, /wp-content/uploads/2016/10/e702734ff6ac2845310894d93b5b3bd2-207x171.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>この図から分かるようにGoogleはアプリ提供のプロセスをDevelop（開発）・Grow（拡大）・Earn（収益）の3つのステージで捉えています。さらに各ステージが繋がって輪になっていることから分かるように、この3ステージはアプリが生きている限り、オーバーラップしながら繰り返し現れてはずっと続いていくものです。</p>

<p>また、図をよく見ると3ステージから成る輪の中心にAnalytics（解析）があることが分かります。これらを考え合わせると、Googleが考えるアプリビジネスが成功している状態とは、<strong>Analyticsを軸にDevelop・Grow・Earnがスムーズに連携している状態</strong>であると理解することができます。</p>

<h2>Analyticsと3つのステージ</h2>

<p>全体像がわかったところで各ステージをサポートする機能を個別に見ていきましょう。なお、旧Firebaseにはなかった機能名は太字で記しています。</p>

<h3>Analytics</h3>

<p>先ほども書いたとおりAnalyticsは新しいFirebaseの核となる機能です。ここで得られる情報がDevelop・Grow・Earnすべてのステージを駆動します。</p>

<dl style="margin-left:20px">
  <dt><strong>Firebase Analytics</strong></dt>
  <dd style="text-indent:0;margin-left:20px">モバイルアプリのイベントログを記録します。初めての起動・アプリ内課金・アプリのバージョンアップなどのデフォルトで記録されるイベントの他、開発者が独自に定義したイベントの発生を記録し、Firebasコンソールで確認できます。対応する環境はiOSとAndroidです。</dd>
</dl>

<h3>Develop</h3>

<p>認証、ストレージ、テストなどアプリの開発に必要となる各種機能群です。</p>

<dl style="margin-left:20px">
  <dt><strong>Firebase Cloud Messaging</strong></dt>
  <dd style="text-indent:0;margin-left:20px">以前はGoogle Cloud Messagingと呼ばれていた機能です。対象のカテゴリを指定して通知を送信できます。対応する環境はiOS、Android、Webです。</dd>
  <dt>Firebase Authentication</dt>
  <dd style="text-indent:0;margin-left:20px">認証機能を提供します。FacebookやTwitterのアカウントを使用した認証、メールアドレスとパスワードを使用した認証などが利用できます。対応する環境はiOS、Android、Webです。</dd>
  <dt>Firebase Realtime Database</dt>
  <dd style="text-indent:0;margin-left:20px">サーバーと全クライアント間でデータが同期されるリアルタイムNoSQLデータベースです。<a href="https://html5experts.jp/technohippy/18040/" data-wpel-link="internal">前回</a>で説明したとおり、Firebaseで最も古い、サービスを特徴付ける機能です。対応する環境はiOS、Android、Webです。</dd>
  <dt><strong>Firebase Storage</strong></dt>
  <dd style="text-indent:0;margin-left:20px">Google Cloud Storageを内部的に使用するストレージサービスです。Firebase Realtime Databaseとは異なり、写真や動画などの静的なコンテンツを保存するのに適しています。対応する環境はiOS、Android、Webです。</dd>
  <dt>Firebase Hosting</dt>
  <dd style="text-indent:0;margin-left:20px">HTMLやJS、CSSなど静的なファイルのホスティングサービスです。Firebaseのコマンドラインツールを使用すれば、コマンドをひとつ実行するだけで簡単にウェブアプリをデプロイできます。対応する環境はもちろんWebだけです。</dd>
  <dt><strong>Firebase Remote Config</strong></dt>
  <dd style="text-indent:0;margin-left:20px">アプリの動作や外観をFirebaseコンソールから変更することができます。設定内容はOSの種類や国に応じて切り替えることができる他、例えばランダムに10%のユーザーにだけ特定の機能を有効にすることも可能です。対応する環境はiOSとAndroidです。</dd>
  <dt><strong>Firebase Test Lab for Android</strong></dt>
  <dd style="text-indent:0;margin-left:20px">Googleのデータセンター内の様々なAndroid端末上でテストを実行できます。テストの結果はログやスクリーンショットで確認できます。対応する環境は現在のところAndroidだけです。</dd>
  <dt><strong>Firebase Crash Reporting</strong></dt>
  <dd style="text-indent:0;margin-left:20px">iOS/Androidアプリのエラーを監視し、エラー発生時にはAnalyticsのイベントを発火し、情報を収集します。対応する環境はiOSとAndroidです。</dd>
</dl>

<h3>Grow</h3>

<p>公開後のアプリのユーザーベースの拡大に必要な機能群です。</p>

<dl style="margin-left:20px">
  <dt><strong>Firebase Notifications</strong></dt>
  <dd style="text-indent:0;margin-left:20px">FirebaseコンソールからグラフィカルなUIを通じてユーザーの端末に通知を送信できます。実際のメッセージの送信にはFirebase Cloud Messagingが利用されています。対応する環境はiOSとAndroidです。</dd>
  <dt><strong>Firebase App Indexing</strong></dt>
  <dd style="text-indent:0;margin-left:20px">以前はGoogle App Indexingと呼ばれていた機能です。Googleの検索結果にアプリを表示でき、直接アプリを起動できるようになります。対応する環境はiOSとAndroidです。</dd>
  <dt><strong>Firebase Dynamic Links</strong></dt>
  <dd style="text-indent:0;margin-left:20px">端末の種類は何か、アプリがインストールされているかどうか、アプリのユーザー登録は完了しているかどうか、などの条件に応じて適切に動作を変えるURLを生成できます。対応する環境はiOSとAndroidです。</dd>
  <dt><strong>Firebase Invites</strong></dt>
  <dd style="text-indent:0;margin-left:20px">Firebase Dynamic Linksを使用してユーザーにアプリの招待を送ることができます。対応する環境はiOSとAndroidです。</dd>
  <dt><strong>Google AdWords</strong></dt>
  <dd style="text-indent:0;margin-left:20px">Google AdWordsのアカウントをFirebaseプロジェクトにリンクし、アプリの利用状況に応じたターゲットユーザーを指定できるようになります。対応する環境はiOSとAndroidです。</dd>
</dl>

<h3>Earn</h3>

<p>アプリから収益を得るために必要な機能です。現時点で所属するAPIはAdMobしかないので、構成の都合で無理やり作ったステージの感じも若干あります。</p>

<dl style="margin-left:20px">
  <dt><strong>AdMob by Google</strong></dt>
  <dd style="text-indent:0;margin-left:20px">以前からあるモバイル広告プラットフォームですが、Firebaseプラットフォームの一員となったことでFirebase Analyticsを分析に利用できるようになりました。対応する環境はiOSとAndroidです。</dd>
</dl>

<h2>ウェブアプリ</h2>

<p>先のセクションでFirebaseで提供されている機能を一通り簡単に説明しました。太字の項目が多いことからも、旧Firebaseと比較して非常に多くの機能が追加されたことがわかると思います。しかし、ここでウェブ開発者な皆さん（html5experts.jpなので当然そうですよね？）にとって少し残念なお知らせがあります。気づかれた方もいるかもしれませんが、<strong>これら新機能の大部分はウェブアプリでは使えません</strong>。</p>

<p>説明のために各機能の対応プラットフォームと、ついでとして元となったサービスを表形式でまとめました。</p>

<table style="font-size:0.9em;margin:auto">
  <tr>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">ステージ</th>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">新Firebase</th>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">旧Firebase</th>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">Web</th>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">iOS</th>
    <th style="text-align:center;font-weight:bold;background:#ffddcc">Android</th>
  </tr>
  <tr>
    <th style="vertical-align:middle;text-align:center;font-weight:bold;background:#ffddcc">Analytics</th>
    <td style="background:#ffffcc">Firebase Analytics</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <th style="vertical-align:middle;text-align:center;font-weight:bold;background:#ffddcc" rowspan="8">Develop</th>
    <td style="background:#ffffcc">Firebase Cloud Messaging</td>
    <td style="background:#eeeecc">Google Cloud Messaging</td>
    <td style="color:red;text-align:center">o</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Authentication</td>
    <td style="background:#ffffcc">Firebase Authentication</td>
    <td style="color:red;text-align:center">o</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Realtime Database</td>
    <td style="background:#ffffcc">Firebase Realtime Database</td>
    <td style="color:red;text-align:center">o</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Storage</td>
    <td style="background:#eeeecc">(Google Cloud Storage)</td>
    <td style="color:red;text-align:center">o</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Hosting</td>
    <td style="background:#ffffcc">Firebase Hosting</td>
    <td style="color:red;text-align:center">o</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Remote Config</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Test Lab for Android</td>
    <td style="background:#eeeecc">Cloud Test Lab for Android</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Crash Report</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <th style="vertical-align:middle;text-align:center;font-weight:bold;background:#ffddcc" rowspan="5">Grow</th>
    <td style="background:#ffffcc">Firebase Notifications</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase App Indexing</td>
    <td style="background:#eeeecc">Google App Indexing</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Dynamic Links</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Firebase Invites</td>
    <td style="background:#eeeeee">&#8211;</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <td style="background:#ffffcc">Google AdWords</td>
    <td style="background:#eeeecc">Google AdWords</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
  <tr>
    <th style="vertical-align:middle;text-align:center;font-weight:bold;background:#ffddcc" rowspan="1">Earn</th>
    <td style="background:#ffffcc">AdMob</td>
    <td style="background:#eeeecc">AdMob</td>
    <td style="text-align:center">&#8211;</td>
    <td style="text-align:center">o</td>
    <td style="text-align:center">o</td>
  </tr>
</table>

<p><br /></p>

<p>いつからかFirebaseの機能が大幅に拡張されたかのように錯覚していましたが、表を見るとWeb版に関しては旧来のFirebaseと比較してできることにほぼ差がないということが一目瞭然です。Develop、Grow、EarnがAnalyticsを中心に連携するのが新Firebaseの基本理念だったはずですが、Webに関して言えばDevelopしかありません。大丈夫なんでしょうか。</p>

<p>そしてそのDevelopについても、2つの違いのうちのひとつであるFirebase Cloud MessagingについてはGoogle Cloud Messagingから名前が変わっただけで、結局新旧の違いらしい違いといえばFirebase Storageにより静的なファイルが扱いやすくなったことくらいです。</p>

<p>従って、ウェブ開発者の視点では新旧の違いは機能面からではなく、「GoogleがFirebaseに対して本気になっている」という<strong>精神面での向上</strong>として捉えるのが正解でしょう。実際Firebaseドキュメント日本語化の状況や、公式ブログでのFirebaseの露出も以前とは段違いですので、<a href="http://blog.parse.com/announcements/moving-on/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">FacebookのParse.comに対する仕打ち</a>のようなものを心配する必要が直近ではなくなったと考えられるのはウェブ開発者としても非常に喜ばしいことです。</p>

<h2>機能面以外の変更</h2>

<p>これまで機能面（と精神面）での変更点について紹介してきましたが、最後にそれら以外の変更点についても簡単に触れておきます。</p>

<h3>FirebaseコンソールのUI</h3>

<p>機能が追加されるに当たって、当然ですがそれらを管理するFirebaseコンソールのUIも変更されています。しかし見た目の変更を除けば、既存機能に関しては左側のナビゲーションに表示される項目が増えただけですので、それほど気にする必要はありません。</p>

<p>ただし、以前のFirebaseで作成したプロジェクトを新しいFirebaseコンソールで管理するには明示的にコンソールをアップグレードし、さらにデータベースの情報をインポートする必要があります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/10/5cf5bb3b65daca9205a8ddff2775f20c.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/10/5cf5bb3b65daca9205a8ddff2775f20c-300x238.png" alt="データインポート" width="300" height="238" class="alignnone size-medium wp-image-21343" srcset="/wp-content/uploads/2016/10/5cf5bb3b65daca9205a8ddff2775f20c-300x238.png 300w, /wp-content/uploads/2016/10/5cf5bb3b65daca9205a8ddff2775f20c.png 640w, /wp-content/uploads/2016/10/5cf5bb3b65daca9205a8ddff2775f20c-207x164.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h3>料金体系</h3>

<p><a href="https://firebase.google.com/pricing/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">料金体系</a>が大幅に変更されました。元々はFreeプランを含めてクォータの違いごとに6種類あったものが、現在はフリープラン（SPARK）・月額固定制有料プラン（FLAME）・従量制有料プラン（BLAZE）の3種類にまとめられました。</p>

<p>これまでフリープランを使用してた人にとっては、クォータはほぼ変更がないまま、以前は無料では利用できなかった独自ドメインを設定できるようになったということで喜ばしい変更でしょう。</p>

<h3>サポート言語の追加</h3>

<p>あくまでも実験的にですが<a href="https://firebase.google.com/docs/cpp/setup" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">C++ SDK</a>が追加されています。モバイルゲームなどパフォーマンスが要求されるアプリでは利用を検討してみてもいいでしょう。</p>

<h2>まとめ</h2>

<p>身もふたもない言い方をすれば、新しいFirebaseは「これまでGoogleが個別に提供していたアプリ提供者向けサービスを上流から下流までほぼ全て集約した統一ブランドの名前」になりました。</p>

<p>本連載に限っての結論としては「以前とほぼ変わっていない」という理解で構いません。UIの変更はもちろんありますが、できることは変わっていないので取り急ぎは安心して<a href="https://html5experts.jp/technohippy/18040/" target="_blank" data-wpel-link="internal">前回の記事</a>を参考にして頂ければと思います。</p>

<p>ということで次回こそ、Firebaseで何かを作りながらより詳細に機能を紹介します。</p>
]]></content:encoded>
			</item>
		<item>
		<title>Firebaseで作る簡単リアルタイムウェブアプリケーション（前編）</title>
		<link>/technohippy/18040/</link>
		<pubDate>Tue, 19 Jan 2016 00:00:44 +0000</pubDate>
		<dc:creator><![CDATA[あんどう やすし]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[サイト制作]]></category>
		<category><![CDATA[BaaS]]></category>
		<category><![CDATA[Firebase]]></category>

		<guid isPermaLink="false">/?p=18040</guid>
		<description><![CDATA[Firebaseは2014年10月にGoogleに買収されたことで一躍有名になったBaaS（Backend as a Service）です。本記事ではちょっとしたリアルタイムウェブアプリケーションを作りながらFireba...]]></description>
				<content:encoded><![CDATA[<p><a href="https://www.firebase.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firebase</a>は2014年10月にGoogleに買収されたことで一躍有名になったBaaS（Backend as a Service）です。本記事ではちょっとしたリアルタイムウェブアプリケーションを作りながらFirebaseの機能を紹介します。</p>

<h2>Firebaseとは</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-300x219.png" alt="https://www.firebase.com/" width="300" height="219" class="size-medium wp-image-18079" srcset="/wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-300x219.png 300w, /wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2.png 640w, /wp-content/uploads/2016/01/3a345fd10f12d48416c28c3d696e92f2-207x151.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p><a href="https://www.firebase.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firebase</a>はデータストレージ、ユーザー管理などアプリケーションのバックエンドとして必要となる機能をサービスを提供することで、アプリケーション開発者がクライアントサイドの開発に集中できるようにしてくれるBaaS（Backend as a Service）の一種です。</p>

<p>2014年10月にGoogleに買収され、<a href="https://cloud.google.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Cloud Platform</a>（GCP）の一員となりました。この買収によりGCPにはPaaS（Platform as a Service）として<a href="https://cloud.google.com/appengine/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google App Engine</a>、IaaS（Infrastracture as a Service）として<a href="https://cloud.google.com/compute/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Compute Engine</a>、BaaSとしてFirebaseと、いわゆるXaaS系が一通り揃ったことになります。</p>

<h2>Firebaseの特徴</h2>

<p>Firebaseはもともとは開発者用APIを持つウェブサイトに埋め込み可能なリアルタイムチャットサービスとして始まりました。</p>

<p>しかし、多くのユーザーがチャットサービスとしてではなく、ゲームなどのアプリケーションでリアルタイムにデータを同期するために使用したため、創業者たちはチャットサービスのリアルタイムメッセージングシステムを切り出して別サービスとしました。これが現在のFirebaseの元となっています。</p>

<p>そのため、Firebaseは数あるBaasの中でも特にチャットアプリのようなリアルタイムにデータを同期する必要があるサービスに適しています。</p>

<h2>Firebaseの機能</h2>

<h3>リアルタイムデータベース</h3>

<p>FirebaseのデータベースはスキーマレスないわゆるNoSQLで、特定のアプリケーションに関係するデータ全体がひとつのJSONオブジェクトとして保持される点が大きな特徴です。</p>

<p>これによりデータが階層構造をなすため、それぞれのデータが一意のURLを持つことができます。例えばデータベース全体を指すURLは以下のようになります。</p>

<ul>
<li>https://アプリケーションID.firebaseio.com/</li>
</ul>

<p>特定のデータを示すURLは以下のようになります。</p>

<ul>
<li>https://アプリケーションID.firebaseio.com/プロパティのパス</li>
</ul>

<p>例えばアプリケーション名 my-first-chat-app のデータ全体が以下の様であるとして</p>

<p></p><pre class="crayon-plain-tag">{
  "messages" : {
    "-K5kPGFquoTbqHYQqBRS" : {
      "body" : "message",
      "name" : "name"
    },
    "-K5kPUqfBfdj4bAa1fyv" : {
      "body" : "message2",
      "name" : "name2"
    },
    "-K5kR-lwtG4I5w9T36Xq" : {
      "body" : "message3",
      "name" : "name3"
    }
}</pre><p></p>

<p>最初のメッセージ（messages/-K5kPGFquoTbqHYQqBRS）の内容だけを確認したいのであれば、次のURLをブラウザで表示すればいいということになります。</p>

<ul>
<li>https://my-first-chat-app.firebaseio.com/messages/-K5kPGFquoTbqHYQqBRS</li>
</ul>

<div id="attachment_18064" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/2b6f6d52f428612fc49a0c207320bcaa.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/2b6f6d52f428612fc49a0c207320bcaa-300x250.png" alt="/messages/-K5kPGFquoTbqHYQqBRS" width="300" height="250" class="size-medium wp-image-18064" srcset="/wp-content/uploads/2016/01/2b6f6d52f428612fc49a0c207320bcaa-300x250.png 300w, /wp-content/uploads/2016/01/2b6f6d52f428612fc49a0c207320bcaa.png 640w, /wp-content/uploads/2016/01/2b6f6d52f428612fc49a0c207320bcaa-207x172.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">特定データの表示</p></div>

<h3>認証</h3>

<p>Firebaseを使用すると非常に簡単にユーザー認証をアプリケーションに組み込むことができます。組み込みの認証機構としては、メールアドレスとパスワードを使用した認証、OAuthを使用した認証（Facebook, Twitter, GitHub, Google）、匿名ログインがあり、加えてJSON Web Tokens (JWTs)を使用して既存の任意の認証システムと連携することも容易です。</p>

<h3>ホスティング</h3>

<p>HTML、CSS、JS、画像などの静的なアセットは、Firebaseコマンドラインツールを使用して自身のドメイン上（<code>アプリケーションID.firebaseapp.com</code>）、もしくは有料プランであれば独自ドメイン上に簡単にデプロイすることができます。</p>

<p>さらにデプロイの履歴は管理画面で見ることができ、問題があった場合には以前のバージョンにロールバックすることも可能です。</p>

<h4>コマンドラインツール</h4>

<p>Firebaseのホスティングサービスを利用するにはFirebaseコマンドラインツールを使用する必要があります。node.jsとnpmがインストールされていればコマンドツールは以下のコマンドで簡単にインストールできます。</p>

<p></p><pre class="crayon-plain-tag">$ npm install -g firebase-tools</pre><p></p>

<p>firebaseコマンドで利用可能なサブコマンドは、以下のとおりです。</p>

<dl>
<dt><strong>firebase init</strong></dt>
<dd>プロジェクトディレクトリを初期化します。ホスティングサービスに必要なすべての設定は当コマンドによりプロジェクトディレクトリルートに作成されるfirebase.jsonファイルに含まれます</dd>
<dt><strong>firebase deploy</strong></dt>
<dd>現在のプロジェクトをサーバーにデプロイします</dd>
<dt><strong>firebase disable:hosting</strong></dt>
<dd>ホスティングを無効にし、アクセスに対し&#8221;Site Not Found&#8221;ページを表示するようにします</dd>
<dt><strong>firebase login</strong></dt>
<dd>コマンドラインツールをログインします</dd>
<dt><strong>firebase logout</strong></dt>
<dd>コマンドラインツールをログアウトします</dd>
<dt><strong>firebase list</strong></dt>
<dd>現在ログイン中のユーザーが利用可能なFirebaseアプリの一覧を表示します</dd>
</dl>

<h3>APIとSDK</h3>

<p>FirebaseデータベースにはREST APIがあり、さらにそのAPIを利用する各種環境用のクライアントライブラリが標準で用意されています。</p>

<ul>
<li><a href="https://www.firebase.com/docs/web/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web</a>（JavaScript）</li>
<li><a href="https://www.firebase.com/docs/ios/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">iOS</a>（Objective C）</li>
<li><a href="https://www.firebase.com/docs/android/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Android</a>（Java）</li>
</ul>

<p>なお、これらの標準クライアントライブラリを使用するとFirebaseはオフラインでの動作が保証されます。つまりネットワーク接続がない場合でも、Firebaseデータベースの読み書きの対象を一旦ローカルのキャッシュとすることで、アプリケーションは正常に動作します。その後、接続が復活した時に内容がサーバーと同期されます。</p>

<p>また、標準ライブラリに加えて、REST APIを使用する非公式なライブラリとして以下の様なものもあります。これ以外にもいろいろとありますので、サーバーサイドで自分の好きな言語を利用したい場合はGitHubなどで検索してみるといいでしょう。</p>

<ul>
<li><a href="http://ozgur.github.io/python-firebase/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Python-Firebase</a>（Python）</li>
<li><a href="https://github.com/ktamas77/firebase-php" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firebase-Php</a>（PHP）</li>
<li><a href="https://github.com/oscardelben/firebase-ruby" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Firebase-Ruby</a>（Ruby）</li>
<li><a href="http://derailed.github.io/bigbertha" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BigBertha</a>（Ruby）</li>
<li><a href="https://github.com/CodementorIO/rest-firebase" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Rest-Firebase</a>（Ruby）</li>
</ul>

<p>なお、標準クライアントライブラリを使用した場合はオフラインでの動作が保証されますが、非公式ライブラリを使用した場合はその限りではありません。</p>

<h2>サンプルアプリケーション</h2>

<p>Firebaseを使用した基本的なアプリケーション開発の流れを確認するために簡単なチャットアプリケーションを作成してみましょう。先に紹介したとおりFirebaseクライアントライブラリは環境に応じて複数ありますが、今回はJavaScript版クライアントライブラリを使用してWebアプリケーションを作成します。</p>

<div id="attachment_18083" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/bb56fbf12877898b24cd5b42c9fce5a5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/bb56fbf12877898b24cd5b42c9fce5a5-300x213.png" alt="サンプルチャット" width="300" height="213" class="size-medium wp-image-18083" srcset="/wp-content/uploads/2016/01/bb56fbf12877898b24cd5b42c9fce5a5-300x213.png 300w, /wp-content/uploads/2016/01/bb56fbf12877898b24cd5b42c9fce5a5.png 640w, /wp-content/uploads/2016/01/bb56fbf12877898b24cd5b42c9fce5a5-207x147.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">サンプルチャット</p></div>

<h3>Firebaseアプリケーション作成</h3>

<p>まずはじめに、今回のサンプルから使用するデータベースを用意するため、ウェブコンソールからFirebaseアプリケーションを作成します。http://firebase.com/ を開き、画面右上のログインボタンをクリックしてログインしてください。</p>

<p>アカウントを新たに作成しても構いませんし、GoogleアカウントやGitHubアカウントを使用してログインすることもできます。</p>

<div id="attachment_18085" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/36fe728933b58011dce534fb2979b11d.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/36fe728933b58011dce534fb2979b11d-300x213.png" alt="Firebaseログイン後" width="300" height="213" class="size-medium wp-image-18085" srcset="/wp-content/uploads/2016/01/36fe728933b58011dce534fb2979b11d-300x213.png 300w, /wp-content/uploads/2016/01/36fe728933b58011dce534fb2979b11d.png 640w, /wp-content/uploads/2016/01/36fe728933b58011dce534fb2979b11d-207x147.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">Firebaseログイン後</p></div>

<p>ログイン後、左下の入力エリアにアプリ名とアプリURLを入力して、アプリを作成します。今回は以下の様な設定を使用するものとします。</p>

<table>
<tr><th>App Name</th><td>My First Chat App</td></tr>
<tr><th>App URL</th><td>https://my-first-chat-app.firebaseio.com/</td></tr>
</table>

<div id="attachment_18086" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/f6e4e49af30774d12e164a9df2864b08.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/f6e4e49af30774d12e164a9df2864b08-300x213.png" alt="スクリーンショット 2015-12-17 22.46.32" width="300" height="213" class="alignnone size-medium wp-image-18086" srcset="/wp-content/uploads/2016/01/f6e4e49af30774d12e164a9df2864b08-300x213.png 300w, /wp-content/uploads/2016/01/f6e4e49af30774d12e164a9df2864b08.png 640w, /wp-content/uploads/2016/01/f6e4e49af30774d12e164a9df2864b08-207x147.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">Firebaseアプリ新規作成</p></div>

<p>サーバーサイドで行う作業は以上です。これだけでNoSQLデータベースが作成され、クライアントアプリから自由に利用できるようになりました。</p>

<h3>サンプルアプリケーションの初期化</h3>

<p>サンプルアプリケーションは最終的にFirebaseホスティングサービスを利用するため、まずfirebase initコマンドを実行してプロジェクトディレクトリを初期化します。</p>

<p></p><pre class="crayon-plain-tag">% firebase init

? What Firebase do you want to use? my-first-chat-app
? What directory should be the public root? public
✔  Public directory public has been created
Firebase initialized, configuration written to firebase.json</pre><p></p>

<p>初期化にあたって</p>

<ol>
<li>アプリ名</li>
<li>デプロイするファイルを配置するディレクトリ</li>
</ol>

<p>を聞かれるので、アプリ名は先程作成したものを、ディレクトリ名はデフォルトのpublicを設定してください。</p>

<h3>ウェブアプリケーション作成</h3>

<p>それではここから実際に冒頭のサンプルアプリケーションを作成していくこととします。といっても必要となるのはHTMLファイルが一つだけ、それも非常に小さなものですので先に全体を見てしまいましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt;
&lt;html lang="ja"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;title&gt;Firebaseサンプル1&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div&gt;
      &lt;input id="name" placeholder="名前" /&gt;
      &lt;input id="message" placeholder="メッセージ" /&gt;
      &lt;button id="send"&gt;投稿&lt;/button&gt;
    &lt;/div&gt;
    &lt;ul id="messages"&gt;
    &lt;/ul&gt;

    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"&gt;&lt;/script&gt;
    &lt;script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"&gt;&lt;/script&gt;
    &lt;script&gt;
      // データベースの参照を準備
      var firebaseRef = new Firebase("https://my-first-chat-app.firebaseio.com/"); // ... 1
      var messagesRef = firebaseRef.child('messages'); // ... 2

      // 既存メッセージを表示
      messagesRef.on('child_added', function(snapshot) { // ... 3
        var msg = snapshot.val();
        $('&lt;li&gt;').text(msg.name + ': ' + msg.body).prependTo('#messages');
      });

      $('#send').click(function() {
        // 新規メッセージを投稿
        messagesRef.push({ // ... 4
          name: $('#name').val(),
          body: $('#message').val()
        });
      });
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>今回のサンプルアプリケーションのコードはこれだけ、コメントや空行を除けばJavaScript部分はたったの12行です。このコードをローカルに保存し、ブラウザで開いてみてください。HTMLを含めて全体でも40行弱のコードですが、複数ブラウザで開いて、一方でメッセージを入力すればその内容はリアルタイムに他方に反映され、（かろうじて）チャットとして利用できます。</p>

<p>コードの詳細については次回以降に譲りますが、簡単に説明すると、行われている処理は以下のとおりです。</p>

<ol>
<li>アプリケーションURLを引数としてFirebaseオブジェクトをインスタンス化し、前節で作成したFirebaseデータベースに接続するためのオブジェクトを生成します。</li>
<li>Firebaseデータベースのmessagesオブジェクトへの参照を取得します。この参照への操作はサーバー上のFirebaseデータベースに保存されることになります。</li>
<li>messagesオブジェクトに子ノードが追加された場合のコールバック関数を登録します。今回はコールバック関数内でメッセージの内容をli要素としてul要素に追加しています。なお、onメソッドで登録されたコールバック関数はHTMLの初回読み込み時にも実行されるため、初回読み込み時用の処理を特別に記述する必要はありません。</li>
<li>messagesオブジェクトに子ノードを追加します。</li>
</ol>

<h4>オフライン対応の確認</h4>

<p>さて、ここで一つ面白い実験をしてみましょう。複数のブラウザでサンプルアプリを開き、使用しているコンピューターのネットワークをOFFにしてください。</p>

<p>そのまま一方の画面でメッセージをいくつか入力すると、メッセージを入力した画面では新しいメッセージがリストに追加されますが、他方の画面にはメッセージが追加されません。</p>

<p>その状態でコンピューターのネットワークをONにするとどうでしょう。少し経って他方の画面にもメッセージが表示されるのが確認できるはずです。</p>

<div id="attachment_18109" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/firebasedb-1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/firebasedb-1-300x120.png" alt="firebasedb" width="300" height="120" class="alignnone size-medium wp-image-18109" srcset="/wp-content/uploads/2016/01/firebasedb-1-300x120.png 300w, /wp-content/uploads/2016/01/firebasedb-1.png 640w, /wp-content/uploads/2016/01/firebasedb-1-207x83.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">ネットワークが正常</p></div>

<p>実はFirebaseデータベースの読み書きはいったんローカルDBを経由して行われています。そのためネットワーク接続が不通の場合もローカル側の処理は正常に完了し、ネットワークが回復すると自動的にデータがサーバーと同期されるのです。</p>

<div id="attachment_18110" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/firebasedb2-1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/firebasedb2-1-300x120.png" alt="firebasedb2" width="300" height="120" class="alignnone size-medium wp-image-18110" srcset="/wp-content/uploads/2016/01/firebasedb2-1-300x120.png 300w, /wp-content/uploads/2016/01/firebasedb2-1.png 640w, /wp-content/uploads/2016/01/firebasedb2-1-207x83.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">ネットワーク異常発生</p></div>

<div id="attachment_18111" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/firebasedb3-1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/firebasedb3-1-300x120.png" alt="firebasedb3" width="300" height="120" class="alignnone size-medium wp-image-18111" srcset="/wp-content/uploads/2016/01/firebasedb3-1-300x120.png 300w, /wp-content/uploads/2016/01/firebasedb3-1.png 640w, /wp-content/uploads/2016/01/firebasedb3-1-207x83.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">ネットワーク復旧</p></div>

<p>これによりアプリケーション開発者はネットワークの状態を一切意識することなくリアルタイムアプリケーションを作成することができます。</p>

<p>リアルタイムに状態を同期する必要がある場合、この機能だけでもFirebaseを採用する価値があるのではないかと私は思うのですが、みなさんはいかがでしょうか？</p>

<h3>データベースの内容確認</h3>

<p>サンプルアプリにメッセージをいくつか書き込んだらダッシュボードでデータベースがどうなっているか、内容を確認してみましょう。https://アプリケーションID.firebaseio.com/ にアクセスしてみてください。</p>

<div id="attachment_18115" style="width: 310px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2016/01/5aaca8f4177775d53bb44e9805facbf5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/01/5aaca8f4177775d53bb44e9805facbf5-300x229.png" alt="データベース確認" width="300" height="229" class="size-medium wp-image-18115" srcset="/wp-content/uploads/2016/01/5aaca8f4177775d53bb44e9805facbf5-300x229.png 300w, /wp-content/uploads/2016/01/5aaca8f4177775d53bb44e9805facbf5.png 640w, /wp-content/uploads/2016/01/5aaca8f4177775d53bb44e9805facbf5-207x158.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a><p class="wp-caption-text">データベース確認</p></div>

<p>ちゃんと登録されています。</p>

<p>ちなみにこのダッシュボードから値を変更することもでき、その場合ももちろんクライアント側のイベントハンドラが発火され、ブラウザ側の表示はリアルタイムに変更されます。</p>

<h3>デプロイ</h3>

<p>最後に、今回のアプリケーションをFirebaseにデプロイして実際に利用できるようにします。firebase initコマンドを実行したディレクトリでfirebase deployコマンドを実行してください。</p>

<p></p><pre class="crayon-plain-tag">% firebase deploy

=== Deploying to 'my-first-chat-app'...

i  deploying hosting
i  preparing public directory for upload...
✔  1 files uploaded successfully

✔  Deploy complete!

URL: https://my-first-chat-app.firebaseapp.com/
Dashboard: https://my-first-chat-app.firebaseio.com/

Visit the URL above or run firebase open</pre><p></p>

<p>では、ブラウザで <a href="https://my-first-chat-app.firebaseapp.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://my-first-chat-app.firebaseapp.com/</a> を開いてみましょう。開発時と同じデータベースを参照しているので先ほど入力したメッセージがここでも表示されています。</p>

<p>ちなみにアプリのドメインは firebaseapp.com で、ダッシュボードのドメインは firebaseio.com です。うっかり打ち間違えないように気をつけましょう。</p>

<h2>まとめ</h2>

<p>いかがでしょう。Firebaseを使用すれば非常に簡単にリアルタイムアプリケーションが作成できるということが分かっていただけたのではないでしょうか。</p>

<p>今回はFirebaseの全体的な機能の概要を説明しました。次回はもう少し複雑なアプリケーションを作りながら、Firebaseのそれぞれの機能をより詳細に掘り下げていきたいと思います。お楽しみに。</p>
]]></content:encoded>
			</item>
		<item>
		<title>Angry Birdsの3D版!?「Enraged Fowls」の技術解説（物理エンジン編）</title>
		<link>/technohippy/10203/</link>
		<pubDate>Thu, 28 Aug 2014 00:00:46 +0000</pubDate>
		<dc:creator><![CDATA[あんどう やすし]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[5jcup]]></category>
		<category><![CDATA[cannon.js]]></category>

		<guid isPermaLink="false">/?p=10203</guid>
		<description><![CDATA[連載： HTML5 Japan Cup 特集 (4)本記事はHTML5 Japan Cup 2014で優秀賞を頂いたEnraged Fowlsというゲームについての技術解説後編です。前編はこちらです。 物理エンジン 前編...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/5jcup-2/" class="series-207" title="HTML5 Japan Cup 特集" data-wpel-link="internal">HTML5 Japan Cup 特集</a> (4)</div><p>本記事は<a href="https://5jcup.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Japan Cup 2014</a>で優秀賞を頂いた<a href="https://5jcup.org/works/53a25c7120a279d145003005" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Enraged Fowls</a>というゲームについての技術解説後編です。<a href="https://html5experts.jp/technohippy/10084/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">前編</a>はこちらです。</p>

<h2>物理エンジン</h2>

<p><a href="https://html5experts.jp/technohippy/10084/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">前編</a>ではスリングショットコントローラーについて説明しましたが、ゲーム本体の技術要素についてはほぼ触れていませんでした。Enraged Fowlsでは弾が飛んでいく動きや、弾がぶつかって崩れるブロックの動きなどを実現するために、物理エンジンを使用しています。物理エンジンは文字通り、物理的な運動をコンピューター上で模擬してくれるライブラリで、特に今回のアプリのような物体同士の衝突を処理する必要がある場合に有用です。Enraged Fowls技術解説後編では、この物理エンジンについて簡単に説明します。</p>

<h3>cannon.js</h3>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/1d9cceeb88131b71b627b09152dda517.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/1d9cceeb88131b71b627b09152dda517-300x246.png" alt="スクリーンショット 2014-08-19 19.05.47" width="300" height="246" class="alignnone size-medium wp-image-10208" srcset="/wp-content/uploads/2014/08/1d9cceeb88131b71b627b09152dda517-300x246.png 300w, /wp-content/uploads/2014/08/1d9cceeb88131b71b627b09152dda517-207x170.png 207w, /wp-content/uploads/2014/08/1d9cceeb88131b71b627b09152dda517.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p><a href="http://www.cannonjs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">cannon.jsについて</a></p>

<p>3次元を扱えるものに限っても、JavaScriptで実装された物理エンジンはいくつかあります。Enraged Fowlsではその中からcannon.jsという物理エンジンを採用しました。これは他の物理エンジンの多くが他言語製物理エンジンの移植で、インターフェースに違和感があったのに対して、cannon.jsはJavaScriptで新たに作成された物理エンジンなので、インターフェースが素直に見えたことと内部構造がシンプルだったためです。</p>

<p>なお、実際のEnraged Fowlsのコードは自作のライブラリを使っていて、物理エンジンの説明向きではなかったため、今回使用しているサンプルコードは、すべて説明用に単純化したEnraged Fowlsから抜き出したものになっています。単純化したコードの全文は以下にありますので、適宜参照してください。</p>

<p><a href="https://github.com/technohippy/enragedfowls-simple/blob/master/js/angry-birds-simple.js" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">簡易版Enraged Fowlsのコード全文
</a></p>

<h3>全体的な流れ</h3>

<p>物理エンジンは、物体の位置や向きを計算してくれるだけで、物体の表示には関知しません。表示に関しては、three.jsをいつも通りに使うことになります。両者を組み合わせる場合の基本的な流れは、次のようになります。</p>

<ol>
<li><strong>物理エンジンを初期化</strong></li>
<li>three.jsを初期化</li>
<li><strong>物理エンジンに物体（形状・位置・向き・速度など）を登録</strong></li>
<li>three.jsに物体（形状）を登録</li>
<li><strong>物理エンジンの物体とthree.jsの物体を関連付け</strong></li>
<li>以下を繰り返し

<ol>
<li><strong>物理エンジンに登録された物体の次の位置と向きを計算</strong></li>
<li><strong>three.jsの物体の位置と向きを、物理エンジンの関連する物体と同期</strong></li>
<li>three.jsの表示を更新</li>
</ol></li>
</ol>

<p>物理エンジンとthree.jsで、別個に物体を扱っているのが冗長に感じられるかもしれませんが、これには理由があります。両者を区別していることで、1つの物体に対して2種類のモデルを使用できるのです。例えばthree.js内で複雑な人型として扱われているオブジェクトを、物理エンジン内では単なる直方体として扱い、当たり判定を簡略化することができます。</p>

<p>上記のリストで重要なのは、5と6-2です。基本的にはオブジェクトの位置と向きは物理エンジンが管理し、オブジェクトの（表示される）形状はthree.jsが管理しますが、それぞれの情報の関連付けは開発者に委ねられます。5と6-2は、この情報の関連付けを処理しています。</p>

<p>本記事での解説は、上記の物理エンジンに関わる部分を抜き出す形で行います。</p>

<h3>物理エンジンを初期化</h3>

<p></p><pre class="crayon-plain-tag">AngryBirds.Game.prototype = {
  constructPhysicalWorld: function() {
    this.cannonWorld = new CANNON.World();
    this.cannonWorld.gravity.set(0,-9.82,0);
    this.cannonWorld.broadphase = new CANNON.NaiveBroadphase();
    // ...snip...
  },
}</pre><p></p>

<p>cannon.jsでは、物理エンジンの実体はCANNON.Worldオブジェクトです。物理エンジン全体に関わる設定や処理は、このオブジェクトを通じて行います。設定しているプロパティはそれぞれ、gravityは名前の通り重力、broadphaseは「衝突している可能性のあるオブジェクトの組み合わせを見つけるアルゴリズム」です(注1)。設定できる値はほかにもありますが、とりあえずこの2つをこの通りに設定しておけば動作します。</p>

<p>注1: 通常、物理エンジンは衝突判定をBroad PhaseとNarrow Phaseの2段階に分け、はじめにBroad Phaseで衝突している可能性のあるオブジェクトの組み合わせをなるべく素早く見つけ出し、次にそれらのオブジェクトが実際に衝突しているかどうかを、Narrow Phaseで厳密に検査します。Broad Phaseのアルゴリズムは、物理エンジンのパフォーマンスに大きく影響を与えるため、cannon.jsではプロパティとして与える形でその変更を容易にしています。</p>

<h3>物理エンジンに物体を登録</h3>

<p></p><pre class="crayon-plain-tag">AngryBirds.Game.prototype = {
  constructPhysicalWorld: function() {
    // 地面
    var groundShape = new CANNON.Plane();
    var groundWeight = 0; // 固定
    this.cannonGround = new CANNON.RigidBody(groundWeight, groundShape); // ...(1)
    this.cannonGround.quaternion = new CANNON.Quaternion();
    this.cannonGround.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2); // ...(2)

    // 鳥
    var birdShape = new CANNON.Sphere(0.5);
    var birdWeight = 10;
    this.cannonBird = new CANNON.RigidBody(birdWeight, birdShape); // ...(3)
    this.cannonBird.position.set(0, 2.5 + 2 + 0.1, 0);

    // CANNON.Worldに追加
    this.cannonWorld.add(this.cannonGround);
    this.cannonWorld.add(this.cannonBird);

    // ...snip...
  },
}</pre><p></p>

<p>cannon.jsでは、物体はCANNON.RigidBodyオブジェクトとして表され、物体の位置や向きの設定などはこのオブジェクトを通じて行います。ただし、物体の形状はCANNON.RigidBodyオブジェクトからは分離されていて、その指定にはCANNON.Shapeオブジェクトのサブクラスを使用します。上記の例では、CANNON.Plane（平面）とCANNON.Sphere（球体）を利用していますが、それ以外にも以下のような形状が使用可能です。</p>

<ul>
<li>CANNON.Sphere: 球体</li>
<li>CANNON.Plane: 平面</li>
<li>CANNON.Box: 直方体</li>
<li>CANNON.ConvexPolyhedron: 凸型多面体</li>
<li>CANNON.Compound: 上記の組み合わせ</li>
</ul>

<p>なお平面はデフォルトではz軸に垂直ですが、cannon.jsでは重力はy軸に垂直なので、地面として使用するためにquaternionを設定して、x軸に対して90度回転させています。</p>

<h3>物理エンジンの物体とthree.jsの物体を関連付け</h3>

<p>物理エンジンの物体とthree.jsの物体を関連付けについては、特に決まったやり方はありません。管理する物体の数が少なければ、単純に1つの物体に対してcannon.js用とthree.js用、2種類のオブジェクトを用意すればいいでしょう。今回の単純化したコードでは、threeFooとcannonFooという2変数で管理しています。</p>

<p></p><pre class="crayon-plain-tag">AngryBirds.Game = function(opts) {
  // ...snip...
  this.threeGround = null;
  this.threeBlocks = null;
  this.threeBird = null;
  this.cannonGround = null;
  this.cannonBlocks = null;
  this.cannonBird = null;
};</pre><p></p>

<p>実際のEnraged Fowlsでは、three.jsのオブジェクトとcannon.jsのオブジェクトを1つにまとめて使うための<a href="https://github.com/technohippy/enragedfowls/blob/master/js/c3.js" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">c3.js</a>という簡単なライブラリを作成しましたが、まだ公開するような完成度ではないので、ここでは説明を省略します。</p>

<h3>物理エンジンに登録された物体の次の位置と向きを計算</h3>

<p></p><pre class="crayon-plain-tag">this.cannonWorld.step(1.0/24.0);</pre><p></p>

<p>物体の位置を更新するには、CANNON.Worldオブジェクトのstepメソッドに経過時間を渡します。これだけで先にaddした物体間の衝突が処理され、位置や向きがそれぞれの運動状態に応じて更新されます。</p>

<h3>three.jsの物体の位置と向きを、物理エンジンの関連する物体と同期</h3>

<p></p><pre class="crayon-plain-tag">this.threeBird.position.copy(this.cannonBird.position);
this.threeBird.quaternion.copy(this.cannonBird.quaternion);</pre><p></p>

<p>先ほどCANNON.Worldオブジェクトのstepメソッドを呼び出しましたが、このメソッドはCANNON.RigidBodyの位置と向きを更新するだけです。表示位置を更新するには、描画の前にthree.js側のオブジェクトとcannon.jsのオブジェクトの位置を同期する必要があります。cannon.jsはthree.jsと組み合わせて使うことが初めから想定されているため、これは非常に簡単です。three.jsのオブジェクトのpositionプロパティ（位置）とquaternionプロパティ（向き）に、cannon.jsのオブジェクトのそれらをcopyしてください。これだけで位置と向きの同期が実現されます。</p>

<p>ここまでの実装を行うと、次のように衝突がそれっぽく扱われるようになります。</p>

<div id="attachment_10220" style="width: 292px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/08/716c6c1ad8f4d575b797eb476eb3c8891.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/716c6c1ad8f4d575b797eb476eb3c8891-282x300.png" alt="物理エンジン前（貫通）" width="282" height="300" class="size-medium wp-image-10220" srcset="/wp-content/uploads/2014/08/716c6c1ad8f4d575b797eb476eb3c8891-282x300.png 282w, /wp-content/uploads/2014/08/716c6c1ad8f4d575b797eb476eb3c8891-194x207.png 194w, /wp-content/uploads/2014/08/716c6c1ad8f4d575b797eb476eb3c8891.png 423w" sizes="(max-width: 282px) 100vw, 282px" /></a><p class="wp-caption-text">物理エンジン前（貫通）</p></div>

<div id="attachment_10218" style="width: 305px" class="wp-caption alignnone"><a href="https://html5experts.jp/wp-content/uploads/2014/08/7988911360b8bea2eb18aa93cdd5c10e.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/7988911360b8bea2eb18aa93cdd5c10e-295x300.png" alt="物理エンジン後" width="295" height="300" class="size-medium wp-image-10218" srcset="/wp-content/uploads/2014/08/7988911360b8bea2eb18aa93cdd5c10e-295x300.png 295w, /wp-content/uploads/2014/08/7988911360b8bea2eb18aa93cdd5c10e-203x207.png 203w, /wp-content/uploads/2014/08/7988911360b8bea2eb18aa93cdd5c10e.png 443w" sizes="(max-width: 295px) 100vw, 295px" /></a><p class="wp-caption-text">物理エンジン後（瓦解中）</p></div>

<h2>まとめ</h2>

<p>モデリングツールを覚えるような時間もモチベーションもなかったため、Enraged Fowlsはthree.jsに用意されている基本図形だけでできています。それでも物理エンジンを使用すれば、その動きで見た目をある程度はカバーできていると言っていいのではないでしょうか。</p>

<p>今回の記事から分かる通り、物理エンジンの利用は存外に簡単です。初期位置を登録してstepメソッドを呼び出し結果を表示に反映させる、これだけです。three.jsを使用して単なるビューアーに留まらないインタラクティブなアプリを作るのであれば、物理エンジンを採用しない理由はありません。本記事を参考に、ぜひいろいろと試してみてください。</p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Japan Cup 特集]]></series:name>
	</item>
		<item>
		<title>Angry Birdsの3D版!?「Enraged Fowls」の技術解説（コントローラー編）</title>
		<link>/technohippy/10084/</link>
		<pubDate>Wed, 27 Aug 2014 00:00:13 +0000</pubDate>
		<dc:creator><![CDATA[あんどう やすし]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[5jcup]]></category>
		<category><![CDATA[WebRTC]]></category>
		<category><![CDATA[WebWorkers]]></category>

		<guid isPermaLink="false">/?p=10084</guid>
		<description><![CDATA[連載： HTML5 Japan Cup 特集 (3)本記事はHTML5 Japan Cup 2014で優秀賞を頂いたEnraged Fowlsというゲームに関する技術的な解説の前編です。 Enraged Fowlsとは ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/5jcup-2/" class="series-207" title="HTML5 Japan Cup 特集" data-wpel-link="internal">HTML5 Japan Cup 特集</a> (3)</div><p>本記事は<a href="https://5jcup.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Japan Cup 2014</a>で優秀賞を頂いた<a href="http://technohippy.github.io/enragedfowls/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Enraged Fowls</a>というゲームに関する技術的な解説の前編です。</p>

<h2>Enraged Fowlsとは</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a-300x199.png" alt="スクリーンショット 2014-08-16 1.41.20" width="300" height="199" class="alignnone size-medium wp-image-10088" srcset="/wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a-300x199.png 300w, /wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a-1024x681.png 1024w, /wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a-207x137.png 207w, /wp-content/uploads/2014/08/ef9fb494aaf85324e475fd93838bd91a.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>タイトルに使われているのは聞きなれない単語かもしれませんが、それぞれ類語辞典で調べたAngryとBirdの同義語です。「<a href="https://www.angrybirds.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Angry Birds</a>」については、おそらく皆さんご存知でしょう。全世界で累計15億ダウンロード（<a href="http://ja.wikipedia.org/wiki/Angry_Birds" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Wikipedia</a>）されたアクションパズルゲームで、物理エンジンを使用してスリングショットで撃ち込まれた鳥と、それにより崩れ落ちるブロックのリアルな動きを実現していることが大きな特徴です。上のスクリーンショットからも分かる通り、「Enraged Fowls」はこの「Angry Birds」を3Dにすることを目指したものです。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="373" height="210" src="//www.youtube.com/embed/VGVn8wb9-Ag" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>


<p><BR>
　加えて、Enraged Fowlsならではの機能としてスマホをセットして使用できる、スリングショット型のお手製コントローラーがあります。当コントローラーを使用すれば、モニターの中の世界に対して、実際にスリングショットで鳥を撃ちこんでいるような感覚を得ることができます。</p>

<h2>技術要素</h2>

<p>Enraged Fowlsの技術的な見どころとしては大きく</p>

<ol>
<li>スリングショットコントローラー</li>
<li>3Dの表示と動き</li>
</ol>

<p>の2つがあると考えています。具体的な技術要素を挙げると以下の様になるでしょうか。</p>

<ul>
<li>WebRTC（スリングショットコントローラー）</li>
<li>Web Workers（スリングショットコントローラー）</li>
<li>WebGL（three.js）</li>
<li>3D物理エンジン（cannon.js）</li>
</ul>

<p>この中でthree.jsについては、今回の「HTML5 Japan Cup 2014」の優秀・最優秀作4作品のうち、Enraged Fowlsを含む3作品が使用していることもあり、おそらく別の記事で解説されると判断して、本記事では説明を省略します。HTML5 Experts.jpにもthree.jsの解説記事がありますので、そちらを参考にしてもいいでしょう。</p>

<p><a href="https://html5experts.jp/yomotsu/5225/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">初心者でも絶対わかる、WebGLプログラミング＜three.js最初の一歩＞</a></p>

<p>また（three.jsを除いても）上記すべてを一度に解説することができなかったため、今回はスリングショット部について解説します。物理エンジンに興味のある方は次回までお待ちください。なお、Enraged Fowlsのソースコードは以下で全て公開されています。必要に応じて参照してください。</p>

<p><a href="https://github.com/technohippy/enragedfowls" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Enraged Fowlsのソースコード</a></p>

<h2>スリングショットコントローラー</h2>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/medium_IMG_20140629_010646.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/medium_IMG_20140629_010646-300x204.jpg" alt="medium_IMG_20140629_010646" width="300" height="204" class="alignnone size-medium wp-image-10094" srcset="/wp-content/uploads/2014/08/medium_IMG_20140629_010646-300x204.jpg 300w, /wp-content/uploads/2014/08/medium_IMG_20140629_010646-1024x697.jpg 1024w, /wp-content/uploads/2014/08/medium_IMG_20140629_010646-207x140.jpg 207w, /wp-content/uploads/2014/08/medium_IMG_20140629_010646.jpg 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>スリングショットコントローラーは、本物のスリングショットのようにコントローラを移動して狙いをつけます。そして、ゴム紐を引いて手を離し弾を撃つという操作を、ウェブカメラとスマートフォンの加速度センサーを利用して実現したものです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/398520a7a7b1ce6e75679a577aa51291.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/398520a7a7b1ce6e75679a577aa51291-300x161.png" alt="スクリーンショット 2014-08-18 14.24.59" width="300" height="161" class="alignnone size-medium wp-image-10109" srcset="/wp-content/uploads/2014/08/398520a7a7b1ce6e75679a577aa51291-300x161.png 300w, /wp-content/uploads/2014/08/398520a7a7b1ce6e75679a577aa51291-207x111.png 207w, /wp-content/uploads/2014/08/398520a7a7b1ce6e75679a577aa51291.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>（もちろん上記のような工作をしなくてもスマートフォンさえあれば、ウェブカムの前にかざして画面をタップするか端末の裏面を指で弾けば動作を確認することができるので、よかったら試してみてください）</p>

<h3>ウェブカムによるスマートフォンの位置の特定</h3>

<p>ウェブカメラに写るスマートフォンの位置を取得する方法は、正直かなり手を抜いていて、スマートフォンの画面を真っ赤にし、ウェブカムの「赤い部分」の平均値をスマートフォンの位置と見なしています。スリングショットコントローラーは、締め切りの一週間ほど前に、ふと思いついて追加した機能です。まず簡単な方法で実装して動作や使用感を検証し、精度が足りないようなら後できちんとしたやり方にしようと考えて実装しましたが、ちょっと遊ぶ分には大して問題もなかったため、結局そのまま今に至っています。まぁよくあることです。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/792dd322f11a7bd38696dea3dfa2d7ff.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/792dd322f11a7bd38696dea3dfa2d7ff-300x113.png" alt="スクリーンショット 2014-08-18 14.00.36" width="300" height="113" class="alignnone size-medium wp-image-10098" srcset="/wp-content/uploads/2014/08/792dd322f11a7bd38696dea3dfa2d7ff-300x113.png 300w, /wp-content/uploads/2014/08/792dd322f11a7bd38696dea3dfa2d7ff-207x78.png 207w, /wp-content/uploads/2014/08/792dd322f11a7bd38696dea3dfa2d7ff.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a>
<br />（右側の画像の緑のドットが&#8221;赤&#8221;と認識された箇所です）</p>

<p>ソースコードの該当部分を以下に抜粋します。</p>

<p></p><pre class="crayon-plain-tag">Detector.prototype.startCamera = function() {
  // ウェブカムの映像取り込み
  navigator.getUserMedia({video: true}, // ... (1)
    function(localMediaStream) {
      // ウェブカムの映像をvideo要素で表示
      this.video.src = window.URL.createObjectURL(localMediaStream); // ... (2)
      this.video.play();
    }.bind(this),
    function(err) { ... }.bind(this)
  );
};

Detector.prototype.startWorker = function() { // ... (3)
  // 画像解析用WebWorker開始
  this.worker = new Worker('js/detector_worker.js');
  this.worker.addEventListener('message', function(event) {
    // WebWorkerから返された解析結果を処理
    this.detectHandlers.forEach(function(handler) {
      handler(event.data, this.gc);
    }.bind(this));
    if (this.isDetecting) setTimeout(this.detect.bind(this), 10);
  }.bind(this));
};

Detector.prototype.detect = function() { // ... (4)
  // video要素の内容を取り込んでWebWorkerで処理
  this.gc.drawImage(this.video, 0, 0, this.video.width, this.video.height);
  this.worker.postMessage(this.gc.getImageData(0, 0, this.video.width, this.video.height));
};</pre><p></p>

<p>スマートフォンの位置の特定は、Detectorオブジェクトで行います。Detectorオブジェクトはdetector.jsとdetector_worker.jsの2つからなっていて、detector.jsではnavigator.getUserMedia関数を使用してウェブカムの画像をvideo要素に取り込み(1)(2)、画像解析用のWebWorkerを開始し(3)、定期的にvideo要素の内容をWebWorkerに送ります(4)。現在のところdetector_worker.jsでは非常に単純な解析しか行っておらず、WebWorkerを使わなくてもそれほど問題にはならないかもしれませんが、将来的に複雑な解析を行うことを可能にするために、バックグラウンドで処理しています。</p>

<p></p><pre class="crayon-plain-tag">// 直近10回の解析結果を保持
var centers = [];

addEventListener('message', function(event) {
  var imageData = event.data;
  var data = imageData.data;
  var redPoints = [];

  // 画像データを走査して赤い部分（isRed）の位置を記録
  for (var x = 0; x &amp;lt; imageData.width; x+=5) {
    for (var y = 0; y &amp;lt; imageData.height; y+=5) {
      var base = x * 4 + y * imageData.width * 4;
      if (isRed(data[base], data[base+1], data[base+2], data[base+3])) { // ... (5)
        redPoints.push({x:x, y:y});
      }
    }
  }

  // 直近10回の赤い部分の中心位置を記録
  var center = getCenter(redPoints);
  while (10 &amp;lt;= centers.length) centers.shift();
  centers.push(center);

  // 直近10回の平均位置を取得
  var centerAverage = getCenterAverage(centers); // ... (6)
  
  // WebWorker呼び出し元に結果を返却
  postMessage({
    redPoints:{points:redPoints, center:center, 
      centerAverage:centerAverage, size:redPoints.length}
  });
});

function isRed(r, b, g, a) {
  // なんとなく赤っぽい色を判定
  return 250 &amp;lt; a &amp;amp;&amp;amp; 100 &amp;lt; r &amp;amp;&amp;amp; g &amp;lt; r/2.0 &amp;amp;&amp;amp; b &amp;lt; r/2.0;
}</pre><p></p>

<p>先に書いた通り、detector_woker.jsの中心的な処理はImageDataオブジェクト内の赤い部分を抜き出して、その中心位置を返すことです。基本的にはImageDataの画素の色をチェックしているだけですが(5)、特に厳密な解析も不要なので全画素をチェックするのではなくある程度間引いた値をチェックし、それにより発生するチラツキを直近10回の解析結果の平均を返すことで防いでいるのが(6)、工夫といえば工夫です。</p>

<p>ちなみに、「赤い部分の位置の平均を取るだけだと服や部屋が赤かったりすると問題が起きるんじゃないか？」と思う人もいるでしょうが、おっしゃる通り、割と大変なことになります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/4c3dd77191ab2b17b10f7fd33249a33e.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/4c3dd77191ab2b17b10f7fd33249a33e-300x113.png" alt="スクリーンショット 2014-08-18 14.06.23" width="300" height="113" class="alignnone size-medium wp-image-10102" srcset="/wp-content/uploads/2014/08/4c3dd77191ab2b17b10f7fd33249a33e-300x113.png 300w, /wp-content/uploads/2014/08/4c3dd77191ab2b17b10f7fd33249a33e-207x78.png 207w, /wp-content/uploads/2014/08/4c3dd77191ab2b17b10f7fd33249a33e.png 640w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>解決策はいろいろあると思うので、まぁ読者の皆さんへの宿題というか、pullreqは随時受付中です。</p>

<h3>Detectorオブジェクトの利用</h3>

<p></p><pre class="crayon-plain-tag">this.detector = new Detector();
this.detector.addDetectHandler(function(data, gc) {
  // ウェブカム画像内のスマートフォンの位置を正規化
  var center = data.redPoints.centerAverage;
  var dx = center.x / Detector.DEFAULT_WIDTH - 0.5;
  var dy = center.y / Detector.DEFAULT_HEIGHT - 0.5;

  this.cameraDirection = new THREE.Vector3(0, 0, 5);

  // y軸方向の位置を射出の縦方向に変換
  var yAxis = new THREE.Vector3(0, 1, 0);
  var yawAngle = -dx * Math.PI/2;
  var yawMatrix = new THREE.Matrix4().makeRotationAxis(yAxis, yawAngle);
  this.cameraDirection.applyMatrix4(yawMatrix);

  // x軸方向の位置を射出の横方向に変換
  var xAxis = new THREE.Vector3(1, 0, 0);
  var pitchAngle = -dy * Math.PI/4 - Math.PI/8;
  var pitchMatrix = new THREE.Matrix4().makeRotationAxis(xAxis, pitchAngle);
  this.cameraDirection.applyMatrix4(pitchMatrix);

  // 視点とカメラの向きを射出方向に合わせて変更
  this.world.threeCamera.position.copy(new THREE.Vector3().copy(
    this.bird.threeMesh.position).sub(this.cameraDirection));
  this.world.threeCamera.lookAt(this.bird.threeMesh.position);
}.bind(this));
this.detector.start();</pre><p></p>

<p>Detectorを利用する側のコードは、上記のようになります。Detectorオブジェクト自体はなるべく汎用的にしたかったので、Enraged Fowls独自の処理はaddDetectHandler関数で、利用側がハンドラ登録するようにしています。</p>

<p>一見複雑な処理にみえるかもしれませんが、要は下の図のように、目の前に固定されたスリングショットがあるイメージで、ウェブカム映像内でスマートフォンが写っている位置に応じて、撃ち出す方向や視点を変更しているだけです。具体的な座標変換についてはコードが全てですし、説明を省略します。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/anim.gif" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/anim.gif" alt="anim" width="300" height="231" class="alignnone size-medium wp-image-10130" /></a></p>

<h3>加速度センサーによるゴム紐リリースの検知</h3>

<p>スリングショットで狙いを付けることができるようになったので、次にゴム紐を伸ばして離すことで、狙いをつけた方向に鳥（弾）を撃てるようにします。正直なところ、これも非常に手を抜いたやり方で実装しています。</p>

<p></p><pre class="crayon-plain-tag">window.addEventListener('devicemotion', function(event) {
  var threshold = 5;
  if (threshold &amp;lt; Math.abs(event.acceleration.z)) {
    toggleMarkerColor();
  }
});</pre><p></p>

<p>windowオブジェクトのdevicemotionイベントで、端末にかかる加速度を取得できます。スマートフォンの画面に対して垂直な方向はz軸方向なので、event.acceleration.zの値がある閾値を超えたときに、スマートフォンの裏側に何かしらの衝撃があったと判断できます。その衝撃を検知したことをアプリ本体に伝えられればいいわけですが、ここでも先ほどのDetectorオブジェクトを使用します。つまり衝撃を検知したときにスマートフォンの画面の色を赤から青に変更し、その色の変化を先のDetectorオブジェクトで検知してアプリに伝え、鳥（弾）を発射します。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/08/3df13bc490329152910634962a56c357.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/3df13bc490329152910634962a56c357-170x300.png" alt="スクリーンショット 2014-08-18 23.39.59" width="85" height="150" class="alignnone size-medium wp-image-10133" srcset="/wp-content/uploads/2014/08/3df13bc490329152910634962a56c357-170x300.png 170w, /wp-content/uploads/2014/08/3df13bc490329152910634962a56c357-117x207.png 117w, /wp-content/uploads/2014/08/3df13bc490329152910634962a56c357.png 224w" sizes="(max-width: 85px) 100vw, 85px" /></a> &laquo;&raquo; <a href="https://html5experts.jp/wp-content/uploads/2014/08/ed3b06ec3c7faf3ab55092cb3a5e604b.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/08/ed3b06ec3c7faf3ab55092cb3a5e604b-170x300.png" alt="スクリーンショット 2014-08-18 23.40.31" width="85" height="150" class="alignnone size-medium wp-image-10134" srcset="/wp-content/uploads/2014/08/ed3b06ec3c7faf3ab55092cb3a5e604b-170x300.png 170w, /wp-content/uploads/2014/08/ed3b06ec3c7faf3ab55092cb3a5e604b-117x207.png 117w, /wp-content/uploads/2014/08/ed3b06ec3c7faf3ab55092cb3a5e604b.png 224w" sizes="(max-width: 85px) 100vw, 85px" /></a></p>

<p>勘のよい方はお気づきかと思いますが、z軸方向の加速度センサの値を見ているだけなので、例えば急にスマートフォンを裏返したり倒したりするだけで弾が暴発します。時間があればなんとかしようとも思っていたのですが、ちょっと遊ぶ分には大して問題もなかったため、結局そのまま今に至っています。まぁよくあることです。</p>

<p>加速度センサの値の履歴から特定のパターンの場合にだけ反応するなど解決策はいろいろあると思うので、読者の皆さんへの宿題というか、pullreq随時受付中です。</p>

<h3>まとめ</h3>

<p>スリングショットコントローラーに使用されている個々の技術は、非常に基本的で、特に難しいことも行っていません。ただそれらの組み合わせでスリングショットを実現したところは、ほんの少しだけ新しいのではないかと自負しています。</p>

<p>次回は、アプリ本体で使用している物理エンジンについて解説する予定です。</p>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Japan Cup 特集]]></series:name>
	</item>
		<item>
		<title>伝説のおっぱいエンジニアは先端技術の無駄遣いがお好き ── あんどうやすしさん（ミクシィ）</title>
		<link>/technohippy/2038/</link>
		<pubDate>Thu, 05 Sep 2013 22:00:34 +0000</pubDate>
		<dc:creator><![CDATA[あんどう やすし]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">/?p=2038</guid>
		<description><![CDATA[連載： エキスパートインタビュー (3)エキスパートインタビュー第三弾は、あんどうやすしさん。ミクシィのエンジニアとして働く傍ら、Google Developers Expertとして「開発者のためのChromeガイドブ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/interview/" class="series-152" title="エキスパートインタビュー" data-wpel-link="internal">エキスパートインタビュー</a> (3)</div><p>エキスパートインタビュー第三弾は、あんどうやすしさん。ミクシィのエンジニアとして働く傍ら、Google Developers Expertとして<a href="http://www.amazon.co.jp/dp/4844334220" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「開発者のためのChromeガイドブック」</a>を執筆するなど、精力的に活動されています。世界的に有名な物理エンジンライブラリ「<a href="http://box2d-js.sourceforge.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Box2D.js</a>の作者」という面もさることながら、「<a href="http://www.itmedia.co.jp/news/articles/1008/05/news081.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google Waveの人</a>」や「<a href="http://d.hatena.ne.jp/technohippy/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">おっぱいエンジニア</a>」など「おもしろい感じの人」としても有名なあんどうさんに、経歴や関心のあることなどをいろいろと伺ってみました。</p>

<p><span id="more-2038"></span></p>

<h2>業務系エンジニアから、30歳で留学 <br>　　　　　── 「やっちゃった感すごかったですよ」</h2>

<p><strong>──あんどうさんとは、意外と長い付き合いですが、そのご経歴とかはあまり伺ったことがありませんでした。どんな開発者人生を歩んでこられたんでしょうか？</strong></p>

<div id="attachment_694" style="width: 209px" class="wp-caption alignright"><a href="https://html5experts.jp/wp-content/uploads/2013/09/ando1.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/ando1-200x300.jpg" alt="エキスパートNO.5 あんどうやすしさん" width="200" height="300" class="alignright size-medium wp-image-2093" srcset="/wp-content/uploads/2013/09/ando1-200x300.jpg 200w, /wp-content/uploads/2013/09/ando1-138x207.jpg 138w, /wp-content/uploads/2013/09/ando1.jpg 426w" sizes="(max-width: 200px) 100vw, 200px" /></a><p class="wp-caption-text">エキスパートNO.5 あんどうやすしさん</p></div>

<p>以前はJavaを使った業務系のエンジニアでした。いわゆる「デスマーチ」も経験するような、「普通」の業務系エンジニアでしたよ。</p>

<p><strong>──あんどうさん、Javaもやってらしたんですね。RubyやJavaScriptなどをやっているイメージがとても強いので、意外です。</strong></p>

<p>はい、Javaは仕事で7～8年やっていました。今もAndroid周りの開発をやっているので、Javaを結構触っていたりします。型がない言語のほうが、書くのは楽しいですけどね。</p>

<p>で、30歳のころに心機一転、イギリスに1年間留学して、コンピューターサイエンスを学ぶことにしました。
ただ、英語が苦手な状態で行ってしまったのが、ちょっとまずかった。行ってから8カ月くらい、ほとんど誰とも話さなかったりしました。</p>

<p><strong>──8カ月！それは…つらかったんじゃないですか？　僕だったら寂しくて死んでしまいそうです。</strong></p>

<div id="attachment_694" style="width: 209px" class="wp-caption alignleft"><a href="https://html5experts.jp/wp-content/uploads/2013/09/shiraishi_2.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/shiraishi_2.jpg" alt="白石編集長" width="200" height="300" class="alignleft size-medium wp-image-2099" /></a><p class="wp-caption-text">白石編集長</p></div>

<p>そこは実は、全然つらくなかったんです。私は、人と喋らないのは苦にならないタイプみたいで。</p>

<p>ただ、「やっちゃった」感はすごかったですけどね（笑）。</p>

<p>留学前にTOEFLのトレーニングはしていったので、リスニング力は向上していました。
なので授業の内容は何となく分かるんですが、試験となるとそうはいかない。</p>

<p>おかげで学校も一度追い出されそうになったりして……。
学校追い出されたら、残りの時間はヨーロッパ旅行して帰ろうとか、本気で計画したものです。
結局は教授に頼み込んで、なんとかなったのですが。</p>

<p>私のイギリス留学は、そもそもの初めから送った荷物が2カ月くらい届かなかったりと、なかなかにハードでした。</p>

<p><strong>──あんどうさん、英語が結構得意なのかと思っていました。イギリスに行ったという話は聞いたことがあったのですが、英語が得意だから行けたのかな、と思っていました。そうじゃなかったんですね。</strong></p>

<p>そうです。それになんか、向こうに行きさえすれば必要に迫られて英語がものすごく上達するようなイメージってあるじゃないですか。
全然そんなことはないですよ！今後、留学したいと考えている人には、英語をきちんと学んでから行くことをオススメします。
たださすがに、耳が英語に慣れたおかげで、その後英語のコミュニケーションにはそれほど苦労しなくはなりました。</p>

<p>留学から戻ったあとはいくつかの転職を経験して、今はミクシィでプラットフォームを開発する部署に所属しています。</p>

<h2>「あの」伝説的エンジニアがHTML5を始めるきっかけを作った！「Webが進化したのは私のおかげ」</h2>

<p><strong>──あんどうさんは、物理エンジンライブラリである<a href="http://box2d-js.sourceforge.net/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Box2D.js</a>の開発でも有名ですね。世界中で使われているライブラリです。</strong></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2013/09/ando3.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/ando3-200x300.jpg" alt="あんどうやすし" width="200" height="300" class="alignright size-medium wp-image-2116" srcset="/wp-content/uploads/2013/09/ando3-200x300.jpg 200w, /wp-content/uploads/2013/09/ando3-138x207.jpg 138w, /wp-content/uploads/2013/09/ando3.jpg 426w" sizes="(max-width: 200px) 100vw, 200px" /></a></p>

<p>はい、ActionScript3版のBox2Dライブラリを、JavaScriptに移植したものですね。今では、<a href="https://code.google.com/p/box2dweb/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">box2dweb</a>などの後継も出てきていますが、JavaScript製物理エンジンとしては結構知られているんじゃないかと思います。</p>

<p>Box2D.jsが完成した瞬間、「これはすごいぞ」と考えて、<a href="http://ajaxian.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Ajaxian</a>とかにも投稿したんです。
でも、全然取り上げてもらえなくて。その後1年後くらいにとある記事で取り上げられて、それでやっとライブラリが知られるようになりました。はじめの頃は、その記事の執筆者がBox2D.jsの作者だという勘違いをされていて、納得いかないと感じたこともありましたけどね（笑）。</p>

<p><strong>──以前、<a href="http://www.mrdoob.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mr.doob</a>(※)も使っていたそうですね。</strong></p>

<p>そうなんですよ！
Mr.doobは、Flashのクリエイターとしても有名な人でしたが、「Box2D.jsがあったから、HTML5を始めた」と言われたときは嬉しかったです。
Mr.doobはその後Three.jsを作り、Webの進化に多大なる貢献をしたわけです。そのきっかけを作ったのは私。だから、Webの進化に多大なる貢献をしたのは私である、と言ってもいいんじゃないでしょうか(笑)</p>

<p>※Mr.doob…<a href="http://threejs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Three.js</a>の作者として有名なクリエイター。先進的なデモギャラリーとして長い歴史を誇る<a href="http://www.chromeexperiments.com/search/results.html?q=doob" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome Experimentsにも、多数の作品を投稿</a>している。</p>

<h2>「技術の無駄遣い、大好きです」</h2>

<p><strong>──あんどうさんは、その高い技術力を使って面白いものを作っている人だ、という印象があります。<a href="http://d.hatena.ne.jp/technohippy/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ブログ</a>上で、いろいろとトライしていらっしゃいますよね。例えば、「<a href="http://blog.technohippy.net/Oppai.swf" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">おっぱいエンジニア</a>」としても有名ですね。</strong></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2013/09/shiraishi_3.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/shiraishi_3-200x300.jpg" alt="白石編集長" width="200" height="300" class="alignleft size-medium wp-image-2113" srcset="/wp-content/uploads/2013/09/shiraishi_3-200x300.jpg 200w, /wp-content/uploads/2013/09/shiraishi_3-138x207.jpg 138w, /wp-content/uploads/2013/09/shiraishi_3.jpg 426w" sizes="(max-width: 200px) 100vw, 200px" /></a></p>

<p>そうですね。自分で言うのもなんですが、あの（おっぱいの）動きは素晴らしいと思います。だいぶこだわりましたからね！
ですが実は、あの動きを作るのにはそれほど時間はかかっていません。動くのを確認するまでは大体1日か2日くらいですね。</p>

<p><strong>──以前、<a href="http://d.hatena.ne.jp/technohippy/20120316#1331912160" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebGLとWebRTC、あと顔認識のライブラリ（Face.js）を組み合わせたデモ</a>を作っていたのを覚えています。ああいった、先端技術を使ったおもしろ系のデモとかを作るのがあんどうさんの真骨頂というか。</strong></p>

<p>そうですね。新しい技術が出たら、それを使ってとにかく面白いものを作りたい。技術の無駄遣い、大好きなんですよ。ジャストワンアイデアで終わるようなものを作りたい。</p>

<p><strong>──なるほど、根っからのエンターテイナー気質というか……おみそれしました。では、最後の質問です。現在注目している技術や、今後期待している技術とかを教えて頂けますか？今後HTML5 Experts.jpに書いていただけるという期待も込めて、お聞きします！</strong></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2013/09/2shot.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2013/09/2shot-300x200.jpg" alt="あんどうさん、白石編集長" width="300" height="200" class="alignright size-medium wp-image-2109" srcset="/wp-content/uploads/2013/09/2shot-300x200.jpg 300w, /wp-content/uploads/2013/09/2shot-207x138.jpg 207w, /wp-content/uploads/2013/09/2shot.jpg 426w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>個人的には、3Dをもっとちゃんとやりたい。あと、物理エンジンの世界をもっと突っ込んで極めていきたい。Box2D.jsは、剛体の物理シミュレーションだったのですが、粉体や流体の物理シミュレーションエンジンなども作ってみたいですね。</p>

<p>3Dや物理エンジン、人工生命などといった、「世界の枠組み」を作るようなのが好きなんです。そういう世界の上では、細かい作りこみをしなくとも、少し手をかけるだけで面白いものが作れる。そうして、人をびっくりさせるようなものをどんどん作っていきたいと思っています。</p>

<p><style><!--
.exp-comment {   border-top: 1px solid lightgray; } .exp-thumbnail { } .exp-info {   font-size: 1.1em !important;   margin-bottom: 0 !important; } .exp-comment-pubdate {   font-size: .8em !important;   margin-bottom: 4px !important; } .exp-comment-main {   border: 1px solid lightgray;   border-radius: 8px;   padding: 1em;   min-height: 70px;   margin-bottom: 16px; } .exp-thumbnail {   width: 70px;   float: left; } .exp-comment-body {   margin-left: 80px; } .editor-comment {   clear: left; } .exp-question {   font-weight: bold;   margin-bottom: 8px; }
--></style><article class="exp-comment"></p>

<div class="exp-comment-main">
<div class="exp-thumbnail"><a href="https://html5experts.jp/wp-content/uploads/2013/09/ando4.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img class="alignleft size-thumbnail wp-image-784" alt="Screenshot_4" src="/wp-content/uploads/2013/09/ando4.jpg" width="66" height="66" /></a></div>
<blockquote class="exp-comment-body">[エキスパート No.5 <a href="https://html5experts.jp/author/technohippy/" data-wpel-link="internal">あんどう やすし</a>]

航空工学科を修了後に数年SI企業で働いた後、やはりコンピューターをちゃんと勉強したいと思いUniversity of BathでMSc Computer Scienceを取得。帰国後はB2C企業を転々としつつ5年ほど前から縁あってGoogle Developers Expertとして活動させてもらっています。
<a href="http://d.hatena.ne.jp/technohippy/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">http://d.hatena.ne.jp/technohippy/</a></blockquote>
</div>

<p></article></p>
]]></content:encoded>
		
		<series:name><![CDATA[エキスパートインタビュー]]></series:name>
	</item>
	</channel>
</rss>
