У меня есть пользовательский образ заката в качестве фона в программе Java. Это JFrame с JPanel, а JPanel - фон захода солнца. Невозможно ли рисовать или рисовать изображения моего листа спрайтов поверх фона? Должен ли я использовать основные цвета, в которых я могу выбрать внутри программы, например, background (Color.BLACK) ;? Я хотел использовать пользовательское изображение в качестве фона и рисовать поверх фона, как если бы это был холст или панель, которую я планирую использовать. Я хочу, чтобы моя игра работала поверх этого. Добавление другого JPanel просто охватывает все.Проблемы с дисплеями
ответ
Вы могли бы ...
Сделать JPanel
, который рисует спрайты, сделать его прозрачным и добавить его к фону панели ...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BackgroundPane backgroundPane = new BackgroundPane();
backgroundPane.setLayout(new BorderLayout());
backgroundPane.add(new SpitePane());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(backgroundPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BackgroundPane extends JPanel {
private BufferedImage bgImg;
public BackgroundPane() {
try {
bgImg = ImageIO.read(...);
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return bgImg == null ? new Dimension(200, 200) : new Dimension(bgImg.getWidth(), bgImg.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bgImg.getWidth())/2;
int y = (getHeight() - bgImg.getHeight())/2;
g2d.drawImage(bgImg, x, y, this);
g2d.dispose();
}
}
public class SpitePane extends JPanel {
private BufferedImage sprite;
public SpitePane() {
try {
sprite = ImageIO.read(...);
} catch (IOException ex) {
ex.printStackTrace();
}
setOpaque(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - sprite.getWidth())/2;
int y = (getHeight() - sprite.getHeight())/2;
g2d.drawImage(sprite, x, y, this);
g2d.dispose();
}
}
}
Но проблема есть, вы на самом деле не достигаете какой-либо эффективности, когда вы обновляете SpritePane
, ему необходимо нарисовать BackgroundPane
(из-за того, как работают краска и прозрачные контейнеры)
Вы могли бы ...
Просто покрасить спрайты непосредственно над фоном, в то же время ...
Это произведет тот же результат, как и выше ...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
GamePane backgroundPane = new GamePane();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(backgroundPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GamePane extends JPanel {
private BufferedImage bgImg;
private BufferedImage sprite;
public GamePane() {
try {
bgImg = ImageIO.read(...);
sprite = ImageIO.read(...);
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return bgImg == null ? new Dimension(200, 200) : new Dimension(bgImg.getWidth(), bgImg.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bgImg.getWidth())/2;
int y = (getHeight() - bgImg.getHeight())/2;
g2d.drawImage(bgImg, x, y, this);
x = (getWidth() - sprite.getWidth())/2;
y = (getHeight() - sprite.getHeight())/2;
g2d.drawImage(sprite, x, y, this);
g2d.dispose();
}
}
}
сейчас , с небольшим количеством умной работы, это может быть фактически более эффективным, если вы только перекрасите области, которые изменились;)
AWT против Swing
Итак, вы продолжаете говорить о Canvas
/Panel
и JPanel
, вам необходимо знать, что эти компоненты работают значительно по-другому друг от друга.
Компоненты AWT (Canvas
/Panel
) известны как тяжелые весовые компоненты, у них есть собственный нативный аналог, на который они рисуют. Они не могут быть прозрачными и не имеют понятия z-упорядочения (что является проблемой при смешивании с компонентами Swing).
компоненты AWT позволяют вам взять под контроль картины процесса (AKA активная живопись), но исключает возможность когда-либо с помощью каких-либо компонентов Swing, с ними (как свинг имеет собственный процесс окраски)
компоненты Swing, известны как легкие весовые компоненты, они совместно используют собственный родительский окно, в котором они находятся. Они также дважды буферизованы по умолчанию (что является одной из причин использования BufferStrategy
с Canvas
) и может быть прозрачным. Swing использует так называемый алгоритм пассивного рендеринга, что означает, что диспетчер repaint будет принимать решения о том, что и когда что-то будет нарисовано, вы можете делать запросы о том, чтобы что-то обновлялось, но вы не можете гарантировать, когда это может быть выполнено ,
Ответ на ваш вопрос, это зависит. Вам нужно решить, какие функции у вас есть, и тип работы, которую вы готовы сделать (активная живопись может потребовать некоторую работу для настройки) и компромисс между двумя системами.
Вы могли бы один взглянуть на Painting in AWT and Swing, Performing Custom Painting и BufferStrategy
и BufferStrategy and BufferCapabilities для более подробной информации
- 1. Работа с несколькими дисплеями?
- 2. Контроллеры с несколькими дисплеями, я привинчен?
- 3. Управление формой в приложении с несколькими дисплеями
- 4. Работает ли Paper.js с сетчаткой или другими дисплеями высокой четкости?
- 5. Непрозрачный белый фон с дисплеями rgba серый на белом фоне?
- 6. Управление мышью с помощью xlib в конфигурации с несколькими дисплеями
- 7. Переключить текст с помощью JQuery с текстовыми дисплеями
- 8. Как я могу создать Android-устройство с двумя дисплеями?
- 9. NSStatusItem с пользовательским представлением, альфа-значением и несколькими дисплеями
- 10. Сохранить расположение JFrame в среде с несколькими дисплеями
- 11. C# Реорганизация позиций с несколькими дисплеями в Windows
- 12. Разница между 7 "и 5" ЖК-дисплеями с arduino
- 13. Переключение между одним и двумя дисплеями в визуальной студии
- 14. Управление 7-сегментными дисплеями от Arduino + 2 кнопок
- 15. Как уменьшить разрыв между двумя дисплеями: встроенные элементы?
- 16. В созданных программно dxf пунктирных линиях с дисплеями настраиваемого типа, например solid
- 17. CSS Проблемы с отображением: таблица
- 18. Проблемы с лентами с использованием дивы - меню навигации
- 19. Проблемы с использованием NSMutableArray с NSTableView (Cocoa)
- 20. Как выглядит Drupal Views между несколькими дисплеями с одним и тем же путем
- 21. Преобразовать в двоичную с дисплеями цикла только цифры, а не бинарные
- 22. API-интерфейс App App App Apping и позиционирование с несколькими дисплеями
- 23. Весь мир KML с дисплеями внутренней границы wierd на картах google
- 24. Как подключить две карты STM32F4-Discovery с ЖК-дисплеями через USART
- 25. Настраивание подформы с различными дисплеями в виде графического интерфейса в Access 2007
- 26. Проблемы с веб-частью Проблемы
- 27. 2 проблемы с перетаскиванием проблемы
- 28. Проблемы с памятью/потенциальные проблемы с памятью
- 29. Проблемы с JToolbar и проблемы с перетаскиванием
- 30. проблемы с goto и проблемы с петлями
Есть несколько. Вы можете просто нарисовать поверх фона через метод paintComponent панели или использовать другую панель и «BorderLayout», покрасить спрайты на второй панели и добавить вторую к первой. Помните, что «Canvas» и «Panel» были компонентами на основе AWT, которые не прозрачны (они непрозрачны, всегда) – MadProgrammer