Android SurfaceView游戏开发示例

本文介绍如何使用SurfaceView进行游戏开发,特别适用于对速度有高要求的游戏。通过双缓冲技术提高绘制效率,并提供了具体的Activity和GameSurfaceView实现示例。

 

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

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

 

具体示例:

Activity

 

[java]  view plain copy print ?
  1. public class Activity01 extends Activity {  
  2.       
  3.     GameSurfaceView gameView = null;  
  4.       
  5.     @Override  
  6.     public void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.          
  9.         gameView = new GameSurfaceView(this);  
  10.         setContentView(gameView);  
  11.     }  
  12. }  

 

 

GameSurfaceView

 

[java]  view plain copy print ?
  1. public class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{  
  2.   
  3.     private Activity01 mActivity = null;  
  4.       
  5.     private SurfaceHolder mHolder = null;  
  6.     private Thread mThread = null;;  
  7.     private boolean mLoop = false;  
  8.       
  9.     private Canvas mCanvas = null;  
  10.     private Paint mPaint = null;  
  11.     private long drawStartTime = 0, drawCostTime = 0, drawTotalTime = 30;  
  12.       
  13.     private float x, y;  
  14.     private int screenWidth = 480, screenHeight = 800;  
  15.       
  16.     public GameSurfaceView(Context context) {  
  17.         super(context);  
  18.   
  19.         mActivity = (Activity01)context;  
  20.           
  21.         mHolder = this.getHolder();  
  22.         mHolder.addCallback(this);  
  23.         setFocusable(true);  
  24.     }  
  25.   
  26.     @Override  
  27.     public void surfaceCreated(SurfaceHolder holder) {  
  28.         mPaint = new Paint();  
  29.         mPaint.setColor(Color.CYAN);  
  30.         mLoop = true;  
  31.           
  32.         new Thread(this).start();  
  33.     }  
  34.   
  35.     @Override  
  36.     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  37.         screenWidth = width;  
  38.         screenHeight = height;  
  39.           
  40.         x = screenWidth / 2;  
  41.         y = screenHeight / 2;  
  42.     }  
  43.   
  44.     @Override  
  45.     public void surfaceDestroyed(SurfaceHolder holder) {  
  46.         mLoop = false;  
  47.     }  
  48.   
  49.     @Override  
  50.     public void run() {  
  51.         while(mLoop){  
  52.             drawStartTime = SystemClock.uptimeMillis();  
  53.               
  54.             synchronized (mHolder) {  
  55.                 try {  
  56.                     mCanvas = mHolder.lockCanvas();  
  57.                     onDraw();       // repaint  
  58.                 } catch (Exception e) {  
  59.                     e.printStackTrace();  
  60.                 } finally {  
  61.                     if(mCanvas != null){  
  62.                         mHolder.unlockCanvasAndPost(mCanvas);  
  63.                     }  
  64.                 }  
  65.             }  
  66.               
  67.             drawCostTime = SystemClock.uptimeMillis() - drawStartTime;  
  68.             Log.i("drawCostTime""drawCostTime = " + drawCostTime);  
  69.             try {  
  70.                 if(drawCostTime < drawTotalTime){  
  71.                     Thread.sleep(drawTotalTime - drawCostTime);     // sleep elapse time  
  72.                 }  
  73.             } catch (Exception e) {  
  74.                 e.printStackTrace();  
  75.             }  
  76.         }  
  77.     }  
  78.       
  79.     private void onDraw(){  
  80.         if(mHolder == null && mPaint == null){  
  81.             return;  
  82.         }  
  83.           
  84.         mPaint.setAntiAlias(true);  
  85.         mPaint.setAlpha(100);  
  86.           
  87.         mPaint.setColor(Color.CYAN);    // paint background color  
  88.         mCanvas.drawRect(00, screenWidth, screenHeight, mPaint);  
  89.           
  90.         mPaint.setColor(Color.BLUE);    // paint foreground color  
  91.         mCanvas.drawCircle(x, y, 50, mPaint);  
  92.     }  
  93.       
  94.     @Override  
  95.     public boolean onTouchEvent(MotionEvent event) {  
  96.         super.onTouchEvent(event);  
  97.   
  98.         switch (event.getAction()) {  
  99.         case MotionEvent.ACTION_DOWN:  
  100.             this.x = event.getX();  
  101.             this.y = event.getY();  
  102.             break;  
  103.   
  104.         case MotionEvent.ACTION_MOVE:  
  105.             this.x = event.getX();  
  106.             this.y = event.getY();  
  107.             break;  
  108.   
  109.         case MotionEvent.ACTION_UP:  
  110.             this.x = event.getX();  
  111.             this.y = event.getY();  
  112.             break;  
  113.   
  114.         default:  
  115.             this.x = event.getX();  
  116.             this.y = event.getY();  
  117.             break;  
  118.         }  
  119.   
  120.         return true;    // true then event can be implemented again  
  121.     }  
  122.   
  123.     @Override  
  124.     public boolean onKeyDown(int keyCode, KeyEvent event){  
  125.         super.onKeyDown(keyCode, event);  
  126.           
  127.         if(keyCode == KeyEvent.ACTION_DOWN){  
  128.             this.mActivity.finish();  
  129.         }  
  130.           
  131.         return true;  
  132.     }  
  133. }  


运行效果:

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值