undefined

bokuweb.me

AngularJS+enchant.js+CoffeeScriptで音ゲーを作ってGitHubPages上で公開しました

これなに?

無料音ゲー flavabeats

github.com

ブラウザ上で遊べる音ゲーです。 ノートと呼ばれるオブジェクトが曲に合わせて落ちてくるのでターゲットに重なるタイミングでキーボードのZ,X,C,V,Bを押していくゲームです。 楽曲はCreativeCommonsのものを使用しています。

なんで作ったの?

Vue.jsやReactやAngularJSやAurelia.JSなどフレームワークが乱立するなか何か一つ使えるようにならないといけない気がしたので勉強用に始めました。(あとcocos2d-JSのAndroidデバッグが嫌になりましたので気分転換に)。最初はAngularJSより学習コストの低そうなVue.jsを触ろうかと思ったのでですが、Vue.jsにはルーティング機能がついていないということで結局AngularJSを触ってみることにしました。(書籍も買っちゃってたし。)

本来ゲームであればenchant.jsでシーンの切替え等を行い、AngularJSなどを使わないってのが普通な気がしますが、今回のような曲選択ページなんかはゲーム側でjavascriptで記述するよりhtmlとして表示してやったほうが簡単だとおもったので・・。実際cocos2d-JSで同じようなメニューページをjavascriptで書くのは少し面倒に感じました。

後はおもけに以下のことを試したみました。

  • webstorage使ってみる(ハイスコアの記録に使っています)
  • GitHubPages上で公開してみる(無料だし独自ドメイン使えるし)

リポジトリ

github.com

はまったこととか、こんな風にやってみましたってこととか

AngularJSは情報が多いとはいえ、やはり手さぐりでいろいろ調べながら試しました。『こうすべきだ!』ってのがあったらご教示いただけると幸いです。

GitHub Pagesで独自ドメインを使用する

以下のページが非常に参考になりました。というかまんまです。

GitHub Pages でWebサイトをホスティングする(独自ドメイン使用) - Think Big Act Local

AngularJSでルーティングする

以下のページが参考になりました。

inter-arteq :: interaction between art and technology » Blog Archive » AngularJSで画面遷移するときに便利なng-view

index.htmlに以下のように記述しておき

<div ng-view id="view"></div>

JS側で以下のように振り分けています。

flavaApp.config ($routeProvider)->
  $routeProvider
  .when '/',
    templateUrl: 'splash.html'
  .when '/select',
    templateUrl: 'select.html'
  .when '/help',
    templateUrl: 'help.html'
  .when '/game/:id',
    controller: 'GameCtrl'
    templateUrl: 'game.html'
  .otherwise
  redirectTo: '/'

また、URLのパラメータを取得するのには以下のページを参考にさせていただきました。

$routeParamsを使用して、URLのパラメータを取得する | 集の一期一会

具体的には

flavaApp = angular.module('flavaApp', ['ngRoute'])

flavaApp.config ($routeProvider)->
  $routeProvider
  .when '/game/:id',
    controller: 'GameCtrl'
    templateUrl: 'game.html'

flavaApp.controller 'GameCtrl', ($scope, $routeParams)->
  console.log $routeParams.id

とするこでhttp://prototype.flavabeats.net/#/game/1にアクセスすることで$routeParams.id1になります。これを使って、ゲームプレイ時はすべてgame.htmlに遷移しつつ、idによってどの楽曲をプレイするか選択しました。

外部ライブラリのコールバックの中等で $scope の値を変更したい場合

以下の記事が参考になりました。

AngularJSでデータバインドが効かないときは $scope.$apply - Yuta Watanabe's Blog

リンク先の記事でも紹介されている、2秒後に$scope.messageを書き換える例ですが以下の記述では動作せず。

function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";
    
    setTimeout(function () {
        $scope.message = "Timeout called!";
        // AngularJS unaware of update to $scope
    }, 2000);
    }

以下のように各必要があるようです。

function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";
    
    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
    }

HTMLとして文字列をバインドする

以下の記事が参考になりました。

3分で分かるAngularJSセキュリティ - teppeis blog

今回はangular-sanitize.jsを使用しました。 以下のようにレベルをhtmlで表示しています。

html

<span class="level" ng-bind-html="m.levelIcon"></span>

JS側

flavaApp = angular.module('flavaApp', ['ngSanitize'])
flavaApp.controller 'GameInfoCtrl', ($scope)->
  level = 'Level '
  for i in [0..9] when i < $scope.music.level
    level += '<i class="fa fa-star-o level"></i>'
  $scope.music.levelIcon = level

topページでスマホ用にメッセージを出す

性懲りもなくスマホには対応していないので、スマホユーザには非対応メッセージを出すようにしました。 userAgentを判定して、ng-hideng-showで要素を表示・非表示にして対応してます。

html

<div class="row" ng-controller="SplashCtrl">
  <div class="col-md-8 col-md-offset-2 text-center inner" ng-hide="isMobile">
    <a ng-href="#/select"><h1><img src="img/logo.png" ></h1>
      <span class="click-message">Click here to start.</span></a>
  </div>
  <div class="col-md-8 col-md-offset-2 text-center inner" ng-show="isMobile">
    <h1><img src="img/logo.png" class="sp-logo"></h1>
    <span class="mobile-message">Sorry, This site is designed specifically for PCs.</span>
  </div>
</div>

JS側

flavaApp.controller 'SplashCtrl', ($scope)->
  agent = navigator.userAgent
  if agent.search(/(iPhone|iPod|Android|Mobile)/) isnt -1 then $scope.isMobile = on else $scope.isMobile = off

webstorageを使う

こんな感じで保存

storage = localStorage
storage.setItem key, value

こんな感じで読み出し

storage.getItem key

できるっぽいです。簡単。

さいごに

インクリメンタルサーチとかソートとかさくっと実装できて楽しかった。もっと勉強してVue.jsやAurelia.JSも触ってみたい。あと、せっかくなんだからBrowserify使ってみればよかった。

※追記

ゲームへの使用例が以下の記事に掲載されていました。

AngularJSを使用したゲーム開発|1 pixel|サイバーエージェント公式クリエイターズブログ