我正在开发一个游戏,它包含在屏幕上的一些视图被移动,你可以与他们互动。
我正在使用ObjectAnimator修改x,y和这些视图的宽度和高度。
我正在添加更多的视图,移除其中的一些视图,并在X秒内用新的坐标和新的刻度再次添加它们。
为了更新屏幕,我每10毫秒使用线程上的run方法使屏幕上的所有项集合无效:
public void run() {
while( !backgroundThread.interrupted() ) {
synchronized(this){
wait(10);
doSomeStuffInOtherThread(); //like adding more items or moving them, etc...
allMyObjects.invalidateInOtherThread(); //this is just pseudocode for simplify the sample
}
}
}它能工作,在功能强大的设备上,每10毫秒重新绘制一次,给用户一种流畅的框架感。问题是,当我在低设备上测试游戏时,游戏非常慢。我认为这是因为doSomeStuffInOtherThread()和allMyObjects.invalidate()InOtherThread方法在低设备上执行太多,超过10 is,而在高端设备上则是立即执行的(小于10 is )。
有一个更好的方法来重新绘制屏幕而不会失去游戏的速度?如果游戏正在丢失fps而不是问题,问题在于它正在丢失速度。。
谢谢
发布于 2017-02-14 19:25:35
基本上,你的问题是你依赖于你的设备处理你的东西所需的时间。这可以用类似的例子来说明。
struct Ball {
float pos_x, pos_y;
float vel_x, vel_y;
};
int main() {
Ball b{ 0.f, 0.f, 10.f, 10.f };
for (;;) {
DosomethingThatMightTakeAWhile();
b.pos_x += b.vel_x;
b.pos_y += b.vel_y;
}
}查看这段简单的代码,您可以很容易地看到,任何计算机从(0, 0)到(100, 100)都需要10个步骤,但取决于DoSomethingThatMightTakeAWhile()在特定计算机上完成的时间,这10个步骤可能在10毫秒内完成,也可能在10秒内完成。这就是你的问题所在。您不需要花费计算的实际时间来计算您的元素移动了多少。
要解决这个问题,您只需考虑从上一帧到最后一帧所需的时间(也许可以睡上一小段时间来节省电池)。所以现在您的代码将如下所示
int main() {
Ball b{ 0.f, 0.f, vel_x, vel_y }; // vel_x and vel_y are the new velocities,
// tweaked to match the speed you want
int64_t t0, t1; // In milliseconds here
t0 = GetTimeSinceStartup();
for (;;) {
DoSomethingThatMightTakeAWhile();
t1 = GetTimeSinceStartup();
float dt = (t1 - t0) / 1000.f; // Time elapsed in seconds
t0 = t1;
b.pos_x += b.vel_x * dt;
b.pos_y += b.vel_y * dt;
}
}您可以看到,代码并不复杂,但区别是,现在,您在计算新位置时有效地考虑了经过的时间。这意味着时间DoSomethingThatMightTakeAWhile()不再重要了,如果你想让你的球用1秒移动100个像素,你把它的速度设置为每秒100个像素,它需要1秒。
https://stackoverflow.com/questions/42181775
复制相似问题