130 likes | 252 Views
プロジェクト演習 Ⅳ ・ Ⅵ インタラクティブゲーム制作. 第 4 回 マルチスレッド とネットワーク. 今日の内容. マルチスレッド ローディングの進捗表示とか 処理高速化も見込めます ネットワーク通信 必然的にマルチスレッドを扱います. マルチスレッドとは. 1 つの プログラムの中で複数の関数が 同時に ( 並列して ) 動かせる技術のこと 今まで皆さんが書いていたプログラムは 「実行している箇所」は 1 カ所だけだった シングルスレッド マルチスレッドの導入により、メインループを回しつつ、他のスレッドで重い処理をさせることができるようになる.
E N D
プロジェクト演習Ⅳ・Ⅵインタラクティブゲーム制作プロジェクト演習Ⅳ・Ⅵインタラクティブゲーム制作 第4回 マルチスレッドとネットワーク
今日の内容 • マルチスレッド • ローディングの進捗表示とか • 処理高速化も見込めます • ネットワーク通信 • 必然的にマルチスレッドを扱います
マルチスレッドとは • 1つのプログラムの中で複数の関数が同時に(並列して)動かせる技術のこと • 今まで皆さんが書いていたプログラムは「実行している箇所」は1カ所だけだった • シングルスレッド • マルチスレッドの導入により、メインループを回しつつ、他のスレッドで重い処理をさせることができるようになる
メリット・デメリット • 重い処理をメインループから外して処理の高速化、効率化が見込める • バックグラウンド読み込み、ローディングの進捗表示、ネットワーク処理、BGMのストリーミング再生など夢は広がるばかり • データのアクセスに制約が付く • バグった時の対応難度が跳ね上がる • 苦労して別スレッドにしてもその割にはリターンが少ない、あるいは悪化することもある
今回のサンプルは(も)Windows限定コード • boostというライブラリを使うと、機種依存せずにスレッド処理が可能 • ただし、ライブラリのサイズが膨大かつ、コンパイル速度が低下するなどの影響も • boostはおすすめしたいのですが、今回は学習の利便性をとってWindowsネイティブの実装にしました
使い方 • Javaライクにしてあります • 基底クラスを継承してMyThreadクラスを作る • Main()をオーバーライドして、別スレッドで行う処理を実装する • MyThreadオブジェクトを作り、Start()をコール • Main()を直接コールしてはだめ • 止める時はEnd()をコール
別スレッドで操作しているデータの参照 • 必ず受け渡し用のメンバ関数を作る • そのメンバ関数内でLock()~Unlock()を忘れずにコールする • Lock()して • 返値用の変数にデータをコピーしたりして • Unlock()する • これを怠ると、データの読み書きがかちあってSUGOIことになる
ネットワーク処理を扱う開発環境 • XNA • 何か規約とかが面倒らしい • DirectPlay • 滅びる定めのフレームワーク • boost::asio • 機種非依存で、将来はC++標準になるかも • でもboostなので… • winsock • Windowsネイティブ実装 • でもAPI構成はUNIXの系譜を受け継いでいてそこそこきれい(他機種への移植も容易)
ネットワークにはマルチスレッドが必須 • 通信待ち状態で処理が止まる • メインループに組み込もうもんならゲームになりようがない • サーバー • 接続してくるクライアントごとにスレッドを立てる • クライアント • サーバーとの接続用に1本立てる
今回のサンプル • POEを開発した時のテストプロジェクト • コマンドバッファによるアクションゲームに対応した設計例となっている • 60FPSのアクションゲームに対応できるのでだいたいのゲームに応用できるはず
考え方 • クライアント: • サーバーにキー入力情報を送る • サーバー: • 各クライアントからと、自分自身のキー入力情報を集め、あるフレームにおける全プレイヤーのキー入力状態のセットを作る • サーバー上で1セットの状態に基づいてゲーム状態を再現しつつ、各クライアントに1セット分のデータを送る • クライアント: • 受け取った1セット分のデータを数フレーム分プール(コマンドバッファリング)しておく • ある程度貯まったら1フレームずつ取り出して状態再現を行う
特徴 • 来たデータを片っ端から再現してしまうと、通信遅延が起きた時のガタ付きがひどくなる • 5フレーム程度ため込んでおくことで、多少の通信速度のムラは吸収できる • あまりためすぎると、操作に対する反応の遅延が大きくなってストレスがたまる
コマンドの送り方 • 固定長のテキストでキーワードを送る • その後でキーワードに即したデータ送信 • キー操作以外にもチャットメッセージを送ったりもできる • コマンドだけだと何かのタイミングで取りこぼしがあると致命傷なので、一定のタイミングで現在の状態そのものを送信