本題について
2023年も自作シューティングゲームと、ステージ編集ツールをそれぞれ改修しました。
目的
- 好きなシューティングゲームを自分で楽しむ
- 変遷が大きいフロントエンドの技術等を学習する
改修履歴
改修期間と改修内容は、大体こんな感じです。
改修期間 | 改修内容 | |
---|---|---|
Shooting Game | 2017/4〜2018/1 | JavaScriptで実装 |
↑ | 2021/10ごろ〜2022/1 | フレームワーク学習のためにReactを採用し、TypeScriptに換装。 テストツールはVitestを採用し、テストコードを作成 |
Edit Stage Tool | 2018/1ごろ〜2018/7 | JavaScriptで実装 |
↑ | 2020/1ごろ〜2020/8 | フレームワーク学習のためにVue(2.x)を採用。JavaScriptで実装 |
↑ | 2022/12ごろ〜2023/9 | フレームワーク学習のためにNuxt3を採用。TypeScriptに換装 テストツールはVitestを採用し、テストコードを作成 |
過去の実装は以下に投稿してます。
1. 自作シューティングゲームとは
TypeScriptで実装したグラディウス風の横スクロールシューティングのブラウザゲームです
一部制約はありますが、基本的にPC・スマホでゲームを楽しめます。
※この動画ではiPad mini6, ゲームコントローラー(Xbox Elite ワイヤレス コントローラー シリーズ 2)使ってプレーしてます。
対応端末
2023/12/1時点での対応状況です
Device | OS Version | Browser |
---|---|---|
MacBook Air(M2) | latest |
|
Windows | latest |
|
Device | OS Version | Browser |
---|---|---|
iPhone 14Pro Max | 17.1 |
|
iPhone 14 Plus | 17.1 |
|
iPad Pro(2022) | 17.1 |
|
iPad Air 4 | 17.1 |
|
iPad mini 6 | 17.1 |
|
2. 2023年自作シューティングゲームの改修
2-1. 画面リサイズ処理の見直し
iPhoneでのリサイズのイメージ
ブラウザのウィンドウサイズを変更する幾つかのケースで、
ゲーム画面の表示サイズを調整してます。
- ブラウザの画面サイズ変更した時
- PCでブラウザの画面サイズを変更
- iOS Safariにてツールバーの表示・非表示切替
- スマホにて画面回転した時
また2.において、ポートレートからランドスケープモードへの回転時、以下を考慮して改修しました。
- タイミングを遅らせて画面サイズを取得してゲーム画面サイズを調整する
- 1.でタイミングを遅らせた際、ゲーム画面が一瞬レイアウト崩れになるので、フェードインすることで自然にゲーム画面を表示させる(...つもり)
リサイズの改修はiOS、iPadOSを考慮する必要があった
iOS、iPadOS(ともに17.2系) Safariで画面回転した直後にウィンドウサイズがうまく拾えず、
以下のように、端末開店後に少しタイミング遅らせてリサイズする必要がありました。
// 画面リサイズ処理
const timerId = 0
const resize = () => {
window.clearTimeout(timerId)
window.setTimeout(() => {
リサイズ処理
}, 500) // <- 任意の値
}
// イベントリスナーの登録
window.addEventListener('resize', resize);
// イベントリスナーの解除
window.removeEventListener('resize', resize);
ただ、これでは端末によって挙動が異なる可能性もあると思い、
新たにdeviceorientation
イベントタイプによるイベントリスナーの登録・解除を追加してみました。
// 画面リサイズ処理
- const timerId = 0
const resize = () => {
- window.clearTimeout(timerId)
- window.setTimeout(() => {
リサイズ処理
- }, 500) // <- 任意の値
}
// イベントリスナーの登録
window.addEventListener('resize', resize); // 上記 1. の対応
+ window.addEventListener('deviceorientation', resize); // 上記 2. の対応
// イベントリスナーの解除
window.removeEventListener('resize', resize);
+ window.removeEventListener('deviceorientation', resize);
こんな感じで実装してみたのですが、結果は変わらずでした。
もう少し楽な方法があればなぁ...と。
2-2. ゲームコントローラーを使ってプレーする
ブラウザのGamepadAPIを使って、PC・iPhone・iPadでゲームパッドやコントローラーを使ってプレーできます
接続方法
接続方式に従い以下のコントローラーでプレーできます。
接続方式 | ゲームコントローラー |
---|---|
Bluetooth | |
ケーブル |
|
以下のツイートは、MacBookのChromeブラウザで8BitDo Arcade StickをBluetooth接続してプレーしてます。
iPhone16 Plus、iOS17.1.x以降、Nintendo SwitchのJoyConが利用できるようになった
iPhone12 Pro Max、iOS 16.xで、Nintendo SwitchのJoyConを使用したら以下の問題がありました。
- 長時間プレーすると端末が熱くなり、ブラウザが落ちてしまう
- ボタンの反応が遅い
それがiPhone16 Plus、iOS17.1.x以降解決された感じですが、もう少し様子見しようと思います
2-3 CSPの設定
学習がてら、CSPに関して以下を参照し、必要なアクセスのみ許可する設定を行いました。
上記構成図により、Viteを使って本番環境用のみmetaタグを使ってCSP設定をしました。
<html>
<head>
...
<!-- # INSERT CSP HERE -->
...
</head>
<body>
...
</body>
</html>
import crypto from 'crypto';
...
// プラグイン
const insertContentSecurityPolicy = (env): Plugin => {
return {
name: 'insert-content-security-policy',
apply: 'build',
transformIndexHtml: async (html) => {
// インラインスクリプトタグ内の文字列を取り出す
const scriptTag = html.replace(/.*<script>(.*)<\/script>.*/g, '$1');
// インラインスクリプト文字列をsha256形式に変換する
const hashString = crypto
.createHash('sha256')
.update(scriptTag, 'utf8')
.digest('base64');
return html.replace(
'<!-- # INSERT CSP HERE -->',
`<meta http-equiv="Content-Security-Policy" content="default-src 'self' *.googletagmanager.com 'sha256-${hashString}'; connect-src 'self' *.google-analytics.com ${(Shooting Editのドメイン名)}" />`,
);
},
};
};
...
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const isBuild = () => command === 'build';
return {
...
plugins: [
...
isBuild() && insertContentSecurityPolicy(env),
]
...
}
}
3. ステージ編集ツール
3-1. 機能と開発
ツール概要
ステージを編集するツールで、主に以下の機能を持ちます。Nuxt3で開発しました。
機能一覧
機能 | 操作イメージ |
---|---|
ステージの作成 | |
ステージの編集 | |
ステージの削除 | |
ステージの並替え |
編集したステージは、以下外部リポジトリに保存するよう実装してます。
※保存自体は、対象リポジトリをあらかじめ一つ選択する形になります。
- Firebase
- microCMS
- MovableType
3-2. 開発環境とデプロイ
開発環境(2024/12/24時点)
- パッケージ
- Nuxt3(v3.8.2) ※TypeScriptで実装
- Vitest
- eslint
- prettier
- stylelint
- パッケージ管理マネージャー
- pnpm
デプロイ
Amazon Lightsailでの運用がうまくいかなかった
Amplifyデプロイ前までは、Amazon Lightsail(nginx)へデプロイしたのですが、
サーバー起動しても以下のように、CPU使用率も一気に上がって、サーバーダウン...。
AWS Lambdaへデプロイする
...できず...。
AWS Amplifyへデプロイする
NitroのAmplifyゼロコンフィグ対応を受けて、Amplifyへのデプロイにリトライ。
AWS Amplify ビルド設定
開発環境ではpnpmパッケージマネージャーを使ってるので、
デフォルトのコードから該当箇所を変更して、無事にデプロイできました。
version: 1
frontend:
phases:
preBuild:
commands:
- nvm use 18
- corepack enable
- npx --yes nypm i
build:
commands:
- npx pnpm build // <- ここでpnpmに変更
artifacts:
baseDirectory: .amplify-hosting
files:
- '**/*'
3-3 自作シューティングゲームとの連携
ステージ編集ツールと、自作シューティングゲームと連携することができます。
ステージのデータは、Firebase・microCMS・MovableTypeに保持させ、
いずれかのAPIを使って操作(保存・取得)するイメージです。
以下構成図では、各要素との関連を示してますが、
編集したステージをプレーすることができます。
# | 説明 | |
---|---|---|
(1) | edit stage(s) | ステージを編集する |
(2) | update stage(s) | ステージを更新する |
(3) | playing game | ゲームする |
(4) | request to fetch stages | 全ステージ取得をリクエストする |
(5) | fetch stages | ステージを取得する |
(6) | fetch stages | ステージを取得する |
4. まとめ
今年も自作シーティングゲーム、ステージ編集ツールを紹介しました。
2017年からシーティングゲームを作成してたので、気づいたらもう7年以上も続いてます。
フロントエンドの変遷が大きい状況の中で、
何か新しい技術等あれば、これらのツールを通じて経験して業務に活かせればと思ってます。