Android SurfaceView游戏开发示例

scott0 2012-04-24

当我们需要开发一个复杂游戏的时候,而且对程序的执行效率要求很高时,View类就不能满足需求了,这时必须用SurfaceView类进行开发。

例如,对速度要求很高的游戏时,View类就不能满足需求了,这时必须使用SurfaceView类进行开发。例如,对速度要求很高的游戏,可以使用双缓冲来显示。游戏中的背景、人物、动画等都需要绘制在一个画布(Canvas)上,而SurfaceView可以直接访问一个画布,SurfaceView 是提供给需要直接画像素而不是使用窗体部件的应用使用的。 每个Surface创建一个Canvas对象(但属性时常改变),用来管理View和Surface上的绘图操作。 

具体示例:

Activity

public class Activity01 extends Activity {  
      
    GameSurfaceView gameView = null;  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
         
        gameView = new GameSurfaceView(this);  
        setContentView(gameView);  
    }  
}  

GameSurfaceView

public class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{  
  
    private Activity01 mActivity = null;  
      
    private SurfaceHolder mHolder = null;  
    private Thread mThread = null;;  
    private boolean mLoop = false;  
      
    private Canvas mCanvas = null;  
    private Paint mPaint = null;  
    private long drawStartTime = 0, drawCostTime = 0, drawTotalTime = 30;  
      
    private float x, y;  
    private int screenWidth = 480, screenHeight = 800;  
      
    public GameSurfaceView(Context context) {  
        super(context);  
  
        mActivity = (Activity01)context;  
          
        mHolder = this.getHolder();  
        mHolder.addCallback(this);  
        setFocusable(true);  
    }  
  
    @Override  
    public void surfaceCreated(SurfaceHolder holder) {  
        mPaint = new Paint();  
        mPaint.setColor(Color.CYAN);  
        mLoop = true;  
          
        new Thread(this).start();  
    }  
  
    @Override  
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
        screenWidth = width;  
        screenHeight = height;  
          
        x = screenWidth / 2;  
        y = screenHeight / 2;  
    }  
  
    @Override  
    public void surfaceDestroyed(SurfaceHolder holder) {  
        mLoop = false;  
    }  
  
    @Override  
    public void run() {  
        while(mLoop){  
            drawStartTime = SystemClock.uptimeMillis();  
              
            synchronized (mHolder) {  
                try {  
                    mCanvas = mHolder.lockCanvas();  
                    onDraw();       // repaint  
                } catch (Exception e) {  
                    e.printStackTrace();  
                } finally {  
                    if(mCanvas != null){  
                        mHolder.unlockCanvasAndPost(mCanvas);  
                    }  
                }  
            }  
              
            drawCostTime = SystemClock.uptimeMillis() - drawStartTime;  
            Log.i("drawCostTime", "drawCostTime = " + drawCostTime);  
            try {  
                if(drawCostTime < drawTotalTime){  
                    Thread.sleep(drawTotalTime - drawCostTime);     // sleep elapse time  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
    private void onDraw(){  
        if(mHolder == null && mPaint == null){  
            return;  
        }  
          
        mPaint.setAntiAlias(true);  
        mPaint.setAlpha(100);  
          
        mPaint.setColor(Color.CYAN);    // paint background color  
        mCanvas.drawRect(0, 0, screenWidth, screenHeight, mPaint);  
          
        mPaint.setColor(Color.BLUE);    // paint foreground color  
        mCanvas.drawCircle(x, y, 50, mPaint);  
    }  
      
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        super.onTouchEvent(event);  
  
        switch (event.getAction()) {  
        case MotionEvent.ACTION_DOWN:  
            this.x = event.getX();  
            this.y = event.getY();  
            break;  
  
        case MotionEvent.ACTION_MOVE:  
            this.x = event.getX();  
            this.y = event.getY();  
            break;  
  
        case MotionEvent.ACTION_UP:  
            this.x = event.getX();  
            this.y = event.getY();  
            break;  
  
        default:  
            this.x = event.getX();  
            this.y = event.getY();  
            break;  
        }  
  
        return true;    // true then event can be implemented again  
    }  
  
    @Override  
    public boolean onKeyDown(int keyCode, KeyEvent event){  
        super.onKeyDown(keyCode, event);  
          
        if(keyCode == KeyEvent.ACTION_DOWN){  
            this.mActivity.finish();  
        }  
          
        return true;  
    }  
}  

运行效果:

Android SurfaceView游戏开发示例

更多信息请查看 java进阶网 http://www.javady.com

相关推荐

tcxingdechen / 0评论 2015-04-17