初めてAngularを触ったとき、「これゲーム作るのに向いているのでは?」と思い勉強と実験を兼ねて作ってみました。
その中で得た色々な気付きを書きたいと思います。
まずは成果物について
The Dragon Throne CROSS
http://srpg.laineus.com
二人対戦専用のシミュレーションRPG(ブラウザゲーム)です。
canvasなどは使わず、全てDOMでできています。
実際に遊んでいる様子の動画はこちらです。
ブラウザ動くでちょっとした対戦シミュレーションRPG作りました。https://t.co/2UuWmHRYa3 pic.twitter.com/qI6uZq5Hft
— らいね (@Laineus) 2017年9月4日
(おともだちが居ない人は違う種類のブラウザを2つ立ち上げて遊ぼう!)
ゲームとして成り立たせるのは無理でした…
以前「絵しりとり」というブラウザゲームを作ったんですが、こちらは今も色んな人が遊んでくれています。
こんな感じでオンライン交流コンテンツとして定着することを目指していたんですが、、無理でした…。
主な原因は以下二点、
1.対戦相手がほぼ見つからない
2.シミュレーションRPGとしてつまらない
1ですが、絵しりとりは「BBS」のように時間帯をまたいでも成立する仕組みですが、
このゲームは「チャット」のように同時に操作していないとゲームになりません。
なので、あらかじめ知人と約束して始めるか、偶然誰かが訪れるのを待つしかありません…。
2ですが、ある程度完成した段階で身内と対戦してみて気づきました。
全然面白くない…。これはじゃんけん程度の戦略性しか無い…。
2は戦略性が出るようにもっと作りこんだりすれば、ある程度は改善できそうではありますが、
大変すぎて心が折れてしまったので、「習作」という大盾を構えて公開することにしました。
そんな経緯で、他にも実装しようと思っていた制限時間機能、ランキング機能など様々な機能がお蔵入りしました。
仕組み
構成はタイトルの通り、Go+Angularで、DBはMySQLです。
ごく普通のSPAで、サーバーはapiのみ、htmlはフロントで吐き出しています。
ユーザー間のデータ同期は、シンプルにapiを数秒ごとに叩きに行っています。
Go言語
「サーバーサイドで使えるPHP以外の言語を使えるようになりたい」
と思い、なんとなくイマドキな雰囲気漂うGo言語を選びました。
WAFはGin、ORMはgormを使っています。
PHPよりも厳格な分、書いていて安心感が強いです。
バグも減るんじゃないでしょうか。
速さについてですが、もちろんGo言語自体は速いと思います。
ただ、最終的に完成したapiの処理速度はどうなのかというと、特に速くはなさそうです。
詳しいことは分からないですが、多分ORMを導入したことの負担がかなり大きい気がしています。
あまりに遅いところは、生のSQL文に置き換えて対応しました。
Angular
裏がGoなら表もGoogleで統一しようということでAngularにしました。
完成した今時点では、他のライブラリにも手を出しているんですが、その中だとRiotが一番気に入っております。
Angularをはじめ、流行りのVDOMやSPAはゲームを作るのに向いている!
実は、半年ほど前にもjQueryで作ったゲームを公開したんですが、
→『PHP+HTML+JSでレスポンシブ対応のロールプレイングゲーム作ってみた』
正直すごく大変でした。
ゲームはボタンを押すたびにどんどん状態が変化していきますが、
そのためにDOMのステートとボタンイベントを相互に管理していくのは中々骨が折れます。
しかし、AngularなどのViewを持つフレームワークやライブラリを使うことで、
Viewテンプレートに変数がどう展開されるかだけ定義しておき、
あとはひたすらjs側で変数の中身を動かしていくだけでよくなります。
これは非常に感動しました。
フロント界隈で色々なライブラリが流行るのも納得です。
ページ遷移のストレスがない「SPA」もゲームに向いている要素と言えます。
ただ、結局のところDOM要素でゲームを作るのは曲芸みたいなものだと思っています。
その上で、どうしてもDOMでブラウザゲーを作らなきゃいけない人がいたら、Viewライブラリの導入はおすすめです。
Angularと他のライブラリを比べて
Angularは、他のライブラリより厳格さが強い印象を受けました。
大規模なサイトを大人数で作るときに、破綻しづらいんじゃないかと思います。
一方、VueやRiotのようなシンプルなライブラリは、フリーダムに書ける分、無茶苦茶なコードも出来やすい気がします。
ただ、僕個人で使うにはAngularレベルのがっつり系フレームワークをフロントに導入するのは…。
朝食にカツ丼を食べるようで胃がもたれる気分です。
まだ良くわからないこと
コンポーネント!
どの粒度で分割すればいいんだろう…。
今回のゲームでいうと、「タイトル画面」「ゲーム一覧」「ゲーム内」の3画面をそれぞれ一つのコンポーネントとして実装しました。
その他、「ゲーム一覧」と「ゲーム内」で重複するヘッダー部分をコンポーネント化したりしてみたんですが、
面倒なデータのやりとりを行ってまで分割するメリットが分からずに辞めてしまいました。
デプロイ
僕は、gitのリリース用ブランチにプッシュしたら勝手に本番反映してほしい人なんですが、
今回はangularもgoも要コンパイルということでひと手間ありました。
goはsupervisorというアプリで常駐させ、apacheからはリバプロで流しています。
プッシュがあったら、Goで作ったapiを再コンパイルし、supervisorでapiを再起動させます。
angularも同じくプッシュ時にサーバー側で再ビルドします。