47
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

リモートカードゲームを気軽に遊べるランダムマッチアプリを開発した話

Last updated at Posted at 2020-05-15

はじめに

私の趣味の一つに、トレーディングカードゲーム(TCG)があります。
昨今の外出自粛要請による影響は、TCG 界隈においても例外に漏れず、対面で TCG を遊ぶ機会のほとんどがなくなってしまいました。
この記事では、少しでも TCG 界隈の停滞感をなくすために開発した Web アプリの紹介と開発手順のメモ書きを~~まとめています。~~鋭意作成中です。
スクリーンショット 2020-05-15 12.57.24.png

対象読者

  • IT 分野以外の趣味で IT を活用したい人
  • Twitter アカウントによる認証を用いた Web アプリをつくりたい人
  • WebRTC(ビデオ通話など)を活用した Web アプリをつくりたい人
  • Nuxt.js/TypeScript の開発に興味がある人

モチベーション

TCG は大前提として対面で遊ぶことを想定したアナログゲームですが、学生以下をメインターゲット層としたものも多く、歳を重ねるにつれて身の周りから TCG を一緒に遊ぶ友達がだんだんと減っていくものです(悲しい)。
他方、TCG を専門に取り扱うカードショップなどでは、店舗大会や公認自主イベントと呼ばれるような、誰でも気軽に参加できるイベントが定期的に開催され、友達や知り合いがいなくても TCG を楽しめる環境が整っていました。

しかしながら、昨今の外出自粛要請により、カードショップでのイベントは全面的に中止に。
このような状況を受けてか、TCG 界隈では、知り合い同士で Skype や Discord などのビデオ通話アプリを用いたリモートカードゲームの環境を積極的に取り入れつつあります。
私自身、今回の騒動以前から何度かリモートカードゲームを遊んだことがありますが、以下のような課題があると感じています。
スクリーンショット 2020-05-15 12.55.53.png

  • 知り合いの中に、都合のつく人がなかなか見つからない
  • とはいえ、事前に日程調整しておく(待ち合わせ時間を決めておく)のは面倒
  • かといって、知り合い以外の募集に自分から声をかける勇気もない
  • 相手が見つかったとて、Skype やら Discord やらを使い分け、都度連絡先を登録するのも面倒

ただの面倒くさがりやんけ。
まあ、とにかくそのような課題の解決を目指す気持ち半分、「転活のポートフォリオがわりに使えねえかなぁ」の気持ち半分で開発した Web アプリがこの**『PTCGrand』**です。

基本アイディアとして、対戦型オンラインゲームでは一般的なランダムマッチング機能を実装しました。
そのため、たとえ知り合いがいなくても、リアルタイムに対戦相手を募集している人同士でリモートカードゲームを遊ぶことができます。

  • 知り合いの中に、都合のつく人がなかなか見つからない
  • とはいえ、事前に日程調整しておく(待ち合わせ時間を決めておく)のは面倒
  • かといって、知り合い以外の募集に自分から声をかける勇気もない

さらに、ビデオ通話機能を Web 上で完結させることで、Skype や Discord の連絡先交換は言わずもがな、アプリのインストールすら不要にしました。
また、この Web アプリを利用するのに複雑な手順があるとかえって面倒になってしまうため、Twitter アカウントとの連携による認証を導入し、設定手順も最小化しています。

  • 相手が見つかったとて、Skype やら Discord やらを使い分け、都度連絡先を登録するのも面倒

特定 TCG プレイヤー向けの紹介記事 は(別名義で)note に投稿済みなので、興味ある方はそちらも併せてご覧ください。

フレームワーク と アーキテクチャ

開発した Web アプリの大まかな構成と動作は、以下の通りです。
スクリーンショット 2020-05-15 12.56.00.png

Nuxt.js/Typescript

  • SPA (Single Page Application) の生成
  • Bootstrap4 (BootstrapVue) によるデザインレイアウト

Firebase

SkyWay

  • ユーザー間のビデオ通話・データ通信の確立

開発手順

重要そうなところやハマったところを中心に、メモ書きを残しています。
用意が面倒なのでスクリーンショットなどを掲載していないため、詳しく知りたい方は、適宜、記事末尾にある参考記事をご覧いただければと思います。

バージョン

$ node -v
v12.16.2
$ npm -v
6.14.4

Nuxt.js プロジェクトの作成

Nuxt.js 公式サイトに書かれているとおり、create-nuxt-app コマンドでプロジェクトを作成します。
開発言語に TypeScript、UI フレームワークに BootstrapVue を選択していますが、このあたりは好みかと思います。

Nuxt.js プロジェクトにおける TypeScript 記法は、公式の Nuxt TypeScript ガイドが参考になります。

