2012-07-31 2 views
3

그래서 캐릭터의 위치에 폭탄을 넣을 수있는 게임을 만들고 있습니다. 폭탄이 표시 될 때 각각의 폭탄은 GIF 이미지와 연관되어 결국 붐 (Bomberman에 대해 생각하십시오)으로 이동합니다.캔버스 (Java)에서 동일한 애니메이션 GIF의 여러 인스턴스

문제는 화면에 두 개 이상의 폭탄을 칠하려 할 때 GIF의 마지막 프레임에서 그렸습니다. 조사해 보니 GIF 큐클을 재설정하는 image.flush() 메서드가 있지만 이제 문제는 화면에 두 번째 폭탄을 칠할 때마다 GIF주기가 이전의 폭탄에 맞게 다시 설정된다는 것입니다.

public Tnt(int x, int y){ 
    this.x = x; 
    this.y = y; 
    ImageIcon ii = new ImageIcon("src/main/resources/modelObjects/tnt.gif"); 
    image = ii.getImage(); 
    image.flush(); 
} 

내가 만들 때마다 폭탄이 ArrayList에 (listTnt)를 입력하고 6 초 후에 제거되고, 그래서는 이미 활성화 폭탄 페인트 :

다음은 각 폭탄에 대한 내 생성자입니다.

여기서 도면 내 방법 :

public void draw(Graphics2D g2d, JPanel board){ 
    for(Tnt tnt: listTnt){   
     g2d.drawImage(tnt.getImage(), tnt.getX(), tnt.getY(), board); 
    } 
} 

편집 : 그것은 Toolkit.getImage를 사용하여 이미지를 재사용하기 때문에, 문제는 이미지 아이콘임을 보인다. 대신 Toolkit.createImage는 재사용 할 수없는 이미지를 만듭니다. 심지어 그나마 지금 image.flush() 필요

public Tnt(int x, int y){ 
    this.x = x; 
    this.y = y; 
    Toolkit t = Toolkit.getDefaultToolkit(); 
    image = t.createImage("src/main/resources/modelObjects/tnt.gif"); 
} 

:

여기에 완벽하게 작동 TNT에 대한 나의 새로운 생성자입니다. 다들 감사 해요.

+2

'이미지'의 범위는 무엇입니까? – trashgod

+0

응용 프로그램의 주요 게임 상태 내에서 나는 폭탄의 목록이 있습니다. 게임에 폭탄을 떨어 뜨리면 새로운 Tnt가 생성되어 목록에 추가되고 6 초 후 (폭탄 수명주기) 폭탄이 목록에서 제거됩니다. 'draw' 메소드는 목록에서 폭탄만을 칠하고'image'는 Tnt 내의 변수입니다. –

+0

[Show an animated BG in Swing] (http://stackoverflow.com/questions/10836832/show-an-animated-bg-in-swing)도 참조하십시오. –

답변

6

Image은 각각 ImageIcon 사이에서 재사용되고 있습니다. OpenJDK source code으로 판단하면 각각이 Toolkit.getImage을 통해 단순히 이미지를 요청하기 때문인 것으로 보입니다.

기본이 툴킷은 같은 Image를 돌려 파일명이 같은 복수의 요구를 해결하기 위해 시도합니다 이 방법은 손에서 문제를 설명하는, 그러나, 멋진주의가있다. 대신

은 (는 처음부터 불필요하게 스윙 클래스를 사용하는 것은 적절 이후), 당신은 완전히 ImageIcon 단계를 건너해야하고, 대신 문서에 나와있는 Toolkit.createImage 전화 :

반환 값 Image는,이 메소드 또는 그 getImage 변형의 다른 호출 원과 공유되지 않는 새로운 객체입니다.

행운을 빈다.

+1

이것은 나에게 맞는 것 같습니다. – aglassman

+1

괜찮 았던 덕분에 선생님! –

+0

+1 좋은 설명과 해결책. 이전에 모르고 있던 해결책을 시도하면서 예제 코드를 추가했습니다. –

2

이 문제를 해결하는 방법을 알지 못했기 때문에 @super_ solution을 시도했지만 아주 잘 작동합니다. 예를 원하는 사람을위한 코드를 공유합니다. 그에게 +1

import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class TestAnimatedGif { 

    private static final int IMAGE_COUNT = 9; 

    protected void initUI() { 
     JFrame frame = new JFrame(TestAnimatedGif.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final JPanel panel = new JPanel(); 
     frame.add(panel); 
     frame.setSize(600, 400); 
     frame.setVisible(true); 
     final Timer t = new Timer(1000, null); 
     t.addActionListener(new ActionListener() { 

      int count = 0; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (count < IMAGE_COUNT) { 
        try { 
         JLabel image = new JLabel(new ImageIcon(Toolkit.getDefaultToolkit().createImage(
           new URL("http://www.sitevip.net/gifs/bomba/BOMB-B_animado.gif")))); 
         panel.add(image); 
         count++; 
         panel.revalidate(); 
         panel.repaint(); 
         System.err.println("image added"); 
        } catch (MalformedURLException e1) { 
         // TODO Auto-generated catch block 
         e1.printStackTrace(); 
        } 
       } else { 
        t.stop(); 
       } 
      } 
     }); 
     t.start(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new TestAnimatedGif().initUI(); 
      } 
     }); 
    } 

} 
+0

+1 [sscce] (http://sscce.org/)와 @super_. – trashgod