[Lv6] ft_trancendence

https://github.com/42tokyo-ft-transcendence/ft_transcendence

<6/15追記>
expに応じてBHまでの日数が付与されると思った?この課題だけ8日しか付与されないよ!exam06は先にやっておこう。

時代のはざまの話をしよう。
4/1以前まではexamをやっていなくてもこの課題に登録できたんだ。だから、俺は今exam05もやっていないよ。examにチャレンジできる回数は残り3回だ。たのしいね。

Q. 何をする課題?
A. チャット機能のあるブラウザゲームを作ります。
frontendはnext.js(react)
backendはnest.js
DBはpostgreSQL
で実装します。

ボリュームの多い課題ですが、機能はかなり独立しています。
分担して実装したので、担当外のことは豆知識程度にしか把握していません。以下のようなことを触りました。

基本設計:画面レイアウト/UI

・大枠はfigmaで設計。手書きで書いたレイアウトをcssにしてくれるサイト。
https://www.figma.com/file/khcDUxA6n48hWWvC2HxwSG/ft_transcendence?node-id=1-3&t=TJoSqenGqoK74nkE-0

・ButtonとかImageとかListとか、UIまわりはchakraUIを利用しました。
もしchakraUIがなかったら完成度の低い不便なサイトになっていたと思う。根深いタブをつけてcssを調教する、などという作業をスキップできます。

・Game画面とかChat画面とかProfile画面とか、とにかくたくさん画面を作ることになります。どう画面遷移させよう?
実装初期では、クリックと同時に最前面に表示させるウィンドウを変更させるような構成でした。つまりURLはlocalhost:3000のまま、表示画面を変えるような実装。
だけど、ブラウザバックに対応していること、というレビュー項目があることがわかり、URL遷移に切り替えました。

認証まわり

・42認証
42APIを利用したsigninでは、nicknameとmailaddressの2データが返ってくるようです。今アクセスしている人がログインしているかどうかの判定はsession管理で行えます。

・二段階認証
QRコードを表示させます。こちらにもsessionを別にもたせて、二段階ができていない場合は二段階画面にリダイレクトさせる、といった判定を持たせていると思う

ChatRoom

チャット部屋では、状態が変化した場合、部屋の参加者全員に状態変化を通知するような仕組みが必要です。
クライアントがメッセージを送れば、サーバは部屋の参加者全員に、メッセージ情報の更新を通知して、画面に反映させます。
socket.emit()とか
socket.on()とか
socket.broadcast()とか
で、サーバーからクライアントに、一斉に情報変更の通知を行うような実装ができます。

Profile

・割と簡単な箇所。DBで管理しているUser情報を表示したり、更新したりします。
プロフィール画像の更新をどうするか
画像データはBackendに.jpgとして保存します。
DBには、画像が置いてあるbackendのpathを保存します。
frontが画像を取得する方法は、APIのGETでbackendにある画像ファイルをもってくるようにしています。

・プロフィール画像を表示するたびにGETさせると、動作が重くなるかな?という懸念がありましたが、1度表示した画像はfrontのcacheに残るので、ダウンロートが行われるのは初回だけのようです。えらいね。

・PublicのProfile情報について。
Q. 新規ユーザが作られたら、どうやってURLを動的に生成する?
A. [targetId].tsxを生成して、getStaticProps()を使う。
[]つきのファイル名はなかなか見慣れませんが、そういうものでした。

フレンドリスト

onlineとかofflineとかの通信情報を知る必要がありますが、Userデータの中にtextでonlineとかもたせればよかった。
sessionを利用して、offlineを感知するなど。

対戦相手とのマッチング

User情報とsocket情報をペアにしたかたまりをqueueに詰めて、待機している人がいればゲームに進むし、いなければ待機という感じ。

オプションで、特定の人とマッチングさせる必要があるので、opponentIdが設定されているかいないかで、自分が待機を継続するのか、今いる人とマッチングさせるのか、という判定を持たせています。

