Cam*_*ron 5 android frame-rate
我将我的游戏基于月球着陆器演示,虽然经过大量修改,但我可以达到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;
}
Run Code Online (Sandbox Code Playgroud)
And*_*ang 21
不要将您的游戏逻辑(对象移动等)更新速率基于帧速率.换句话说,将绘图和逻辑更新代码放在两个单独的组件/线程中.这样,您的游戏逻辑就完全独立于您的帧速率.
逻辑更新应该基于自上次更新以来经过了多长时间(让我们称之为delta).因此,如果您的对象以1px /毫秒移动,那么在每次更新期间,您的对象应该执行以下操作:
public void update(int delta) {
this.x += this.speed * delta;
}
Run Code Online (Sandbox Code Playgroud)
所以现在即使你的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.
}
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!如果您有任何其他问题,请询问; 我自己一直在制作Android游戏.:)
示例代码:
复制这两个片段(1个活动和1个视图)并运行代码.无论您的FPS是什么,结果都应该是一个白点平滑地落在您的屏幕上.代码看起来有点复杂而且很长,但实际上很简单; 评论应该解释一切.
这个活动类并不太重要.您可以忽略其中的大部分代码.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这堂课是令人兴奋的东西!
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9331 次 |
| 最近记录: |