$ npx create-nuxt-app <project-name>

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in <project-name>
? Project name <project-name>
? Project description <project-description>
? Author name @blachocolat
? Choose programming language TypeScript
? Choose the package manager Npm
? Choose UI framework Bootstrap Vue
? Choose custom server framework None (Recommended)
? Choose the runtime for TypeScript Default
? Choose Nuxt.js modules Progressive Web App (PWA) Support
? Choose linting tools ESLint, Prettier
? Choose test framework Jest
? Choose rendering mode Single Page App
? Choose development tools jsconfig.json (Recommended for VS Code)

Bootstrap テーマ と Web フォントの導入

Nuxt.js プロジェクトの UI フレームワークに Bootstrap を採用する強みの一つは、過去のプロジェクトのテーマを使い回せることかもしれません1
今回は、以前「所有しているボードゲームの管理サイト」を開発した際に使用した Bootswatch の Lumen テーマを導入することにしました。

/assets 以下に scss/bootswatch.scss を作成し、Global に読み込む設定を nuxt.config.js に追加します。
アプリのテーマ色を設定するため、元の設定値が書かれた _variables.scss@import するよりも前に変数 $primary を定義することで、実質的に変数を書き換えています2
CSS セレクタによる Style の適用は、より後に書かれたものが優先されるため、@import の後に記述します。

また、同様に SCSS の変数を書き換える形で、Google Fonts で公開されている Web フォントを適用しています。

/assets/scss/bootswatch.scss
$primary: #d44050;
$font-family-sans-serif: 'M PLUS 1p', sans-serif;
$font-family-monospace: 'M PLUS 1p', monospace;

@import '~/node_modules/bootswatch/dist/lumen/_variables';
// $primary: $blue !default;
@import '~/node_modules/bootstrap/scss/bootstrap';
@import '~/node_modules/bootswatch/dist/lumen/_bootswatch';

.b-avatar {
  &.badge-secondary {
    color: $gray-500;
  }
}

...
nuxt.config.js
  export default {
    head: {
      ...
      link: [
        ...
+       { rel: 'stylesheet', type: 'text/css', href: 'https://fonts.googleapis.com/css?family=M+PLUS+1p' }
      ]
    },
    ...
    css: [
      ...
+     '~/assets/scss/bootswatch.scss'
    ],
    ...
  }

Firebase Hosting へのデプロイ

Firebase CLI (firebase-tools) をインストールしていなければ、npm 経由でインストールします。
インストール完了後、firebase login コマンドを実行し、Web ブラウザ経由で Google アカウントを紐づけます。

$ npm install -g firebase-tools
$ firebase login

作成した Nuxt.js プロジェクトに移動し、Firebase プロジェクトとしての初期設定を行います。
Firebase 公式ドキュメントを参考に、あらかじめ Web ブラウザから Firebase プロジェクトを作成しておくとよいでしょう。

ここでは、? Which Firebase CLI features... の設問に対して Firebase Hosting のみを選択しています。

$ cd /path-to/<project-name>
$ firebase init

...

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Ente
r to confirm your choices. Hosting: Configure and deploy Firebase Hosting sites

...

=== Project Setup

? Please select an option: Use an existing project
? Select a default Firebase project for this directory: <project-name> (<project-name>)
i  Using project <project-name> (<project-name>)

...

=== Hosting Setup

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No

...

Firebase Hosting の公開ディレクトリに /public を指定したため、それに合わせるように nuxt.config.js の出力ディレクトリを変更します。

nuxt.config.js
  export default {
    ...
+   generate: {
+     dir: 'public'
+   },
    ...

以上で、準備が整いました。
下記コマンドで SPA を生成し、Firebase Hosting にデプロイします。

$ npm run generate
$ firebase deploy

なお、一度公開した SPA を非公開にしたい場合、下記コマンドを実行します。

$ firebase hosting:disable

参考記事

おわりに

せっかくそれなりの形になった Web アプリを開発したので、開発手順のメモ書きをまとめ~~ました。~~たかったのですが途中で力尽きてしまいました。

アプリについては、公開から数日経ったものの肝心のユーザー数はまだまだ少なく、なかなかランダムマッチングが成立していない状況です。
その結果、半ば “待ち合わせ時間を決めておく” のが必要になっており、上であげた課題そのものにぶち当たっています(悲しい)。

~~開発モチベーションの半分が半分なのであれですが、~~個人開発だからこそ、機能をゴリゴリ実装するだけでなく、必要な人のもとに届くための施策を考えていきたいですね。

  1. 開発を一段落を終えた時点での感想としては、「見た目に大きなこだわりがなければ BootstrapVue ではなく Material Design フレームワークである Vuetify を採用するのが無難そう」という感じです。

  2. _variables.scss 内の変数宣言の末尾に付された !default は、すでに同名の変数が宣言されていなければ適用する、という意味らしいです。

47
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?