Game開始

front側では、上下キーの入力のみbackendに通知する、としています。
backend側で、今の玉の位置がどこかとか、プレイヤーのバーの位置がどこかとか計算して、1000/60のフレームで通知させています。

Gameが終了しない不具合に長く捕まって、煮詰まることがありました。
現象としては、新たに0-0から始まるゲームと、裏でひたすら過去のゲームが動き続け33-4になっているゲームとが存在してしまい、チラついて表示されてしまうもの。
多重起動されている感じ。Gameに詰めているobjectを終了させても死んでくれないので、そこではないらしい。

結論として、backend側でフレーム処理を宣言している箇所に、終了フラグを持たせる必要があったようだ。chatGPTが教えてくれた。

interval = setInterval(sendGameObjects, 1000 / 60);
// ゲームが終了したらインターバルを停止
currentGameObjects.onGameEnd(() => {
     clearInterval(interval);   
});

History

対戦履歴と、全体ランキング表示すればいいのかな?という感じ。
History専用のテーブルを持たせており、Nicknameも使っている。
ところが、UserのNicknameは自由に変更されるため、UserのNicknameが変わってもHistoryのNicknameが変わらないといった面倒なことがあった。

Tips/作業memo

Q. swagger?
A. APIの一覧を表示してくれる便利ツール。あのGETどうやって呼ぶんだっけとか、/UserにPOSTあるんだっけ?とか思ったときに、サイトで確認できる。

Q. package.json?
A. package.jsonがある階層でnpm installを実行すると、記述されたアプリケーションとバージョンが一括でinstallされます。共同開発するうえで、同じ環境を用意するために必要なもの。
自分で書く必要はなくて、npm install {application} を行うと、どんどん追記されるもの。
うまくいかない場合は、node_modulesを削除さて、npm iをしなおせばいい。

Q. WSLでホットリロードが10分以上かかる。
A. wslのマウント先にcloneすると、localデータとwslを行き来するから負荷がすごいらしい。
ホットリロードとは、とらせん実行中にファイルを編集更新すると、即座に適応させてくれる機構のこと。

\\wsl.localhost\Ubuntu-22.04\home\

この中でgitcloneすればリアルタイムで動く。

Q. ローカルで環境を動かしたい。
A. 
1. postgreSQLをローカルにインストール
https://blog.y-yuki.net/entry/2022/03/21/100000
起動させる。

■まずは sudo apt update で パッケージ一覧を更新
sudo apt update

■Postgres をインストール
sudo apt install postgresql

■Postgres の再起動を実行
sudo /etc/init.d/postgresql restart

■postgres ユーザにチェンジ
sudo -u postgres -i

■DB用のユーザ作成
createuser -d -U postgres -P db-user01
password = postgres

2, /backend/.env.local
LocalのDBとbackendを連携させる

DATABASE_URL="postgresql://db-user02:postgres@localhost:5432/ft_transcendence?schema=public"

# DATABASE_URL="{サービス名}://{USER名}:{パスワード}@{接続先ホスト名}:5432/{db名}}?schema=public"


Q. DBにデータを追加したい。APIでの変更を可能にしたい。
A. 一般的な話ではないがこういうこと。

https://github.com/42tokyo-ft-transcendence/ft_transcendence/commit/2722873953b592f28cb92d8c9b132ac587386501

データ追加するのに必要な編集は3ファイル
DBに追加するためのもの
・backend/prisma/schema.prisma
APIの更新を可能にするためのもの
・backend/src/users/dto/create-user.dto.ts
・backend/src/users/entities/user.entity.ts


課題中に得たものをここにすべてまとめたいが、建前上不要なものが多数生まれている。
下書きとして残すために、この機能を活用しただけ。購入しないこと。興味があればDMから。

ここから先は

2,823字

¥ 100,000

この記事が気に入ったらサポートをしてみませんか?