gpt4 book ai didi

Android 2d Canvas 游戏: FPS Jitter problem

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:49:27 25 4
gpt4 key购买 nike

我的游戏基于月球着陆器演示,尽管经过大量修改,我可以获得大约 40-50fps,但问题是它在 40-50fps 之间波动太大,导致移动图形抖动!它非常烦人,让我的游戏看起来很糟糕,而实际上它以良好的帧速率运行。

我尝试将线程优先级设置得更高,但这只会让情况变得更糟......现在它会在 40-60fps 之间波动......

我正在考虑将 FPS 限制在 30 左右,以使其保持不变。这是个好主意吗?还有其他人有经验或不同的解决方案吗?

谢谢!

这是我的运行循环

@Override
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if(mMode == STATE_RUNNING){

updatePhysics();
}
doDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}

private void updatePhysics() {

now = android.os.SystemClock.uptimeMillis();

elapsed = (now - mLastTime) / 1000.0;

posistionY += elapsed * speed;
mLastTime = now;
}

最佳答案

不要将游戏的逻辑(对象移动等)更新速率建立在帧速率上。换句话说,将您的绘图和逻辑更新代码放在两个单独的组件/线程中。这样您的游戏逻辑就完全独立于您的帧率。

逻辑更新应该基于自上次更新以来经过了多少时间(我们称之为delta)。因此,如果您有一个以 1 像素/毫秒的速度移动的对象,那么在每次更新期间您的对象应该执行如下操作:

public void update(int delta) {
this.x += this.speed * delta;
}

所以现在即使你的 FPS 滞后,它也不会影响你的物体的移动速度,因为 delta 会更大,使物体移动得更远以补偿(在某些情况下会很复杂,但这就是它的要点).

这是在逻辑更新对象(在某个线程循环中运行)中计算增量的一种方法:

private long lastUpdateTime;
private long currentTime;

public void update() {
currentTime = System.currentTimeMillis();
int delta = (int) (currentTime - lastUpdateTime);
lastUpdateTime = currentTime;
myGameObject.update(delta); // This would call something like the update method above.
}

希望对您有所帮助!如有其他问题请追问;我一直在自己制作 Android 游戏。 :)


示例代码:

复制这两个 fragment (1 个 Activity 和 1 个 View )并运行代码。无论您的 FPS 是多少,结果都应该是一个白点顺畅地落下您的屏幕。代码看起来有点复杂和冗长,但实际上很简单;评论应该解释一切。

这个 Activity 课不是太重要。您可以忽略其中的大部分代码。

public class TestActivity extends Activity {

private TestView view;

public void onCreate(Bundle savedInstanceState) {
// These lines just add the view we're using.
super.onCreate(savedInstanceState);
setContentView(R.layout.randomimage);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relative_layout);
view = new TestView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
10000, 10000);
rl.addView(view, params);

// This starts our view's logic thread
view.startMyLogicThread();
}

public void onPause() {
super.onPause();
// When our activity pauses, we want our view to stop updating its logic.
// This prevents your application from running in the background, which eats up the battery.
view.setActive(false);
}
}

这个类是令人兴奋的地方!

public class TestView extends View {

// Of course, this stuff should be in its own object, but just for this example..
private float position; // Where our dot is
private float velocity; // How fast the dot's moving

private Paint p; // Used during onDraw()
private boolean active; // If our logic is still active

public TestView(Context context) {
super(context);
// Set some initial arbitrary values
position = 10f;
velocity = .05f;
p = new Paint();
p.setColor(Color.WHITE);
active = true;
}

// We draw everything here. This is by default in its own thread (the UI thread).
// Let's just call this thread THREAD_A.
public void onDraw(Canvas c) {
c.drawCircle(150, position, 1, p);
}

// This just updates our position based on a delta that's given.
public void update(int delta) {
position += delta * velocity;
postInvalidate(); // Tells our view to redraw itself, since our position changed.
}

// The important part!
// This starts another thread (let's call this THREAD_B). THREAD_B will run completely
// independent from THREAD_A (above); therefore, FPS changes will not affect how
// our velocity increases our position.
public void startMyLogicThread() {
new Thread() {
public void run() {
// Store the current time values.
long time1 = System.currentTimeMillis();
long time2;

// Once active is false, this loop (and thread) terminates.
while (active) {
try {
// This is your target delta. 25ms = 40fps
Thread.sleep(25);
} catch (InterruptedException e1) {
e1.printStackTrace();
}

time2 = System.currentTimeMillis(); // Get current time
int delta = (int) (time2 - time1); // Calculate how long it's been since last update
update(delta); // Call update with our delta
time1 = time2; // Update our time variables.
}
}
}.start(); // Start THREAD_B
}

// Method that's called by the activity
public void setActive(boolean active) {
this.active = active;
}
}

关于Android 2d Canvas 游戏: FPS Jitter problem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3312720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com