在Android 2D游戏中使对象(位图)在画布上滚动

时间:2012-03-14 22:22:48

标签: android bitmap 2d surfaceview

我们知道,在Android 2D游戏中,在2D游戏中移动物体非常容易。只需使用SurfaceView并使用Canvas.drawBitmap()绘制单个位图。

但是当谈到滚动物体时,例如一个球,我怎么能做到这一点?使用变换矩阵会导致渲染位图的质量非常差,不是吗?

1 个答案:

答案 0 :(得分:1)

如果要使用基于Canvas的绘图旋转位图,除了使用转换矩阵之外没有太多选择,可以通过传递给Canvas.drawBitmap()的Matrix或直接调用的转换操作在画布上。如果您使用Paint.setFilterBitmap(boolean)启用位图过滤,质量将会很好,至少按照我的标准。

这是一个完整的例子(基于矩阵)你可以玩,特别是看看它有什么区别可以打开和关闭位图过滤(或者只看下面的截图)。它不使用SurfaceView,只是一个普通的自定义视图,但它应该很容易移植到SurfaceView:

<强> CustomView.java

package com.example.android;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.TypedValue;
import android.view.View;

public class CustomView extends View {
    private static final float DP_PER_SECONDS = 10;

    private final float mBallCirfumference;
    private final float mBallRadius;
    private final Bitmap mBallBitmap;
    private final Paint mBallBitmapPaint;
    private final Matrix mBallTransformMatrix = new Matrix();
    private final float mPxPerSecond;

    private long mStartTime = -1;

    public CustomView(Context context) {
        super(context);
        final Resources res = getResources();

        // Load the ball bitmap. You probably want to use a better bitmap ;)
        mBallBitmap = BitmapFactory.decodeResource(res, R.drawable.icon);

        // We need the radius and circumference of the ball for our calculations
        // later
        mBallRadius = mBallBitmap.getHeight() / 2;
        mBallCirfumference = mBallRadius * 2 * (float)Math.PI;

        // Create ourself a paint object so we can adjust the quality of the
        // bitmap drawing
        mBallBitmapPaint = new Paint();

        // Significantly improves quality when drawing transformed bitmaps. Compare
        // with when you disable this, which is the default
        mBallBitmapPaint.setFilterBitmap(true);

        // Calculate speed of ball in pixels
        mPxPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DP_PER_SECONDS,
                res.getDisplayMetrics());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // Calculate how far into the animation we are
        if (mStartTime == -1) {
            mStartTime = getDrawingTime();
        }
        long currentTime = getDrawingTime();
        float secondsPassed = (currentTime - mStartTime) / 1000.0f;

        // Calculate how far the ball has moved and how many degrees it has been
        // rotated as a consequence of the movement
        float movedDistance = secondsPassed * mPxPerSecond;
        float fullRotationsMade = movedDistance / mBallCirfumference;
        float rotationInDegrees = fullRotationsMade * 360;

        // Setup the transformation matrix to simulate a rolling ball
        mBallTransformMatrix.reset();
        mBallTransformMatrix.postRotate(rotationInDegrees, mBallRadius, mBallRadius);
        mBallTransformMatrix.postTranslate(movedDistance, 0);
        canvas.drawBitmap(mBallBitmap, mBallTransformMatrix, mBallBitmapPaint);

        // Force redraw so we get an animation
        invalidate();
    }
}

<强> ExampleActivity.java

package com.example.android;

import android.app.Activity;
import android.os.Bundle;

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new CustomView(this));
    }
}

使用位图过滤启用的示例屏幕截图。如果你运行这个例子,位图会像一个球一样滚动(原谅我糟糕的球形图形选择):

enter image description here

使用位图过滤禁用的示例屏幕截图。

enter image description here