Как показать анимацию открытия/закрытия рта Пакмана на Java с двойной буферизацией?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь показать знаменитую анимацию открытия/закрытия рта персонажа pacman в одноразовой игре pacman, которую я создаю, чтобы научиться программированию игр.

Я рисую изображение открытого рта, а затем перерисовываю изображение закрытого рта в том же месте (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) {}
            }
}

Другие советы

Как сказал Сфоссен, вам нужна задержка между рисованием изображений.

Еще несколько вещей, которые следует учитывать.

  • Для плавной анимации вам, вероятно, понадобится нечто большее, чем просто изображения «рот открыт» и «рот закрыт».Вам понадобятся два или три промежуточных изображения.
  • Чтобы упростить управление ресурсами, вы можете объединить все кадры анимации в одно широкое изображение, которое будет выглядеть как «диафильм».Затем, чтобы нарисовать кадр, вы используете смещение (x, y) для интересующего вас кадра.
  • Наконец, если вы рисуете все кадры каждый раз, когда проходите основной цикл вашей программы, Pac-Man будет полностью пережевывать каждый раз, когда вы его перемещаете.Вам следует подумать о том, чтобы каждый раз рисовать только один кадр в основном цикле и использовать переменную для отслеживания, в каком кадре вы находитесь.

Пример (псевдокод)

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