Android 在曲面视图中设置图像动画和旋转图像

Android 在曲面视图中设置图像动画和旋转图像,android,Android,我想在SurfaceView上设置运动动画。理想情况下,我也希望在动画完成后收到通知 例如: 我可能有一辆朝北的车。如果我想给它设置动画,使它朝南500毫秒,我怎么能做到呢 我使用的是SurfaceView,所以所有动画都必须手动处理,我认为我不能使用XML或android Animator类 另外,我想知道在SurfaceView中连续设置动画的最佳方法(例如,步行循环)手动旋转图像可能有点痛苦,但我是这样做的 private void animateRotation(int degrees,

我想在SurfaceView上设置运动动画。理想情况下,我也希望在动画完成后收到通知

例如: 我可能有一辆朝北的车。如果我想给它设置动画,使它朝南500毫秒,我怎么能做到呢

我使用的是SurfaceView,所以所有动画都必须手动处理,我认为我不能使用XML或android Animator类


另外,我想知道在SurfaceView中连续设置动画的最佳方法(例如,步行循环)

手动旋转图像可能有点痛苦,但我是这样做的

private void animateRotation(int degrees, float durationOfAnimation){
    long startTime = SystemClock.elapsedRealtime();
    long currentTime;
    float elapsedRatio = 0;
    Bitmap bufferBitmap = carBitmap;

    Matrix matrix = new Matrix();

    while (elapsedRatio < 1){
        matrix.setRotate(elapsedRatio * degrees);
        carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
        //draw your canvas here using whatever method you've defined
        currentTime = SystemClock.elapsedRealtime();
        elapsedRatio = (currentTime - startTime) / durationOfAnimation;
    }

    // As elapsed ratio will never exactly equal 1, you have to manually draw the last frame
    matrix = new Matrix();
    matrix.setRotate(degrees);
    carBitmap = Bitmap.createBitmap(bufferBitmap, 0, 0, width, height, matrix, true);
    // draw the canvas again here as before
    // And you can now set whatever other notification or action you wanted to do at the end of your animation

}
private void animateRotation(整数度、浮动持续时间){
long startTime=SystemClock.elapsedRealtime();
长时间;
浮点数elapsedRatio=0;
位图缓冲位图=carBitmap;
矩阵=新矩阵();
而(elapsedRatio<1){
矩阵旋转(elapsedRatio*度);
carBitmap=Bitmap.createBitmap(缓冲位图,0,0,宽度,高度,矩阵,真);
//使用您定义的任何方法在此处绘制画布
currentTime=SystemClock.elapsedRealtime();
elapsedRatio=(当前时间-开始时间)/活动持续时间;
}
//由于经过的比率永远不会完全等于1,因此必须手动绘制最后一帧
矩阵=新矩阵();
矩阵。设置旋转(度);
carBitmap=Bitmap.createBitmap(缓冲位图,0,0,宽度,高度,矩阵,真);
//像以前一样在这里再次绘制画布
//现在,您可以在动画结束时设置要执行的任何其他通知或操作
}
这将在指定的时间+绘制最后一帧的时间内,将carBitmap旋转到指定的任何角度。然而,有一个陷阱。这会旋转您的carBitmap,而不会正确调整其在屏幕上的位置。根据绘制位图的方式,最终可能会导致carBitmap旋转,而位图的左上角保持不变。当汽车旋转时,位图将拉伸并调整以适应新汽车的大小,并用透明像素填充周围的间隙。很难描述这会是什么样子,因此下面是一个旋转正方形的示例:

灰色区域表示位图的完整大小,并用透明像素填充。要解决这个问题,你需要使用三角学。这有点复杂。。。如果这最终成为您的一个问题(我不知道您是如何将位图绘制到画布的,所以可能不是),并且您无法找到解决方案,请让我知道,我将发布我是如何做到的


(我不知道这是否是最有效的方法,但只要位图小于300x300左右,对我来说效果就很好。也许如果有人知道更好的方法,他们可以告诉我们!)

你想要多个独立的动画对象吗?如果是这样,那么您应该使用游戏循环。(一个主while循环,增量更新所有游戏对象。)在各种循环实现上。(我目前正在为我的Android游戏项目使用“依赖于恒定游戏速度的FPS”。)

因此,您的汽车将看起来像这样(大量代码缺失):

您只需要加载位图一次。因此,如果您有多辆车,您可能希望为每辆车提供相同的位图对象(将位图缓存在SurfaceView中)

我还没有进入步行动画,但最简单的解决方案是有多个位图,每次调用display时只绘制一个不同的位图

如果你还没有看的话,请看一看


如果希望在动画完成时收到通知,则应进行回调

interface CompletedTurnCallback {
    void turnCompleted(Car turningCar);
}

让您的逻辑类实现回调,并让您的汽车在转弯完成时调用它(在
update()
)。请注意,如果您在
update\u game()
中迭代一个汽车列表,并试图在回调中从该列表中删除一辆汽车,您将得到ConcurrentModificationException。(您可以通过命令队列解决此问题。)

如果重复创建位图,可能会遇到性能问题。相反,只需创建一次,然后将矩阵传递到
canvas.drawBitmap()
。此外,while循环将阻止任何其他动画,直到你的回合完成。尝试一个游戏循环:
interface CompletedTurnCallback {
    void turnCompleted(Car turningCar);
}