2012-03-14 24 views
1

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

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

回答

1

如果要使用基于Canvas的绘图来旋转位图,则只需使用变换矩阵,或者通过传递给Canvas.drawBitmap()的Matrix或直接在Canvas上调用的变换操作。如果你用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

+0

非常感谢你,马丁!这个样本看起来很棒!但是目前,我正在使用'drawBitmap(位图位图,浮动左边,浮动顶部,Paint paint)'绘制位图。我怎样才能在这里附上矩阵?我在绘图之前尝试了canvas.setMatrix(矩阵),然后在绘图之后尝试了canvas.setMatrix(null)。但是然后这个对象(这里是:球)被绘制在它不应该在的地方。 – caw 2012-03-16 19:16:02

+1

不客气!通过在Matrix.postTranslate()中简单地添加'left'和'top'值,就可以直接使用'Matrix'来定位球,而不是使用上面的'Canvas'方法,就像这样:'mBallTransformMatrix.postTranslate左+移动距离,顶+ 0);'(对不起,最近的回复,我一直在度假。) – 2012-04-02 10:50:09

+0

非常感谢!现在旋转起作用了,至少!但是,当我在'Canvas.onDraw()'中使用'postTranslate()'的坐标之前,球就疯狂地飞过了屏幕。这是为什么?矩阵的翻译似乎不同于onDraw()使用的坐标,不是吗? – caw 2012-04-03 17:29:15