Перемещение и изменение размера объекта JPanels внутри JFrame

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

  1. Невозможно установить размер каждой части, поэтому каждая часть JPanel занимает весь JFrame, скрывая остальные части и фон (игровое поле).

  2. Не могу установить положение фигур.

У меня есть диспетчер потоков по умолчанию. Пробовал setbounds и не повезло.

Возможно, я должен сделать часть, чтобы расширить другие JComponent? Добавленное изображение: Это кусок, теперь серая область тоже кусок! Проверил это, создав прослушиватель mousePressed и назначив ему некоторые вещи. Под серой областью находится игровое поле (или, по крайней мере, должно быть!), еще одна панель JPanel.

замещающий текст http://img42.imageshack.us/img42/2227/screenshotvdy.png< /а>

Некоторый код:

package TheProject;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameWindow extends JFrame {
public GameWindow() {
    setSize(800, 600);
    setLocationRelativeTo(null);
    Map map = new Map(800, 600, 2);
    add(map);

    MilitaryUnit imperialRussia = new MilitaryUnit(30, Color.BLACK, Color.YELLOW, Color.WHITE);
    imperialRussia.setPreferredSize(new Dimension(30, 30));
    add(imperialRussia);

}
 }

Это происходит, когда я применяю метод pack(): http://img442.imageshack.us/img442/5813/screenshot2ml.png

Пакеты вокруг модуля, а не карты, которая больше и заполняет JFrame.


person Gabriel A. Zorrilla    schedule 13.04.2010    source источник
comment
В итоге я использовал JLayeredPane, чтобы поместить все это (карту и юниты). JLP не поддерживает менеджеры компоновки, поэтому мне пришлось искать их вручную, но я работал.   -  person Gabriel A. Zorrilla    schedule 13.04.2010
comment
LayoutManagers повлияет на все дочерние компоненты этого контейнера независимо от настроек слоя. nofollow noreferrer">java.sun.com/javase/6/docs/api/javax/swing/JLayeredPane.html   -  person trashgod    schedule 13.04.2010


Ответы (4)


Я написал несколько игр, используя JPanel. В основном то, как я использую JPanel, похоже на то, как я использую Canvas, то есть я рисую непосредственно на нем, переопределяя метод paint(). Причина, по которой я использую JPanel, заключается в том, что я могу определить размер моего игрового мира, а затем использовать setPreferredSize() для установки размера панели. Затем я добавляю панель в файл JScrollPane. Таким образом, это позаботится о панорамировании и т. Д.

Скажем, я пишу 2D-игру. Вот как я использую JPanel. У меня есть логическая карта (2D-массив), которая содержит мою игровую карту. Скажем, каждое местоположение имеет размер 32x32 пикселя. Итак, вы начинаете рисовать землю и то, что находится на этой земле в этом месте. например, в x=1, y=2, что является положением экрана x=32, y=64, вы сначала рисуете землю, а затем рисуете то, что находится на земле. Таким образом, грубая схема цикла рендеринга будет выглядеть примерно так:

for (int y = 0; y < map.length; y++)
   for (int x = 0; x < map[y].length; x++) {
      drawGround(map[y][x])
      for very element on on map[y][x] - render them
}      

Вы устанавливаете прослушиватель MouseListener для JPanel, поэтому каждый щелчок мыши вы переводите обратно на карту, например. щелчок мышью x=54, y=72 будет соответствовать x=1, y=2. Расчет немного сложен, если у вас есть изометрический вид.

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

person Chuk Lee    schedule 13.04.2010
comment
Вы должны переопределить paintComponent(), а НЕ paint() для пользовательской окраски. - person camickr; 13.04.2010
comment
Я полагаю, что, поскольку я рисую все, а не настраиваю компонент, я буду использовать paint(). Единственное, что, возможно, мне следует сделать, это вызвать paintBorder() в paint(). В любом случае спасибо за комментарий к нему. - person Chuk Lee; 13.04.2010
comment
Да, но что, если вы хотите нажать на одну единицу/кусок? Как найти кусок? Вот почему я использовал этот подход с классом для карты/игрового поля и другим классом для юнитов/фигур. - person Gabriel A. Zorrilla; 13.04.2010
comment
Когда вы переводите экран на карту, вы получаете ссылку на структуру вашего игрового мира; в моем примере это массив. Таким образом, каждый элемент массива будет содержать ссылку на то, какие юниты находятся в этом месте. Я предполагаю, что только 1 единица может занимать пространство. Таким образом, вы точно знаете, какой блок выбран. Если в вашей игре нет понятия «этаж», как в боковом скроллере, вы можете применить подобное понятие. У вас есть все эти вещи, летающие по вашему экрану, когда вы нажимаете на них, сканируйте свою структуру данных, чтобы увидеть, какой объект выбран. - person Chuk Lee; 13.04.2010
comment
Существует множество игровых фреймворков Java, которые вы можете использовать и одновременно изучать Java 13thmonkey.org/ ~boris/jgame goldenstudios.or.id/products/GTGE interactivepulp.com/pulpcore Я использовал GTGE иpulpcore. Они с открытым исходным кодом, так что вы можете посмотреть, как они написаны. Однако большинство из них используют Canvas. Вы также можете посмотреть игру, которую я написал (и забросил, не спрашивайте) carcassonne.dev. java.net - person Chuk Lee; 13.04.2010

Для игры со случайным движением фигур вы, вероятно, использовали бы «нулевую раскладку».

Прочтите раздел руководства Swing по Абсолютное позиционирование, чтобы узнать больше. Информация.

person camickr    schedule 13.04.2010

Пробовали ли вы визуальный редактор NetBeans? Вы можете использовать его для перетаскивания и изменения размера объектов Swing по своему усмотрению в представлении «Дизайн», а затем можете переключиться в представление кода, чтобы увидеть сгенерированный код. Вы можете учиться таким образом.

person JRL    schedule 13.04.2010

Вы пробовали setPreferredSize(Dimension d)?

Изменить: вам нужно вызвать pack() в вашем JFrame после того, как вы добавили свои компоненты:

JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(800,600));
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200,200));
frame.add(panel);
frame.pack();
frame.setvisible(true);

Кроме того, вы добавляете карту в свой JFrame, которая имеет те же размеры, что и ваш JFrame - отлично. Но затем вы добавляете еще один компонент в раскладку потока по умолчанию. Это не может вместиться в вашу рамку, так как Карта уже занимает 100% места.

person Frederik Wordenskjold    schedule 13.04.2010
comment
Я думаю, что мы упускаем некоторые детали. Опубликуйте код, чтобы мы могли увидеть, что вы уже пробовали. - person Frederik Wordenskjold; 13.04.2010