ダブルバッファリングを使用して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);
}
役に立ちましたか?

解決

2つの画像間でスリープする必要があります。それ以外の場合は、最後にペイントされた画像のみが表示されます。

eg。

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)オフセットを使用します。
  • 最後に、プログラムのメインループを通過するたびにすべてのフレームを描画すると、Pac-Manは移動するたびに完全な動きをします。メインループを通るたびに1つのフレームのみを描画し、変数を使用して現在のフレームを追跡することを検討する必要があります。

例(擬似コード)

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