エンジニアリングとお絵描き

お絵描きが趣味のエンジニアが、誰かの為になりそうなことや未来の自分の助けになりそうなことを書き残します.

1日で作れる簡単なWebゲームを作りたい...!

タイトルの通り、1日クオリティのゲームを制作したいと思い至り、作ってみることにしました。

何故1日かというと、取り合えず何か成果物を作ることを最優先にしようと考えたからです。

早速作っていこうと思います。

使用技術

以下、使用技術となります。

  • TypeScript
  • Pixi.js
  • Firebase hosting

hothkurou様(作っちゃうおじさん様)のTypeScript+Pixi.jsで快適なゲーム制作ライフを送ろう!の記事と、サンプルゲームを参考に作成しました。

作成の流れと最初のづまづき

自分はまだまだWeb関連の知識が浅い為、プログラムを書くよりも環境構築等に苦戦すると思い、以下のような流れでゲームを制作することにしました。

  1. サンプルゲームをローカルで実行する
  2. Firebase hosting を 用いてサンプルゲームをhostingして実行する
  3. サンプルゲームを改変していき、オリジナルゲームにする

hothkurou様の記事がとても丁寧であった為、サンプルをローカルで動かすだけならすぐに実行できました。

FIrebase を 用いた hostingは過去に経験があった為、2番目も問題なくできると思ったのですが、Firebaseでhostingする際、サンプルゲームのディレクトリ構造を少しいじる必要があり、相対パスを書き方を正しく理解していなかった自分はここで大きくつまづきました....。

以下、元々のサンプルプログラムのディレクトリ構造です。 (jsonファイル等は省略しました。) 参考:ディレクトリ構成図を書くときに便利な記号

sample_game
    ├dist
    │  └main.js
    ├image
    │  └ball.png
    ├sound
    │  └hit.mp3
    ├typescript
    │  ├create_button.js.map
    │  ├scene_manager.js.map
    │  ├script.js.map
    │  ├create_button.js
    │  ├scene_manager.js
    │  ├script.js
    │  ├create_button.ts
    │  ├scene_manager.ts
    │  └script.ts
    └index.html

Firebase を 用いたhostingを行う際には、公開するディレクトリを選択し、その中にindex.htmlファイルが入っている必要があります。そうなるとindex.htmlで読み込むmain.jsのパスや、script.tsで読み込む画像・音声ファイルのパスも変わります....

結果として以下のような構造に変えたら無事hostingした状態でサンプルを動作させることができました。distディレクトリを公開用に設定しています。(jsonファイル等は省略しました。)

sample_game
    ├dist
    │  ├main.js
    │  ├image
    │  │   └ball.png
    │  ├sound
    │  │   └hit.mp3
    │  └ index.html
    ├image
    │  └ball.png
    ├sound
    │  └hit.mp3
    └typescript
         ├create_button.js.map
         ├scene_manager.js.map
         ├script.js.map
         ├create_button.js
         ├scene_manager.js
         ├script.js
         ├create_button.ts
         ├scene_manager.ts
         └script.ts

上のディレクトリ構造を見ると、distディレクトリの中と外の両方にimage、soundディレクトリがあります...。 絶対正しいやり方では無いと思いますが、こうすることでローカルとhostingしてる際の両方で動作させることができました。

同じファイルを複数の場所に置くなんてあってはならない為、後日調べて解決したいと思います...。 参考:【超初心者向け】Firebaseでハマった落とし穴

1日頑張った成果物

作っちゃうおじさん様のサンプルゲームのコメントがとっても親切だったことと、間違え探しゲームの難易度の低さから、何とか1日でそれっぽい物を作ることができました。

作る時間よりも何を作るか悩む時間の方にやる気と時間を奪われた気がします。

動作のgif画像と、ゲームのリンクです。

f:id:pengin_0_maru:20210321183336g:plain
間違え探しゲーム

また時間を作って改良していきたいと思います。

gitのアカウント切り替え

今後、Webアプリの個人開発に力を入れていくにあたり、gitアカウントの切り替えを行う必要が出てきました。

その為、色々な方の記事を参考にしながら行った作業の記録を残しておきます。

参考1:一つのPC上で複数のgitアカウントをうまいこと使い分ける

上記の記事を参考にしながら作業を行ったところ以下のコマンドを打ってエラーが発生。

$ ssh -T github-sub
no such identity: /home/iuchi/.ssh/sub_rsa: No such file or directory
git@github.com: Permission denied (publickey).

サブアカウント用の公開鍵・秘密鍵を作成していなかったので当たり前ですね...

そもそも公開鍵・秘密鍵の手順を忘れていた為、まず下記の記事を参考にすることとしました。 公開鍵・秘密鍵の概念は理解している(つもり)なので、何とかなるはず...

参考2:GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~

無事鍵を作成して、再度ssh -T github-subを実行したところまたしてもエラーが発生。

$ ssh -T github-sub
git@github.com: Permission denied (publickey).

これは参考2で鍵の作成までしかやらず、公開鍵をGitHubにアップしていなかったからでした。

読み飛ばし、ダメ....

公開鍵をアップし、再度コマンドを実行したところ、無事参考2と同じことができました。

$ ssh -T github-sub
Hi maru0pengin! You've successfully authenticated, but GitHub does not provide shell access.

次に、作成したプログラムをリモートリポジトリに追加しようと思ったのですが、以下のようなエラーが出てしまいました。

fatal: remote origin already exists.

このサイトを参考に、originを削除したら無事リモートリポジトリに追加できました。 fatal: remote origin already exists. と表示された場合の解決法

後は参考2のGitHubでssh接続する手順~公開鍵・秘密鍵の生成から~の手順に従ってshellを作成し、簡単にアカウントの切り替えが行えるようになりました...!!

