2013-08-25 6 views
1

Я делаю маленькую игру. Это не действие, а головоломка, поэтому производительность не так важна. Теперь у меня есть основная игровая площадка, фоновое изображение. В некоторых случаях я хочу рисовать другие изображения над частями фонового изображения. Моя проблема заключается в том, что как фоновое изображение, так и наложенное изображение могут быть анимированными gif, с неизвестным количеством кадров (в основном, выбранным пользователем).Java: Наложение/наложение анимированного gif на другой анимированный gif

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

Как конечный результат может выглядеть следующим образом: http://i.stack.imgur.com/PxdDt.png (только представьте себе это анимированный)

Я нашел решение к нему, который работает, установив менеджер компоновки обнулить и используя позиционированы абсолютно компоненты JLabel с иконками, чтобы они анимированные, используя один в качестве фона, а другой добавил к нему в качестве переднего плана:

background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight()); 
foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight()); 
background.setLocation(0, 0); 
foreground.setLocation(30, 30); 
background.setLayout(null); 
background.add(foreground); 
frame.setLayout(null); 
frame.add(background); 

(полный код ниже)

Установка менеджера компоновки обнулить, как я слышал, проблематично (особенно, так как я. хотеть добавьте некоторый текст к изображению позже, хотя я бы использовал другой ярлык внутри фона один, а не сам ярлык фона или что-то еще), и изменение размера кажется невозможным таким образом, поскольку я не могу изменить размер значка изображения JLabels (нашли некоторые решения, которые разделили gif на один bufferedImage для каждого слоя и изменили их размер до того, как снова их снова собрать, через которые он теряет определенные задержки между кадрами и т. д.). Кроме того, поскольку позиция должна быть идеальной для пикселя, изменение размера, даже если возможно, может быть проблематичным из-за ошибок округления.

Теперь, есть ли лучший способ сделать это? Могу ли я каким-то образом загрузить анимированные gifs и объединить их вручную (даже жестко они могут иметь различное количество слоев), поэтому мне пришлось рисовать только одно изображение? Есть ли менеджер компоновки, где я могу вручную устанавливать позиции компонентов, но который автоматически масштабирует его, если вы изменяете размер окна/панели? Может быть, сторонний графический проект, который может делать то, что я хочу с места в карьер?

Идеально было бы что-то вроде того, что я сделал бы, если бы они не были анимациями, например, построение объединенного изображения, а затем изменение размера и отображение этого.

Полный код:

import java.awt.Dimension; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

public final class Tester extends JFrame { 
    public static void main(String[] args) throws MalformedURLException { 
     new Tester(); 
    } 

    private Tester() throws MalformedURLException { 
     setTitle("Tester"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Icon backgroundIcon = new ImageIcon(new URL("http://s5.favim.com/orig/51/animated-gif-gif-hands-sign-language-Favim.com-542945.gif")); 
     Icon foregroundIcon = new ImageIcon(new URL("http://i.imgur.com/89HANHg.gif")); 

     JLabel background = new JLabel(backgroundIcon); 
     JLabel foreground = new JLabel(foregroundIcon); 

     // ugly 
     background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight()); 
     foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight()); 
     background.setLocation(0, 0); 
     foreground.setLocation(30, 30); 
     background.setLayout(null); 
     background.add(foreground); 
     setLayout(null); 
     add(background); 

     // set size of frame to size of content 
     setResizable(false); 
     getContentPane().setPreferredSize(new Dimension(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight())); 
     pack(); 

     setLocationRelativeTo(null); 
     setVisible(true); 
    } 
} 
+0

В Вашем [sscce] (http://sscce.org/), доступ размещены изображения с помощью 'URL', как показано [здесь] (http://stackoverflow.com/a/10862262/230513) или [ниже] (http://stackoverflow.com/a/18434145/230513); использовать синтетические изображения, как показано [здесь] (http://stackoverflow.com/a/15982915/230513); или использовать значки 'UIManager', как показано [здесь] (http://stackoverflow.com/a/12228640/230513). – trashgod

+0

Отредактировано соответственно – Klaue

ответ

3

Это работает для меня. Меньшее орбитальное изображение центрируется внутри изображения большей фазы луны.

import java.awt.*; 
import javax.swing.*; 
import java.net.*; 

public final class Tester extends JFrame { 
    public static void main(String[] args) throws MalformedURLException { 
     new Tester(); 
    } 

    private Tester() throws MalformedURLException { 
     setTitle("Tester"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Icon backgroundIcon = new ImageIcon(
       new URL("http://1point1c.org/gif/moon/moonphases.gif")); 
     Icon foregroundIcon = new ImageIcon(
       new URL("http://1point1c.org/gif/thum/plnttm.gif")); 

     JLabel background = new JLabel(backgroundIcon); 
     JLabel foreground = new JLabel(foregroundIcon); 

     background.setLayout(new GridBagLayout()); 
     background.add(foreground); 
     add(background); 

     pack(); 

     setLocationByPlatform(true); 
     setVisible(true); 
    } 
} 
+0

Это (или другие менеджеры макетов) было бы хорошо, если бы изображение переднего плана должно было быть центрировано, но оно должно быть в очень определенном месте. Представьте, например, фоновое изображение, показывающее стену с пустой рамкой для рисования, в которой при наведении курсора мыши или около нее анимированный gif должен отображаться (накладываться). он должен быть точно внутри кадра, поэтому все менеджеры макетов, о которых я могу думать, не будут работать. – Klaue

+0

Что, так что «пустая рамка картины» (независимо от того, что есть) не центрирована? Он перемещается или находится в статическом месте? –

+0

* «он должен быть точно внутри кадра», * точно, где ** ** *, поэтому все менеджеры макетов, о которых я могу думать, не будут работать ». * Если есть логика для позиционирования второго изображения, эта логика могут быть включены в диспетчер компоновки. –

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