1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

2023年自作ゲーム総括

Last updated at Posted at 2024-01-03

本題について

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
  • Safari
  • Chrome
Windows latest
  • Edge
  • Chrome
Device OS Version Browser
iPhone 14Pro Max 17.1
  • Safari
  • Chrome
iPhone 14 Plus 17.1
  • Safari
  • Chrome
iPad Pro(2022) 17.1
  • Safari
  • Chrome
iPad Air 4 17.1
  • Safari
  • Chrome
iPad mini 6 17.1
  • Safari
  • Chrome

2. 2023年自作シューティングゲームの改修

2-1. 画面リサイズ処理の見直し

iPhoneでのリサイズのイメージ

ブラウザのウィンドウサイズを変更する幾つかのケースで、
ゲーム画面の表示サイズを調整してます。

  1. ブラウザの画面サイズ変更した時
    • PCでブラウザの画面サイズを変更
    • iOS Safariにてツールバーの表示・非表示切替
  2. スマホにて画面回転した時

gamerotation.gif

また2.において、ポートレートからランドスケープモードへの回転時、以下を考慮して改修しました。

  1. タイミングを遅らせて画面サイズを取得してゲーム画面サイズを調整する
  2. 1.でタイミングを遅らせた際、ゲーム画面が一瞬レイアウト崩れになるので、フェードインすることで自然にゲーム画面を表示させる(...つもり)

リサイズの改修はiOS、iPadOSを考慮する必要があった

iOS、iPadOS(ともに17.2系) Safariで画面回転した直後にウィンドウサイズがうまく拾えず、
以下のように、端末開店後に少しタイミング遅らせてリサイズする必要がありました。

resize.ts
// 画面リサイズ処理
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
ケーブル
  • 8BitDo Arcade Stick
    Windows PCのみ
    キーマッピングアプリを使う

以下のツイートは、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設定をしました。

index.html
<html>
<head>
  ...
  <!-- # INSERT CSP HERE -->
  ...
</head>
<body>
  ...
</body>
</html>
vite.config.ts
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で開発しました。

機能一覧

機能 操作イメージ
ステージの作成 Monosnap screencast 2023-12-30 17-02-02.gif
ステージの編集 Monosnap screencast 2023-12-30 17-05-20.gif
ステージの削除 Photos Library.gif
ステージの並替え test.gif

編集したステージは、以下外部リポジトリに保存するよう実装してます。
※保存自体は、対象リポジトリをあらかじめ一つ選択する形になります。

  • 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使用率も一気に上がって、サーバーダウン...。

image.png

AWS Lambdaへデプロイする

...できず...。

AWS Amplifyへデプロイする

NitroのAmplifyゼロコンフィグ対応を受けて、Amplifyへのデプロイにリトライ。

AWS Amplify ビルド設定

開発環境ではpnpmパッケージマネージャーを使ってるので、
デフォルトのコードから該当箇所を変更して、無事にデプロイできました。

amplify.yml
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年以上も続いてます。

フロントエンドの変遷が大きい状況の中で、
何か新しい技術等あれば、これらのツールを通じて経験して業務に活かせればと思ってます。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?