0

クラスで描画されるSpriteビットマップがあります。このビットマップは 1 つ以上の画像であるため、アニメーション化できます。

XMLの次をインフレートするとGameLayout、このスプライトが描画されます。run()私の GameActivityのメソッドが呼び出されるたびに (特別な状況で)、この画像は 4 回更新されるため、アニメーションは終了します。

これはすべて完全に実行されていますが、私の問題は、ボタンを押すと (条件が満たされているかどうかに関係なく)、ビットマップが次の画像にジャンプするため、view.invalidate().

どうすればこれを止めることができるか分かりますか?

ゲーム アクティビティ:

public class GameActivity extends Activity implements OnClickListener, Runnable
{
private int punkte;
private int highscore;
private Handler handler = new Handler();
private int balken = 0;
private boolean abnehmend = false;
private int Klick = 0;
private boolean balkenAktiv = true;
private boolean gewartet = false;
private int versuche;
private View view;
private int counter = 0;

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // inflate mainXML->
    View mainView = getLayoutInflater().inflate(R.layout.activity_game, null);
    // find container->
    LinearLayout container = (LinearLayout) mainView.findViewById(R.id.container);
    // initialize your custom view->
    view = new GameLayout(this);
    // add your custom view to container->
    container.addView(view);

    setContentView(mainView);

    versuche = leseVersuche();
    highscore = leseHighscore();
    setupActionBar();
    neueRunde();    

    Button button = (Button) findViewById(R.id.thebutton);
    button.setOnClickListener(this);
}

/**
 * Set up the {@link android.app.ActionBar}, if the API is available.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() 
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
    {
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.game, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    switch (item.getItemId()) 
    {
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void neueRunde()
{
    punkte = 0;
    refreshScreen();
}

private void refreshScreen()
{
    TextView tvPunkte = (TextView) findViewById(R.id.points);
    tvPunkte.setText("Punkte: " + Integer.toString(punkte));    

    TextView tvHighscores = (TextView) findViewById(R.id.highscores);
    tvHighscores.setText("Highscore: " + Integer.toString(highscore));

    TextView tvVersuche = (TextView) findViewById(R.id.versuches);
    tvVersuche.setText("Versuche: " + Integer.toString(versuche));
}

@Override
public void onClick(View v)
{
    if(Klick == 0)
    {
        handler.postDelayed(this, 0);
        Klick = 1;
    }
    else
    {
        if(Klick == 1)
        {   
            balkenAktiv = false;
            handler.postDelayed(this, 500);
            punkte = balken;
            versuche++;
            schreibeVersuche(versuche);
            highscore += punkte;
            schreibeHighscore(highscore);
            Klick = 2;
            refreshScreen();
        }
        else
        {
        if(Klick == 2)
            {
                Klick = 0;
                punkte = 0;
                balken = 0;
                ProgressBar proBar = (ProgressBar) findViewById(R.id.sprung);
                proBar.setProgress(balken);
                refreshScreen();
            }
        }
    }
}

@Override
public void run()
{   
    if(balkenAktiv == true)
    {
        gewartet = false;
        ProgressBar proBar = (ProgressBar) findViewById(R.id.sprung);
        if(abnehmend == false)
        {
            if(balken < 100)
            {
                balken+=5;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
            else if(balken == 100)
            {
                abnehmend = true;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
        }

        else if(abnehmend == true)
        {
            if(balken > 0)
            {
                balken-=5;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
            else if (balken == 0)
            {
                abnehmend = false;
                proBar.setProgress(balken);
                refreshScreen();
                handler.postDelayed(this, 0);
            }
        }       
    }       
    else if (balkenAktiv == false)
    {       
        if(gewartet == true)
        {
            if(counter < 4)
            {
                counter++;
                view.invalidate();
                handler.postDelayed(this, 500);
            }
            else if (counter >= 4)
            {
                balkenAktiv = true;
                counter = 0;
            }
        }
        gewartet = true;
    }
}   

private void schreibeHighscore(int highscore)
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    SharedPreferences.Editor editor = pref.edit();
    editor.putInt("HIGHSCORE", highscore);
    editor.commit();
}

private void schreibeVersuche(int versuche)
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    SharedPreferences.Editor editor = pref.edit();
    editor.putInt("VERSUCHE", versuche);
    editor.commit();
}

private int leseVersuche()
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    return pref.getInt("VERSUCHE", 0);
}

private int leseHighscore()
{
    SharedPreferences pref = getSharedPreferences("GAME", 0);
    return pref.getInt("HIGHSCORE", 0);
}   
}

ビュー クラスの onDraw:

    @Override
protected void onDraw(Canvas canvas)
{
    sprite.draw(canvas);
    sprite.update(System.currentTimeMillis());
}

スプライト クラス:

public class Sprite 
{   
//private static final String TAG = Sprite.class.getSimpleName();

private Bitmap bitmap;      // the animation sequence
private Rect sourceRect;    // the rectangle to be drawn from the animation bitmap
private int frameNr;        // number of frames in animation
private int currentFrame;   // the current frame
private long frameTicker;   // the time of the last frame update
private int framePeriod;    // milliseconds between each frame (1000/fps)

private int spriteWidth;    // the width of the sprite to calculate the cut out rectangle
private int spriteHeight;   // the height of the sprite

private int x;              // the X coordinate of the object (top left of the image)
private int y;              // the Y coordinate of the object (top left of the image)

public Sprite(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) 
{
    this.bitmap = bitmap;
    this.x = x;
    this.y = y;
    currentFrame = 0;
    frameNr = frameCount;
    spriteWidth = bitmap.getWidth() / frameCount;
    spriteHeight = bitmap.getHeight();
    sourceRect = new Rect( 0, 0, spriteWidth, spriteHeight);
    framePeriod = 1000 / fps;
    frameTicker = 0l;
}

public void update(long gameTime) 
{
    if (gameTime > frameTicker + framePeriod) 
    {
        frameTicker = gameTime;
        // increment the frame
        currentFrame++;
        if (currentFrame >= frameNr) 
        {
            currentFrame = 0;
        }
    }
    // define the rectangle to cut out sprite
    this.sourceRect.left = currentFrame * spriteWidth;
    this.sourceRect.right = this.sourceRect.left + spriteWidth;
}

public void draw(Canvas canvas) 
{
    // where to draw the sprite
    Rect destRect = new Rect( x, y, x + spriteWidth, y + spriteHeight);
    canvas.drawBitmap(bitmap, sourceRect, destRect, null);
}
}
4

1 に答える 1

0

これに対する解決策は非常に簡単でした:

メソッドで使用view.invalidate()する代わりに、GameLayout クラスのisnteadを呼び出します。run()
((GameLayout) view).update(System.currentTimeMillis())
update()onDraw()

この変更により、update()メソッドを自分から削除できたonDraw()ので、更新された場合onDraw()、画像は更新されますが、変更されません。

次に、メソッドに追加invalidate()して、update()更新後に再描画されるようにしました。

今、すべてがスムーズに実行されています。

于 2013-08-18T16:59:56.763 に答える