我正在尝试学习使用传感器制作Android游戏。我要做的是使用加速度传感器使球在屏幕上移动。实际上,我做了一些其中的一部分。当x和y的加速度改变时,球在屏幕中移动。但我的问题是它看起来并不顺畅。看起来球在连续路径中没有在屏幕上绘制。我为这个应用程序使用SurfaceView
类,并且我在与主线程不同的线程上创建了绘图。
部分代码来自我的MainActivity
类,它与传感器相关:
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long actualTime = System.currentTimeMillis();
long delta_t = actualTime - lastUpdate;
lastUpdate = actualTime;
ax = event.values[0];
ay = event.values[1];
if (ax > 0) {
isleft = true;
delta_x = (float) (0.005 * ax * delta_t * delta_t);
}
if (ax < 0) {
isleft = false;
delta_x = (float) (-0.005 * ax * delta_t * delta_t);
}
if (ay > 0) {
isdown = true;
delta_y = (float) (0.005 * ay * delta_t * delta_t);
}
if (ay < 0) {
isdown = false;
delta_y = (float) (-0.005 * ay * delta_t * delta_t);
}
getBallPos();
}
}
private void getBallPos() {
delta_x /= 10000;
delta_y /= 10000;
for (int i = 1; i <= 10000; i++) {
if (isleft)
ballview.setX_loc(ballview.getX_loc() - delta_x);
if (!isleft)
ballview.setX_loc(ballview.getX_loc() + delta_x);
if (isdown)
ballview.setY_loc(ballview.getY_loc() + delta_y);
if (!isdown)
ballview.setY_loc(ballview.getY_loc() - delta_y);
}
}
部分代码来自扩展BallGame
的{{1}}类,我在不同的主题上绘图:
SurfaceView
提前谢谢。
答案 0 :(得分:1)
我认为有两个问题:
首先,您要用onSensorChanged
方法更新球的位置。该方法由系统调用,并不保证调用以恒定频率完成。在这种情况下,球的运动取决于这些调用。我认为更好的方法是将最后的ax
和ay
存储为变量,这两个onSensorChanged
方法可以访问这些变量来写入值和绘制线程以供读取。然后你可以在绘图线程中计算球位置,这可以用恒定频率重绘画布。
这给我们带来了第二个问题,即在循环时绘制线程。它不受控制画布重绘的频率。对系统来说是一个很大的负担。更好的方法是选择刷新率(例如每秒50帧)并以此频率更新绘图。它可以在while循环结束时完成,其中可以调用Thread.sleep()
函数。您可以在while循环开始时测量帧绘制何时开始long frameStartTime = System.currentTimeMillis()
,然后在while循环结束时调用:
long sleepTime = refreshInterval-(System.currentTimeMillis()-frameStartTime ); if (sleepTime > 0) { Thread.sleep(sleepTime); }
(50 fps是refreshInterval = 1000/50 = 20 ms)。
此调用在帧刷新间隔减去用于绘制球的时间的时间内休眠线程。当您选择足够的刷新率时,系统负载会降低,并且将有更多时间重新绘制。