Java многопользовательская игра - сетевые концепции - PullRequest
7 голосов
/ 28 сентября 2011

Для школьного проекта мы должны создать многопользовательскую игру на Java (должна быть клиент / сервер), в которую можно играть через Интернет (мы программируем это в школе, так что это не домашняя работа).Игра пошаговая, но должен быть чат, конечно же, в режиме реального времени.Однако никто из нас не имеет опыта сетевого программирования, и чем больше я об этом читаю, тем больше у меня возникает вопросов.

Моей первой мыслью было использование API сокетов для реализации многопользовательской части.Сервер ожидает новых данных от клиентов.Тем не менее, есть несколько видов данных для получения, таких как сообщения чата, движения и т. Д. Кроме того, как только соединение с сервером установлено, должны быть отправлены некоторые исходные данные (например, имя игрока).Сервер должен иметь возможность видеть, какое сообщение он получил, но как?Я думал о создании класса Message со строковым полем type.Но в коде моего сервера я получу код, подобный следующему:

if (message.type.equals("message")) {
  // code to execute for chat messages
} else if (message.type.equals("movement")) {
  // code to execute for movement
} else if () {
  // ...
} else {
  // ...
} // Please ignore syntax errors :P

Когда есть много разных типов данных для отправки (и они будут), это не выглядит как самый эффективныйпуть.Кроме того, это будет означать, что и сервер, и клиент должны иметь этот класс / интерфейс сообщений (дублирующий код).

А как насчет других игровых вещей?Например, игрок 1 перемещает своего персонажа в положение, которое побеждает другого персонажа.Клиент игрока 1 рассчитывает это поражение и применяет правильные действия.Но что следует отправлять на сервер?Просто новая позиция игрока или также поражение?Первый вариант означает, что все остальные клиенты должны выполнять вычисления.Разве это не может вызвать проблемы?Поскольку у меня нет предыдущего опыта сетевого программирования, я немного запутался в том, как все это делать.

Я также читал в другой теме здесь, в Stackoverflow, что RMI может быть лучшим вариантом.Прочитав некоторую информацию об этом, я понимаю, что такое RMI, но я все еще не могу понять, является ли это хорошим вариантом для этого проекта или нет.Любые советы для этого?

Как видите, я немного запутался в том, как начать с сетевой части этого проекта.Я искал некоторые книги по игровому программированию (для Java ofcourse), но ни одна из них не сфокусирована на сетевой части.Я также искал сетевые книги по Java, но, похоже, они сосредоточены на технологии, а не на хороших практиках кода.

Если кто-нибудь знает хорошую книгу или совет по правильному выбору, это будет с благодарностью.

Спасибо

Ответы [ 2 ]

7 голосов
/ 28 сентября 2011

Вы на правильном пути, но есть несколько вещей, которые нужно прояснить.

Если вы используете сокеты, вы поняли, что вам нужно определить протокол - общий язык для обмена ходами и состоянием игры. Сокеты позволят вам отправлять любые данные практически в любом формате. Похоже, вы думаете о сериализации класса Message для отправки этого типа, это одно из действий. Если вы используете RMI (у которого есть собственный протокол), вы будете действовать так, как если бы вы вызывали методы Java, но по сути вы делаете что-то подобное, сериализуя данные и передавая их через сокет.

Нет ничего неявного в совместном использовании кода между клиентом и сервером - фактически, большинство сервисов делают это в той или иной форме. Ваш клиент и сервер могут использовать общую библиотеку для определения передаваемых классов сообщений. RMI использует заглушки метода для определения интерфейса. Веб-сервисы всех видов определяют способ вызова методов. Общая идея состоит в том, чтобы показывать только интерфейс, а не реализацию.

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

class MessageProcessor{
    void process(Move1Message m) {...}
    void process(Move2Message m) {...}
    ....

}

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

Если вы не заинтересованы в изучении того, как реализовать собственный протокол или использовать библиотеку сокетов Java, будет проще использовать RMI. Вы также можете использовать SOAP, REST или любой другой протокол, но я бы не стал задумываться о том, какой использовать в данный момент. У меня нет никаких предложений, кроме документации RMI , хотя я думаю, что в этой книге было много примеров кода для работы в сети.

0 голосов
/ 28 сентября 2011

при работе с сокетами у каждого клиента будет свое собственное соединение, от которого будет ждать поток сервера (не забудьте сбросить поток на стороне клиента, иначе вы будете ждать вечно)

каждая строка будетотдельное сообщение, и чтобы различать типы сообщений, вы можете использовать «заголовок» в начале каждого сообщения (определенную 3-символьную последовательность в начале), например, msg, mov, lgn и использовать * 1006.* Trie -подобный выбор с переключателями, чтобы быстро решить, какой из них вы получили


при использовании RMI вы можете заставить сервер сохранять объект менеджера (экспортированный и зарегистрированный в реестре), на котором клиентможет запросить объект "connection", который будет таким же, как соединение в реализации сокета, но вы сможете иметь метод для каждой вещи, которую хотите сделать, хотя обратные вызовы должны быть выполнены другим способом (ссокеты у вас есть соединение готово к этому)

...