トップページ > 過去ログ > 記事閲覧
ネット対戦について
名前:ひら 日時: 2008/01/30 21:29

いつもDXライブラリを使わせて頂いております。 この度、初めてオンライン対応のゲームを製作しているのですが、わからない事が多々ありましたので質問させていただきます。 まず、参考としてサンプルのチャットプログラムを使わせてもらったのですが、もしint型とchar型を送信する事がある時はどうやって型の識別をすれば良いのでしょうか? 送信するデータ内に型の識別も加えてやるしかないのでしょうか? また、クラスなどを送信する際にデータのサイズを確認する方法は何かございますでしょうか?(lstrlenだと文字列のみなので・・・) そして、最後に同期についてですが、私が考えている方法は毎フレームにクライアントがキー入力をホストに送り、ホストがそれを踏まえて処理を行い、全クライアントに全変数のデータを返すというものです。 しかし、これだと全変数の容量が10kだとし、4人接続だとすれば、10(kバイト)*60(フレーム)*4=2.4Mとなってしまいます。 キー入力だけ渡して各自で処理をする方法では一度ズレてしまうと二度と戻らないので・・・。 何か良い方法はないものでしょうか? ご教授のほど、よろしくお願いいたします。

Page: 1 |

Re: ネット対戦について ( No.1 )
名前:crow 日時:2008/01/31 01:31

こんにちは。 クラスを送信するならばサイズが固定の物を使うべきだと思います。 また、異なるデータを送信するためには、 やはり識別番号を最初に送るのがスマートなやり方のような気がします。 > キー入力だけ渡して各自で処理をする方法では一度ズレてしまうと二度と戻らない これは、どのようなゲームかによって変わってくると思います。 例えばテトリスのような相互依存があまりないゲームならば、 キー入力とフレーム番号を渡してキュー構造に格納してやれば、 もし通信が多少遅延したとても相手側の処理を数フレーム分まとめてやるだけですみます。 格闘ゲームのように相互に当たり判定の発生するゲームでは、 やはり誰かをホストにして処理しないとうまくいかないでしょう。 ホストが集めたキー入力データを、 全員分まとめて配信する方法ではどうでしょうか? これもキュー構造を使うことで遅延に対処できます。
Re: ネット対戦について ( No.2 )
名前: 日時:2008/01/31 11:31

>送信するデータ内に型の識別 過去に同じような質問がありますので そちらを参照してください。 ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=611 > クラスなどを送信する際に クラスがどの様なものを指すか微妙ですが、 C++などのクラスのことであれば送信できません。 というより意味がありません。 #ここでいうクラスの認識が間違っていれば #以下は無視してください。 たとえクラスのサイズが固定されていたとしても、 クラス内にあるメソッドの領域が実行時に 決定されては、そのメソッドを含むクラスを 送信できたとしても、受信側ではただのごみに なってしまいます。 また、多重継承などでポリモーフィズムな クラスなど保持されるインスタンスと実態が 異なるメモリに配置される可能性があるものは 送信したとしても受信側ではその領域すら 存在しない事になります。 データだけのクラスを使うならば素直に構造体を 使うべきでしょう。
Re: ネット対戦について ( No.3 )
名前:ひら 日時:2008/01/31 12:36

>>crowさん ご回答ありがとうございます。 また、質問となってしまいますが、私が作成しているのは格闘ゲームのように自分と相手の状態が毎フレーム重要になってくるものです。 そこでキューを使った同期方法を詳しく知りたいのですが、教えていただけませんでしょうか? 私の考えだとAが60F、Bが20Fの性能のPCがあった場合、一方的にBに処理が溜まってしまいBが見ている画面が毎秒40Fづつ遅れてしまいます。 対策として、AとBに受信フラグを作成し、フラグが立ったら送信できるというようにすれば、交互に通信ができると思いましたが、この場合だとBの送信をAが待つ事になり、Aが20Fしか性能がでなくなってしまいます(複数人でやる場合に一番性能の低い人に合わせることになってしまう) もし、Aの受信時間に制限をつける場合(100カウントして来なかったら受信ループを抜ける)は、AとBのキー入力に差異が出てしまいます。 例:Aが1・2・3・4・5という順で入力した場合に、3を入力の際にBからの受信ができなかったため、送信もしなかった。 Aの処理は1・2・3・4・5 Bの処理は1・2・4・5 この方法の時にキー入力のみでなく、必要な全てのデータを送信していれば問題はないのですが・・・。 少し頭の中がこんがらがってきました。 何か良い方法ありましたらよろしくお願いいたします。 >>通さん 過去の質問を参照させていただきまして、とても参考になりました。 クラスの送信に関しては、オブジェクトを送信時にどうやってそのオブジェクトのサイズを調べるのか悩んでいました。 過去の質問を見る限りではsizeof(クラス名)で良さそうですね。 また、オブジェクトに関してはデータのみでしたので構造体を使用したいと思います。 ご指摘ありがとうございました。
Re: ネット対戦について ( No.4 )
名前:crow 日時:2008/02/01 00:18

キュー構造とは、先に入れたデータから先に取り出せるという入れ物のことです。 (詳しく解説しているサイトがたくさんあるので見てみてください) キュー構造を使った遅延対策というのは、 受信したデータをいったん入れ物に入れておいて、 溜まってる分だけ一度に処理させるという考え方です。 これをするためには、描画以外の処理を数フレーム分 まとめて行えるような作りにしておく必要があります。 以下は、実装の一例です。(格闘ゲームとします) [ホスト側の処理] 対戦相手のキー入力データを受信しキューに格納。 特定時間内に受信データが無い場合は、「相手はキー入力をしなかった」と判断。 データ格納数に応じて相手のキャラを数フレーム分動かす。 自分のキャラは当然1フレーム分の処理。 ダメージ判定はその後ホストだけが行う。 送信するデータは両キャラの位置やHP、アクションのフレーム数など。 [クライアント側] 毎フレーム、自分のキー入力データを送信。 自分では当たり判定や動作の処理は行わず、 受信したデータの最新の物だけを画面に反映させる。 他に、状況に応じていろいろと実装案はあると思います。 ただ、処理落ちの激しい状況でネット対戦をするのは少し辛い物があるかもしれません。 大手メーカーのゲームでさえ、通信の遅延や処理落ちの際には 予想もできないようなおかしな動きをすることがあります。 (例えば、戦っている敵がいきなりワープしたり、 当たったはずの攻撃が他の人から見ると当たってなかったり) ですから、一時的な処理の遅延は仕方ないにしても、 平均フレームレートはなるべく落ちないような状態にするべきだと思います。
Re: ネット対戦について ( No.5 )
名前:ひら 日時:2008/02/01 00:51

>>crowさん ご回答ありがとうございます。 やはり、「キーをホストに集めての処理」の場合と 「互いにキー入力を交換して、各自で処理」する場合の良し悪しがあるんですね。 自分としてはホスト側で処理を行って、結果をクライアント側に返すようにしたかったのですが・・・。 今回はオフラインゲームをオンライン化するという事で、 既に変数が無数に出来てしまっているため、それらを一回構造体に格納し、 送信してから、各変数に値を入れる作業が大変そうです。 (格納する変数を洗い出してExcelなどで「オブジェクト名.」を頭につければ良いのかも?) 何はともあれ、今回はとても参考になりました。 また不明な点があれば質問させて頂く機会があるかもしれません。 その時はよろしくお願いいたします。

Page: 1 |