2011-04-27 5 views
0

나는 내 자신의 2 차원 게임을 만드는 중입니다. 게임 세계의 모든 객체에는 Sprite 객체가 있으며 화면이 그려지면 객체의 스프라이트가 객체의 위치에 그려집니다.스프라이트 애니메이션 관리 스레드를 사용하여

스프라이트 클래스는 단일 이미지 또는 애니메이션 스프라이트를 만드는 데 사용되는 일련의 이미지 일 수 있습니다.

import java.awt.image.BufferedImage; 
import java.awt.Graphics2D; 
public class Sprite implements Runnable{ 
    private int currentImage; 
    private BufferedImage[] sprites; 
    private int delayMS; 
    private Thread animation; 

    public Sprite(BufferedImage sprite){ 
     sprites = new BufferedImage[1]; 
     sprites[0] = sprite; 
    } 

    public Sprite(BufferedImage[] spriteAnimation,int delay){ 
     this.sprites = spriteAnimation; 
     currentImage = 0; 
     delayMS = delay; 
     //start a thread to time animation 
     animation = new Thread(this); 
     animation.start(); 
    } 

    private void next(){ 
     if(currentImage < sprites.length - 1) 
      currentImage++; 
     else 
      currentImage = 0; 
    } 

    public void run() { 
     while (Thread.currentThread() == animation) { 
      //delay the animation for delayMS 
      try { 
       Thread.sleep(delayMS); 
      } catch (InterruptedException e) { 
       break; 
      } 
      //next image 
      next(); 
     } 
    } 

    public void draw(Graphics2D g,int x,int y){ 
     g.drawImage(sprites[currentImage],null,x,y); 
    } 
} 

많은 애니메이션을 실행하기 위해 스레드를 사용한다는 주제에 대한 신뢰할만한 정보를 찾을 수 없었습니다. 이것이 최선의 접근 방식인지 궁금합니다. 내가 세계에 동일한 물건을 200,000 던지기 전까지는 모든 것이 잘 작동합니다. FPS가 낮아지기 시작하고 일부 애니메이션 스프라이트가 다른 시간에 프레임을 변경하기 시작합니다. 스레드가 인스턴스화 될 때 지연되기 시작하기 때문에 이것은 의미가 있습니다.

제 질문은이 문제를 처리 할 수있는 효과적인 방법이 있는지, 중요한 FPS 손실없이 더 많은 개체를 사용하도록 허용하고 스레드/스레드를 동기화하여 애니메이션이 프레임을 함께 전환하도록하는 것입니다.

+0

스윙을 사용하고 있습니까? – trashgod

+0

애니메이션에 대해서는 잘 모르지만 스레딩에 대해 알고 있습니다. currentImage 멤버를 var volatile로 변경해, 다양한 thread간에 갱신이 행해지도록 (듯이) 할 필요가 있습니다. 또한 생성자에서 Thread를 시작하는 것은 거의 항상 나쁜 설계입니다. (이 클래스를 하위 클래스로 만들려면 Thread가 완전히 생성되기 전에 Thread가 시작됩니다.) 정적 도우미 메서드를 사용하여 클래스를 만들고 스레드를 시작합니다 (완전히 생성 된 후). – jtahlborn

답변

1

일반적인 방법은 모든 스프라이트를 알고 각각의 프레임에 대해 그리기 메소드 (또는 바람직하게는 다시 그려야하는 것들만)를 호출하는 게임 루프를 만드는 것입니다. 이렇게하면 스프라이트가 애니메이션을 원한다고 결정할 때마다 다음 프레임까지 그렇게되지 않습니다. 그냥 그리기 방법을 애니메이션으로 처리하면됩니다. e.i. next() 부분. 물론 게임 루프에서 지연을두면 fps가 결정됩니다.

프레임 속도 독립적 인 애니메이션을 얻으려면 동일한 방법을 사용하지만 마지막 끌기 이후 경과 한 시간을 나타내는 draw 메서드에 인수를 추가 한 다음이 값을 기반으로 애니메이션의 양을 계산하십시오.

+0

감사합니다. 실에 대해 뭔가를 알기 전에 그것을 시험해 보았습니다. 더 잘 작동합니다. 다행히 물리학을위한 프레임 사이의 시간을 사용하고 있었기 때문에 스프라이트 클래스의 매개 변수를 수정해야만했습니다. – Hector

0

모든 스프라이트를 자체 스레드에서 실행하는 대신 컨테이너에 스프라이트를 놓고 렌더링 스레드에서 모든 표시된 스프라이트를 반복하고 그립니다 (스프라이트 우선 순위를 구현할 수도 있고 스프라이트 앞에 배경 레이어를 렌더링 할 수도 있습니다) ...).

0

스프라이트에 더 많은 스레드를 사용하면 (즉, 하나의 스프라이트에 대해 하나의 스레드) CPU를 먹을 것이고 게임에서 애니메이션을 구현하는 가장 좋은 방법은 스레드의 모든 실행 루프에 대한 것입니다. (다음 이미지 나 이전 키 누름과 같이) 스프라이트를 마지막에 페인트합니다. 여기에 스프라이트가 더 많고 페인트가 더 오래 걸리는 경우 동기화 할 때 2 ~ 3 스레드 최대 시간에 FPS가 떨어집니다.

관련 문제