如何在表面上绘制平滑的运动

How to draw smooth movement on surface

我正在尝试实现绘制对象的平滑移动。
在这里我画了一个圆圈,它本身在 Hypotrochoid 路径上移动。 我将延迟设置为 16 毫秒以获得每秒 60 帧并定位每一帧。但是我的圈子仍然不顺利。 主要 Activity

Handler handler = new Handler();
    Runnable runnable = new Runnable(){

        @Override
        public void run(){
            masterMotion.tryDrawing();
            handler.postDelayed(runnable, 16);

        }
    };


    @Override
    public void surfaceCreated(SurfaceHolder holder){
        masterMotion = new MasterMotion(MainActivity.this, holder);
        handler.postDelayed(runnable, 16);

    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int frmt, int w, int h){
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        handler.removeCallbacks(runnable);
    }

运动

public Motion(int type, int color, int xPos, int yPos, int radius, int totalHeight){
        this.type = type;
        this.color = color;

        this.radius = radius;
        xBottom = xPos;
        yBottom = yPos;
        xTop = xBottom;
        yTop =  (int) (radius * 0.2 - radius);
        xMid = xBottom;
        yMid = (int) (radius * 0.2 - radius + totalHeight / 2);
        xAlt = xBottom;
        yAlt=yBottom;
        switch(type){
            case 0:
                innerR = 20;
                hR = 10;
                hD = 2;
                break;


        }
    }


    public void drawMyStuff(final Canvas canvas, final Paint mPaint){
        updatePositions();
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(color);
        canvas.drawCircle(xR, yR, radius, mPaint);

    }


    public void updatePositions(){
        xR =
            (float) (xAlt + (innerR - hR) * Math.cos(angle) + hD * Math.cos(
                                                                               ((innerR - hR) /
                                                                                    hR) *
                                                                                   angle
            ));
        yR =
            (float) (yAlt + (innerR - hR) * Math.sin(angle) + hD * Math.sin(
                                                                               ((innerR - hR) /
                                                                                    hR) *
                                                                                   angle
            ));
angle = (angle + 0.03) % (2 * Math.PI);

        if(stepCount>=0){
            xAlt+=stepX;
            yAlt+=stepY;
            stepCount--;
        }
    }


    public void goBottom(){
        mustMoove=true;
        direction =0;
        stepX = (xBottom-xAlt)/20;
        stepY = (yBottom - yAlt) /20;
        stepCount=20;

    }


    public void goMid(){
        mustMoove = true;
        direction = 1;
        stepX = (xMid - xAlt) / 100;
        stepY = (yMid - yAlt) / 100;
        stepCount=100;
    }


    public void goTop(){
        mustMoove = true;
        direction = 2;
        stepX = (xTop - xAlt) / 100;
        stepY = (yTop - yAlt) / 100;
        stepCount=100;
    }

}

应用程序无法确定显示器的刷新率。尝试通过休眠 16.7 毫秒将速率 "set" 提高到 60fps 会产生不稳定的结果。您应该使用 Choreographer 来获取通知和时间信息,并按实际时间增量而不是固定长度的帧推进动画。

关于 Android 游戏循环的讨论可以在 architecture doc 中找到。

可以在 Grafika 中找到 Choreographer 的流畅动画插图;试试 "record GL app" activity,它即使在丢帧时也能流畅地制作动画。观看 "scheduled swap" activity 也很有趣,它可以用来证明 30fps 在 60fps 显示器上看起来比 48fps 更流畅,尽管帧速率较低。

可以在 Android Breakout 中看到使用 GLSurfaceView "queue stuffing" 方法的流畅动画。它使用自上次绘制回调以来的时间来确定将动画推进多远,这不如 Choreographer 准确,但对于大多数用途来说已经足够接近了。