2013-09-22 2 views
0

В настоящее время я использую go для реализации игрового сервера из-за потрясающих примитивов параллелизма. Все это было очень легко реализовать и работает очень надежно. Я прихожу в основном из фона Java, хотя у меня возникают проблемы с забыванием иерархии типов Java. Мне нужно иметь набор игровых объектов, которые имеют общую структуру данных, такую ​​как позиция, скорость и т. Д., Но все они могут иметь различное поведение в своих методах обновления или специальные поля, чтобы обеспечить разную функциональность. Первоначально у меня была структура, содержащая все общие данные, и каждый пользовательский тип вставлял бы эту структуру. Проблема заключается в использовании структур данных для организации. Я использую quadtree, чтобы клиенты не уведомляли о состоянии соседнего объекта. Таким образом, я могу передать дерево указателю на встроенную структуру каждого игрового объекта, и все работает.Проблема, связанная с поиском состава объекта

Проблема с этим я не могу получить доступ к содержащему типу, как только я запрошу квадрант. Так, например,

type GameObject struct { 
    Position Point 
    Velocity Point 
    ID int32 
} 

type Client struct { 
    GameObject 
    conn net.Conn 
    // other fields 
} 

Теперь, когда Если я хочу обновить ближайшие игрок о состоянии объекта, я запросить квадрадерево, но нет теперь способа определить, является ли GameObject на самом деле клиент, и нет способ доступа к его соединению для отправки пакетов.

Из 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, и я ценю любую помощь, которую я могу получить. Если это путь, возможно, кто-то может помочь мне разобраться в рассуждениях, стоящих за этим дизайном.

ответ

0

Трудно ответить на вопрос, не зная больше о проблеме и ваших ограничениях, но вот три идеи.

Во-первых, возможно, вы можете хранить композитный тип в квадратном дереве, а не только указатель GameObject.

type QuadTreeEntry struct { 
    GameOb *GameObject 
    Entity interface{} 
} 

«Сущность» будет * Клиентом и все остальное, что будет в вашем квадранте.

Во-вторых, вы можете подумать, нужен ли вам весь GameObject в quadtree. Может быть, это было бы лучше?

type QuadTreeEntry struct { 
    Position Point 
    Entity interface{} 
} 

Это имеет хороший эффект удаления косвенности получить на позиции в коде квадрадерева, и это труднее случайно аннулирование квадрадерева, так как его не обмен данных Амплуа с исходным объектом.

В-третий, если эффективность не слишком важна, вы можете сделать это:

type GameObjectGetter interface { 
    GetGameObject() *GameObject 
} 

func (c *Client) GetGameObject() *GameObject { 
    return &c.GameObject 
} 

Так что все, что идет в четырехъядерном дереве будет GameObjectGetter.

Смежные вопросы