Как должны быть объекты в Java-игре - PullRequest
4 голосов
/ 19 апреля 2010

РЕДАКТИРОВАТЬ: я просто удалил весь пост и переформулировал вопрос, чтобы быть более общим.

Я хочу сделать простую стратегическую игру: карта, юниты.

Карта: один класс. Единицы: другой класс, самозванец.

Простые вопросы:

  1. Как юнит должен перерисовать себя на карте.
  2. Единица должна быть JPanel или аналогичным компонентом Swing (просто чтобы иметь возможность управлять ими как сущностью со своими собственными обработчиками мыши) или может быть другой вещью, не пренебрегая тем фактом, что она должна быть автономным объектом со своими собственными действиями. обработчики и поля.
  3. Является ли эта модель юнитов карты правильной простой игрой, которая помогла бы мне в увлекательной форме изучить основы Java и ООП.

Вот так!

Ответы [ 2 ]

2 голосов
/ 20 апреля 2010

Есть 2 способа.

  1. Либо есть класс Map, который является основным JPanel, чтобы поддерживать коллекцию юнитов, но сохранить класс Unit как не-Swing. Когда вызывается метод paint () карты, попросите каждый модуль перерисовать себя, вызвав метод в каждом видимом модуле. Модуль может быть унаследован от любого базового класса, например Rectangle, или какой-либо другой структуры данных, которую вы используете в программе. В этом случае класс Unit обрабатывает рисование и вычисления, а карта обрабатывает щелчки и события для каждого модуля. Он может передать сообщение в подразделение, если это необходимо; однако, если самому устройству не нужно знать об этих вещах, этот метод работает хорошо. Класс Unit легкий и экономичный. Вы также можете решить, знает ли Подразделение свою позицию на карте или нет.

  2. Или иметь каждый юнит в качестве JComponent и обрабатывать его собственные события отдельно. Недостатком является то, что каждый экземпляр юнита создает кучу данных для его отрисовки. Таким образом, если у вас есть сотни юнитов, из которых нарисовано только несколько, этот способ неэффективен. Преимущество состоит в том, что каждый юнит может обрабатывать свои собственные события GUI без перевода и т. Д. Это предполагает также отображение 1: 1 реальных юнитов в игре и графических юнитов на экране. Также сложнее реализовать определенные обработчики событий в модуле, если ему нужно знать, что вокруг других модулей!

  3. Третий и, возможно, лучший способ состоит в том, чтобы иметь класс модулей данных, содержащий игровую информацию о модуле, как в (1), но у которого есть метод для создания JComponent, когда это необходимо. Например, JComponent может быть внутренним классом в модуле - он может получить доступ к данным модуля. Это замечательно, если единицу измерения необходимо отображать в 2 местах (например, на 2 экранах или видах).

-

Приложение к адресным комментариям

Это верно, в (1) Карта (основной JPanel) реализует обработчик мыши и спрашивает каждый юнит по очереди, если он «попал». Это позволяет вам делать более сложные вещи, например, иметь 2 блока, накладывающихся друг на друга / друг на друга, и оба могут реагировать на щелчок.

Кроме того, например, они могут быть не прямоугольными или могут быть нарисованы с помощью альфа-канала (если Юниты были JComponents, они по умолчанию будут захватывать любое событие мыши по всему своему прямоугольнику). Если ваши юниты не перекрываются и находятся в своих собственных прямоугольниках, тогда достаточно собственного обработчика мыши JComponent.

Если вы используете подход (1), Карта может спросить каждый блок, содержит ли он точку, по которой щелкают, и Карта затем может обработать процесс «выбора». Помните, что подразделение само по себе не сможет определить, какие другие подразделения выбраны - выбор может включать отмену выбора другого подразделения. В этом случае операция выбора на самом деле является операцией Map, а не операцией Unit, хотя она также может изменить внешний вид или функцию Unit.

Если вы используете отдельные JComponents для Юнитов, вы можете переопределить «Содержит» (Точка), чтобы определить, попадет ли мышь в элемент, но это не позволит другим Юнитам также реагировать на щелчок. Но каждый юнит может «выбрать себя» (установить флаг, используемый при рисовании), а затем уведомить карту (он должен будет найти его с помощью getParent или с помощью предварительно заданного свойства).

Ключевыми вещами, которые вы должны знать, прежде чем принять решение об этом проекте, будет: Вам когда-нибудь понадобится более одной панели «Карта» на игру? Вам когда-нибудь понадобится больше объектов Юнитов, чем должно быть отображено? Вам когда-нибудь нужно будет отображать юнит более одного раза? Если ответы да, вы должны отделить классы «Данные» от классов «Просмотр», как предложено в 3.затем: Что нужно «сделать» Юниту и что ему нужно знать о Карте и других Юнитах, чтобы сделать это? например перемещение обычно выполняется классом Map в этой ситуации, так как это зависит от карты и других юнитов; рисование лучше всего выполнять модулем, потому что может быть много подтипов модуля с различными структурами данных, которые, возможно, должны быть нарисованы; Операции выбора юнитов, как вы указали, находятся где-то посередине. Если вы видите, как Swing реализует это (например, ButtonGroup, ListSelectionModel), само «выделение» может рассматриваться как отдельный класс.

0 голосов
/ 19 апреля 2010

Несколько лет назад я создал пасьянс «колышек», который был просто JPanel, который расширил MouseListener и MouseMotionListener. Колышки были примитивными кругами, нарисованными в методе рисования, но вы могли отследить, где они приземлились, взяв курсор и математически определив квадрат, в котором он приземлился. Это выровнялось с массивом, который хранил 1 или 0 для каждого квадрата на доске в зависимости от того, было ли там что-нибудь. Вы также можете перетаскивать каждый фрагмент, находя текущую позицию курсора, а затем вызывая repaint () в методе mouseDragged, который вы получаете от реализации MouseMotionListener.

Я бы, вероятно, предложил начать с этого. Создайте массив любого размера и используйте его для отслеживания единиц измерения. Затем каждый раз, когда вы делаете ход, просто проверяйте этот массив и перерисовывайте ваши юниты в методе рисования. Если вы используете движение мыши, то вы можете получить текущую позицию устройства на mouseDown, затем сделать то, что я упоминал ранее, с помощью mouseDragged, а затем получить ваше окончательное местоположение на mouseUp, а также выполнить вычисления в отношении законных перемещений и т. Д. В mouseUp.

В методе рисования вы просто зацикливаетесь на массиве, который определяет карту, и если в текущей позиции в массиве есть единица измерения, то выполняете что-то вроде g.fillOval (x, y, x_dimension, y_dimension). В этом массиве могут быть только элементы, равные 0, если ни одна единица не находится в текущей позиции, или 1 для единицы команды 1 в текущей позиции, 2 для команды 2 и т. Д. Метод рисования возьмет эти числа и соответственно прорисует фигуры (измените цвет для каждого типа или любого другого).

Надеюсь, это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...