今後の記事について

今後、Webアプリ開発をメインに行おうと思っているため、開発過程で調べたことや、気が付いたことをここで書いていこうと思います。 HatenaBlogはメモ的な用途として使い、ちゃんとした備忘録のような記事はQiitaを用いようと考えています。

const char *" の引数は型 "char *" のパラメーターと互換性がありません

久々に更新します.

VisualStudioを使用してウェブアプリ制作をしていたところ、躓いたので記録を残します。

「"const char * " の引数は型 "char * " のパラメーターと互換性がありません」

というエラーが出ました。 これは、C++では文字列リテラルの型はconst char[]で、これを実引数に使用するとconst charに変換され、関数の引数がcharだと互換性がないというものらしいです。

参考:https://dixq.net/forum/viewtopic.php?f=3&t=20056#p150167

この問題は関数の引数にconstを付けちゃえば解決すると思うのですが、今回はライブラリに含まれている関数であったためそれは難しく、困ってしまいました。 解決策としては、[C/C++]→[すべてのオプション]→[その他のオプション]に /Zc:strictStrings- と記入しました。

参考

https://dixq.net/forum/viewtopic.php?f=3&t=20056#p150167

https://docs.microsoft.com/ja-jp/cpp/build/reference/zc-strictstrings-disable-string-literal-type-conversion?view=vs-2019

デフォルトではこのようなエラーは起きないみたいなのですが、実際に起きたので記録しました。 因みに、私はVisualStudioでプロジェクトを作成する際に「Windowsデスクトップアプリケーション」を選択しました。もしかしたらこれが原因なのかもしれません。

OpenPoseを使った姿勢推定(2)

前回から引き続き、@miu200521358様の記事を参考にして3d-pose-baseline-vmdの導入をしました。 qiita.com

この導入は比較的大きな躓きもなく進められたのですが、一点問題があり、 H36Mデータという学習データ?(理解できていない)のダウンロード先のDropboxが開けませんでした。

しかしよく調べてみると、@miu200521358様の別記事ではリンクが修正されており、無事DLすることができました。 qiita.com

ここにDL先のリンクを張るのは良くない気がするので、H36MデータがDLできなくて困っている方がいたらmiu様に直接確認するのが良いと思います。 (自分も後1時間ぐらい詰まってたら聞きに行ったと思います)

これ以外は特に問題もなく以下のような画像を出力できました。

f:id:pengin_0_maru:20200605123006p:plain
出力画像の一部

gifファイルも出力されるのでそっちを載せたかったのですが、10MBを超えると載せられないみたいです。残念...。

OpenPoseを使った姿勢推定

@miu200521358様の記事を見ながらMMD自動トレースを行ってみようと思いました。 qiita.com

OpenPoseは元から入っていたので、それ以降の作業から取り掛かりました。 結構躓いたので記録として残したいと思います。(そもそも一日かけても結果出力までたどり付けなかった...)

jsonファイルが出力できない

OpenPoseでは画像や動画から検出した骨格情報をjsonファイルで出力することができるのですが、何故かそれがうまくいきませんでした。 コマンドの書き方が悪いかと思ったのですが、問題はOpenPoseを置いていた場所で、管理者権限が無いとファイルの変更や書き込みができない場所に保存していました。 (どういうところで管理者権限が必要なのかは理解していない...)

この問題は普通にデスクトップやCドライブ直下などにOpenPoseを置けば解決すると思います。

mp4形式の動画が読み込めない

Zoomを使って動画を作成しようと思い、録画機能を使って出力してみたところ動画の形式はmp4でした。 OpenPoseの検出サンプル動画はavi形式で行っていたため、mp4の動画を入力する方法を調べた結果 --video input.mp4 と入力すれば良いと出てきたのですが、 エラーが出て実行できませんでした。

結果、input.mp4は付けずにaviの動画入力と同じようにコマンド入力すればmp4も読み込めました。 (OpenPoseのバージョンは1.6.0)

FCRN-DepthPrediction-vmd の導入

まず、参考にした@miu200521358さんの記事ではAnacondaを導入しているのですが、Anacondaに関して全然調べない状態で記事にないコマンドを幾つか入力してしまい、一度は動いたtensorflowが動かなくなってしまいました。 主な原因としてはcondaとpipの違いを理解せず、競合してしまったことだと思います。 結局PythonもAnacondaアンインストールし、環境を作り直しました。

次に、tensorflowのバージョンアップによるプログラムエラーが起こりました。 バージョン1と2で使えなくなるモジュールが幾つかあるようで、エラーが出ました。 しかし、tensorflowをimportするとき以下のように書けば解決できます。

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

最後に、OpenPoseのバージョン変化によると思われるエラーが発生しました。 これは自分の予想が入るので確かではないのですが、OpenPoseのバージョンアップにより検出する骨格座標の数が18から25へ増え、 バージョンアップ前のOpenPoseを想定しているプログラムでは動かなくなっているようでした。

この座標数の変化によるプログラムの修正箇所は思って以上に多く、今の自分のPython知識では完全に治すことは難しいと考えたため、 記事が書かれた当時のバージョンと思われるOpenPose1.3.0を再ダウンロードすることにしました。

これにより正しく動作するかはまた後日確認したいと思います。

[追記] OpenPose1.3.0を入れたところ、何故か動作しませんでした。 途方に暮れながら@miu200521358様の記事を眺めていたところ、Qiitaの下の方にあるコメント欄に解決策が載っていました。

OpenPoseを起動する際のパラメータに「--model_pose COCO」と追加することで、OpenPoseの出力を25点から18点へ変更することができるみたいです。 これにより無事動作させることができました。