1

我第一次尝试为 android 编写游戏,并且需要编写一个循环来在画布上绘制动画。这基本上是我需要的:

every 0.1 seconds do { //0.1 seconds is arbitrary of course, I need a time frame that's good for animation
   every 5 seonds do {
      someStuff();
    }
   drawEverything();
}

任何人都可以推荐一种实现这一点的好方法吗?谢谢!

4

4 回答 4

2

你可以使用一个ScheduleExecutorService

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ScheduledExecutorService.html

Runnable someStuff = new Runnable....

Runnable drawEverything = new Runnable...

然后,安排他们:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

executor.scheduleAtFixedRate(someStuff, 0, 100, TimeUnit.MILLISECONDS);
executor.scheduleAtFixedRate(drawEverything, 0, 5, TimeUnit.SECONDS);

这比使用永不结束的循环要干净得多。好在如果你有一个关闭钩子,或者只是想直接调用它,你可以调用:

executor.shutDown()

这将完成任何待处理的任务然后停止。

于 2012-11-27T23:13:39.610 回答
0

这取决于您所针对的 Android API 版本以及您实现游戏的方式。

如果您对 API 级别 16 (4.1 / Jellybean) 及更高版本没问题,您可以使用 Choreographer 类 ( http://developer.android.com/reference/android/view/Choreographer.html )。

如果您使用的是 OpenGL ES 或提供垂直同步回调的引擎,您可能希望以不同的方式构建游戏。与其用你的时间来驱动显示器,不如让系统来驱动你的游戏,并且事件会根据经过的时间而发生。例如,参见http://code.google.com/p/android-breakout/GameState.calculateNextFrame()中推进弹跳球的方式。这感觉不太自然,因为您不再指挥流量,但它也更“真实”,因为您的动画将被锁定在屏幕刷新更新上。

于 2012-11-27T23:52:24.907 回答
0

尝试使用CountDownTimeronTick方法或ChronometersetOnChronometerTickListener方法。

于 2012-11-27T22:57:14.737 回答
0

创建一个 custom View,实现它的onDraw()方法并在那里做你的绘图。每次视图层次结构失效时,onDraw()都会调用:

public class MyGameView extends View {

    @Override
    protected void onDraw(Canvas canvas) {
        // Any tasks that should run every frame can be placed here. For
        // example moving the player and monsters.

        // Draw everything to canvas here.
        canvas.drawBitmap(mPlayerBitmap, mPlayerX, mPlayerY, null);
        canvas.drawBitmap(mMonsterBitmap, mMonsterX, mMonsterY, null);

        // Either do a invalidate() to draw in maximum frame rate here. Or do
        // postInvalidateDelayed(10) to draw a new frame every 0.1 seconds.
        // onDraw() will automatically be called by the system.
        postInvalidateDelayed(10);
    }
}

然后可以将您的新视图添加到现有视图层次结构中,其中包含Buttons 和TextViews 等其他内容,使用ViewGroup.addView(myGameView). 或者可以将其设置为内容视图以占据整个屏幕,使用Activity.setContentView(myGameView).

可以通过发布重复发生的任务,View.postDelayed()以确保它们与onDraw(). ARunnable可以发布,然后每次run()调用它的方法时再次发布自己。最好在 中发布任务Activity.onResume()并将其删除Activity.onPause(),以确保当您的游戏在后台时不会运行任何内容:

@Override
protected void onResume() {
    super.onResume();
    mMyGameView.postDelayed(mRunnable, 5000);
}

@Override
protected void onPause() {
    super.onPause();
    mMyGameView.removeCallbacks(mRunnable);
}

private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        // Perform reoccurring task...

        mMyGameView.postDelayed(mRunnable, 5000);
    }
};
于 2013-03-20T15:05:25.787 回答