이중 버퍼링을 사용하여 Java에서 팩맨의 입 열기/닫기 애니메이션을 표시하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/622375

  •  05-07-2019
  •  | 
  •  

문제

저는 게임 프로그래밍을 독학하기 위해 만들고 있는 일회용 팩맨 게임에서 팩맨 캐릭터의 유명한 입 열기/닫기 애니메이션을 보여주려고 합니다.

내가 하고 있는 일은 열린 입 이미지를 그린 다음 정확히 동일한(x/y) 위치에 닫힌 입 이미지를 다시 그리는 것입니다.하지만 이것은 작동하지 않으며 항상 입을 다물고 있는 애니메이션만 봅니다.

이것을 루프에 넣으면 시스템이 멈추고 입을 벌린 이미지가 깜박이는 것을 볼 수 있지만 이미지가 대체되는 것은 볼 수 없습니다.

두 이미지가 예상대로 올바르게 로드되는지 테스트하고 확인했습니다.

여기 내 startAnim() 함수는 애플릿을 두 번 클릭하면 호출됩니다.

public void beginGame() //Called from engine.java
{
    isRunning=true;
    repaint();
    pacman.startAnim();
}

public void startAnim() //In different class, pacman.java
{
    Image orig;
    while (engine.isRunning)
    {
        orig=this.getCurrentImg();
        draw(engine.getGraphics());
        this.setCurrImg(currImg2);
        this.draw(engine.getGraphics());
        this.setCurrImg(orig);
        this.draw(engine.getGraphics());
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e) {}
    }
}

public void draw(Graphics g) //Called from engine.paint()
{
    g.drawImage(getCurrentImg(), getX(), 
            getY(), engine);
}
도움이 되었습니까?

해결책

두 이미지 사이에서 잠을 자야합니다. 그렇지 않으면 마지막 이미지 만 그려집니다.

예를 들어.

while( running )
{
    image 1
    draw
    sleep
    image 2
    draw
    sleep
}

이 같은:

public void startAnim() //In different class, pacman.java
{
                            final int  cnt  = 2;
    Image[] imgs = new Image[ cnt  ];
    int         step = 0;

    imgs[ 0 ] = closedMouthImage;
    imgs[ 1 ] = openMouthImage;

            while ( engine.isRunning )
            {
                this.setCurrImg( imgs[ step ] );
                    draw(engine.getGraphics());
                step = ( step + 1 ) % cnt;
                    try
                    {
                                Thread.sleep(100);
                    }
                    catch (InterruptedException e) {}
            }
}

다른 팁

sfossen이 말했듯이 이미지를 그리는 사이에는 지연이 필요합니다.

고려해야 할 몇 가지 다른 사항.

  • 부드러운 애니메이션을 위해서는 "입을 벌린" 이미지와 "입을 닫은" 이미지 이상의 것이 필요할 수 있습니다.2개 또는 3개의 중간 이미지가 필요합니다.
  • 리소스 관리를 더 쉽게 하려면 모든 애니메이션 프레임을 "필름 스트립"처럼 보이는 하나의 넓은 이미지에 함께 넣을 수 있습니다.그런 다음 프레임을 그리려면 관심 있는 프레임에 대한 (x, y) 오프셋을 사용합니다.
  • 마지막으로, 프로그램의 메인 루프를 통과할 때마다 모든 프레임을 그리면 팩맨은 움직일 때마다 완전히 씹어먹을 것입니다.메인 루프를 통해 매번 하나의 프레임만 그리는 것과 변수를 사용하여 현재 있는 프레임을 추적하는 것에 대해 생각해야 합니다.

예(의사 코드)

frameWidth = 32
frameIndex = 0
while(running) {
  // Draw just the frame of your animation that you want
  drawImage(pacmanX, pacmanY, filmStrip, frameIndex * frameWidth, 0, frameWidth, frameHeight)
  frameIndex = (frameIndex + 1) % frameCount

  // Update position of pacman & ghosts
  // Update sound effects, score indicators, etc.
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top