第 4,5 回:マルチスレッドとネットワーク

Download Report

Transcript 第 4,5 回:マルチスレッドとネットワーク

プロジェクト演習Ⅳ・Ⅵ
インタラクティブゲーム制作
第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フレーム程度ため込んでおくことで、
多少の通信速度のムラは吸収できる
– あまりためすぎると、操作に対する反応の
遅延が大きくなってストレスがたまる
コマンドの送り方
• 固定長のテキストでキーワードを送る
• その後でキーワードに即したデータ送信
• キー操作以外にもチャットメッセージを
送ったりもできる
• コマンドだけだと何かのタイミングで
取りこぼしがあると致命傷なので、
一定のタイミングで現在の状態そのもの
を送信