私は現在、同時実行プリミティブが優れているため、ゲーム サーバーを実装するために go を使用しています。それはすべて簡単に実装でき、非常に確実に機能します。私は主に Java のバックグラウンドを持っていますが、Java の型階層を忘れるのに苦労しています。位置、速度などの同様のデータ構造をすべて共有するゲーム オブジェクトのコレクションが必要ですが、それらはすべて、更新メソッド内で異なる動作をしたり、異なる機能を許可する特別なフィールドを持つ場合があります。最初は、すべての共有データを含む構造体があり、各カスタム型はその構造体を埋め込んでいました。問題は、組織にデータ構造を使用することです。四分木を使用して、クライアントに近くのオブジェクトの状態を通知します。このようにして、各ゲーム オブジェクトの埋め込まれた構造体へのポインタをツリーに渡すことができ、すべてが機能します。
これの問題は、四分木を照会すると、含まれている型にアクセスできないことです。たとえば、
type GameObject struct {
Position Point
Velocity Point
ID int32
}
type Client struct {
GameObject
conn net.Conn
// other fields
}
ここで、オブジェクトの状態について近くのプレイヤーを更新したい場合、四分木を照会しますが、ゲームオブジェクトが実際にクライアントであるかどうかを判断する方法があり、パケットを送信するための接続にアクセスする方法がありません。
Java から、基本クラスを作成し、それをクライアント用にサブクラス化することに慣れています。次に、instanceof
特別な処理が必要なものを特定し、それに応じてキャストしてカスタム機能にアクセスできます。次のようなことができると思います。
type GameObject interface {
Position() Point
Velocity() Point
ID() int32
}
type Client struct {
pos Point
vel Point
id int32
conn net.Conn
// other fields
}
func (c *Client) Position() Point {
return c.pos
}
func (c *Client) Velocity() Point {
return c.vel
}
func (c *Client) ID() int32 {
return c.id
}
この方法では、型アサーションを使用してクライアントを分離できますが、これにより、他のゲーム オブジェクトを実装するための多くの重複コードが発生します。go でこのようなことを行うには、もっと慣用的な方法があると思います。これが正しい方法である場合、誰かがこの設計の背後にある理由を理解するのを手伝ってくれるかもしれません.