2014-08-15 1 views
0

В игре серверу, возможно, придется отправить клиенту пакет с информацией, допустим, добавить Enemy. Данные, чтобы добавить такого врага, могут быть похожими на каждого врага (позиция, id ...), но есть необходимость различать, какой он враг. Это зомби? Оборотень? Что ж.Организация пакетов для сообщений подобного типа, но различного типа

Я помню два способа сделать это:

1 - Создание Enum.
Итак, у меня могло бы быть Enum с каждым типом врага, и в моем Пакете я бы послал этот тип. Плюсы: Только один Пакет для добавления нескольких типов врагов, только один способ обработки его приема.

Против: Каждый раз, когда я хочу добавить нового врага, я должен создать новую запись в перечислении, а метод, который получает, скорее всего, будет раздражающим большим случаем переключения.

2 - Создайте пакет на врага, с разными «ручкой» метод
Pros: Это «кажется» более организованным, так как каждый элемент имеет назначенный пакет и метод, и нет необходимости, чтобы добавить запись в перечисление (хотя идентификатор должен добавить новый метод ручки, так что ... да.)

Недостатки: Многие враги имеют в виду множество пакетов, что означает многие методы обработки, которые могут быть беспорядком.

Итак, в основном, tl: dr, у меня есть «PacketAddEnemy» с перечислением типа EnemyType и несколькими коммутационными шкафами, или у меня есть «PacketAddZombie», «PacketAddWerewolf» и т. Д., Но в итоге со спамом пакетов и методов.

Я предпочитаю первый вариант, но мне не нравятся оба. Интересно, есть ли интересные альтернативы?

ответ

1

Существует много разных способов справиться с этим. Мой любимый способ справиться с этим похож на вариант, который вы опубликовали. Где каждый объект имеет уникальный идентификатор типа. Вместо одного длинного оператора switch для создания объектов, вместо этого вы можете использовать более основанный на reflection подход. Это немного медленнее, но он обеспечивает очень красивый и чистый интерфейс.

Просто помните, что есть много способов справиться с этим, и это только мой предпочтительный способ. Каждая игра обрабатывает это по-другому, и вам просто нужно пойти с чем-то, что вам нравится.

Пример:

public enum EntityIDs { 

    Zombie(EntityZombie.class), 
    Werewolf(EntityWerewolf.class); 
    // And so on for all of your entities 

    public Class< ? extends Entity > entityClass; 

    private EntityIDs(Class< ? extends Entity > cl) { 
     this.entityClass = cl; 
    } 

    public static Entity createEntity(int id) { 
     Class< ? extends Entity > cl = EntityIDs.values()[ id ].entityClass; 

     return cl.newInstance(); 
    } 
} 

Затем вы должны получить идентификатор типа с сервера и общих данных, таких, как местоположение. Этот идентификатор может быть порядковым номером типа Entity, или каким-либо другим способом вы решите сопоставить его с их типом. Затем вы можете использовать поле entityClass для создания объектов. Конечно, это требует, чтобы вы все еще перечисляли каждую сущность в перечислении, но создание новой модели так же просто, как и одна строка. Это требует, чтобы все Entities подклассы использовали общий суперкласс, например Entity. Это также требует, чтобы каждый подкласс Entity имел общий конструктор, обычно просто конструктор по умолчанию с инициализацией, выполненной после построения.

Наличие общего класса супер упрощает часть вашей проблемы. Вы должны поместить все общие данные, такие как местоположение, внутри суперкласса. Когда вы хотите переместить сущность, вам не нужно будет заботиться о том, какой тип сущности она есть, вам нужно будет только знать, в каком сущности и где она движется.

World world = ...; 
Entity entity = world.getEntity(entityId); 
if(entity != null) { 
    entity.move(newX, newY); 
} 

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

Это действительно связано с издержками, потому что отражение происходит не очень быстро. Обычно он состоит из нескольких вызовов метода для каждого вызова. Вы можете изменить это, чтобы вместо этого использовать фабричный шаблон, где каждый тип Entity имеет EntityCreator, который отвечает за создание каждого Entity.

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

  • Нет связанных вопросов^_^