0

ゲームプログラミングを独学するために作っている使い捨てのパックマンゲームで、パックマンキャラクターの有名な口の開閉アニメーションを表示しようとしています。

私がやっていることは、開いた口の画像を描画してから、まったく同じ (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);
}
4

2 に答える 2

3

2つの画像の間で寝なければなりません。そうしないと、最後にペイントされたイメージしか表示されません。

例えば。

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) {}
            }
}
于 2009-03-07T20:02:57.357 に答える
2

sfossen が言ったように、画像を描画する間に遅延が必要です。

他にも考慮すべき点がいくつかあります。

  • アニメーションをスムーズにするには、おそらく「口が開いている」イメージと「口が閉じている」イメージ以上のものが必要です。2 つまたは 3 つの中間イメージが必要です。
  • リソース管理を容易にするために、すべてのアニメーション フレームを 1 つの幅の広い画像にまとめて、"フィルムストリップ" のように見せることができます。次に、フレームを描画するには、関心のあるフレームの (x, y) オフセットを使用します。
  • 最後に、プログラムのメイン ループを通過するたびにすべてのフレームを描画すると、パックマンは、移動するたびに完全なチョップを実行します。メイン ループで毎回 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.
}
于 2009-03-07T20:15:25.720 に答える