目次
- 背景
- TL;DR
- 使用した技術
- 手順アウトライン
- 手順詳細
- 実用性
1. 背景
- 友人たちとTRPGをするようになった。
- セッションはSkype越しにやっており、皆が個別のダイスツールを使っているので、虚偽の報告が可能(しないとは思ってるけど、まぁ、可能)。
- 「ダイスロールの結果を共有できるツールがあったら良いんじゃね?」
- 調べたらいっぱいあるんだけど、なんか妙に多機能で何をすれば良いのかわからなかったり、アカウント作ったりと面倒。
- 「部屋にいる人とだけダイスロールの結果を共有することだけを目的とした、ログインとかいらない、見やすいツールを作ろう」
- ちょうどAngularも勉強してたし、いい機会だと思った。
- Web Socketという技術にも興味があったし、ちょうどよかった
2. TL;DR
- github
- ~~一般公開してるから誰でも使えるよ(now.shに無料デプロイしてるから最初起動するとき遅いかも)~~残念ながらもう起動していません...
3. 使用した技術
- node.js (v8.10.0)
- express(v4.16.4) - node.jsの有名なフレームワークのパッケージ
- socket.io (v2.1.1) - サーバーサイドでweb socketのライブラリを使用するためのパッケージ
- socket.io-client (v2.1.1) - クライアントサイドでweb socketのライブラリをしようするためのパッケージ
- @types/socket.io-client (v.1.4.32) - Angularのフレームワーク内でsocket.io-clientを利用するために必要なパッケージ(データ型の情報などがあるんだと思ってる)
- @angular-cli (v1.6.8) - Angularのプロジェクトを始めたり、ビルドしたり、運用したりするためのツール
4. 手順アウトライン
- 調査
- Web Socketについて
- 開発
- プロジェクトの土台を作成
- 画面の作成
- ロジックの作成
5. 手順詳細
1. 調査
1-1. Web Socketについて
- ちょっとWeb Socketについて調査
- この記事が超簡単に説明してくれてるので、概要を知りたい場合は読むべし。
- 基本的にわかったことは…
- イベント名で処理を分ける。
- emitでイベント名と共にデータを送る。
- サーバー側もクライアント側も考え方は同じ。
server.js
// パッケージのインポートなど
const express = require('express');
const app = express();
const http = require('http');
const server = http.Server(app);
const io = require('socket.io')(server);
// クライアントがつながったら
io.on('connection', (socket) => {
// クライアントからのsocket.ioの<eventName>イベントのリクエストを受け取り、渡された[arguments...]を受け取って処理をする
socket.on('<eventName>', ([arguments...]) => {
/* 何らかの処理 */
// つながっているクライアント全員に<eventName>イベントで<dataToSend>を送る
io.emit('<eventName>', <dataToSend>);
// <roomName>にjoinしているクライアント全員に<eventName>イベントで<dataToSend>を送る
io.to('<roomName>').emit('<eventName>', <dataToSend>);
});
});
2. 開発
2-1. プロジェクトの土台を作成
-
@angular-cli
のおかげで簡単に土台を作ることが可能。 - 基本的に以下を覚えていれば問題ないと思う
ターミナル
$ ng new <プロジェクト名> # 新たなAngularプロジェクトのフォルダを作成してくれる
$ ng g component <コンポーネント名> # コンポーネントのファイルを作ってくれる
$ ng g service <サービス名> # サービスのファイルを作ってくれる
2-2. 画面の作成
- 画面作成時に意識したのは、レスポンシブデザインとクロスブラウザ対応。
- Bootstrapとか使わずに自分で考えたstyleを使ってみたかった。
- あと、自分はよく暗い部屋でやるので、眩しすぎないように全体的に暗い色合いを使う。
- あとはみやすさ…かな
そんなこんなを考えながらイメージを紙に適当に書いていく…
こんな感じでイメージを少しずつに固めていく(もはやただの落書き)
![4077.jpg](https://qiita-image-store.s3.amazonaws.com/0/317253/8b4c55c2-d8b0-01a0-86b6-36aba526f536.jpeg)- 補足: Internet Explorerに対応させるためにpolyfillを有効化しないといけない。
-
src/polyfill.ts
ファイルがあるので、コメントを外す。
-
src/polyfill.ts
/* (省略) */
// 以下の箇所にコメントがかかってるはずだから全部外す
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';
/* (省略) */
2-3. ロジックの作成
- 「ロジックの作成」ではかなりざっくりなので、分解すると…
- ルーティングのロジック
- 新しい部屋を作るときのロジック
- 部屋に参加するロジック
- 部屋の有無を確認するロジック
- 部屋に誰か入ったときに、それを部屋の人全員に伝えるロジック
- 部屋に誰か入ったときに、部屋に今現在誰が入っているかを伝えるロジック
- 部屋に誰かが入ったときにIDを割り振るロジック
- 部屋に誰かが入ったときにランダムな表示名を割り振るロジック
- ユーザーが任意に表示名を変更するロジック
- ダイスを振るロジック
- ダイスの出目をみんなに伝えるロジック
- ダイスの出目をログするロジック
- ログを消去するロジック
- 誰かが退室したときのロジック
上記をすべて考える必要があった。
6. 実用性
個人的な意見だが、実用性は結構あると思う。理由を以下に挙げる…
- 部屋を作って、番号を教えるだけだから誰でも手っ取り早く使えるし、アカウント登録とか必要ない。
- UI/UXを気にして、できるだけシンプルにしたので、見やすく、直感的に使いやすい。
- 機能が少ないので画面がごちゃごちゃしてない。またしても見やすい。
- レスポンシブデザインなのでスマホ・タブレットに対応している。
- 表示名を変えれるようになってるから誰が誰だかちゃんと分かる。
自画自賛もここまでくればキモいけど、まぁまぁの出来だと思っている。
ベースがこれなら機能も追加しやすいだろうし。
ただ、もうちょっとデザインやレイアウトをうまくできたら嬉しかった…
まぁ、これもいい経験ということで…