View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。在游戏开发 中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要。在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等。

   游戏中最重要的就是需要与玩家交互,比如键盘输入、触笔点击事件,我们如何来处理这些事件呢?Android中提供了 onKeyUp、onKeyDown、onKeyMultiple、onKeyPreIme、onTouchEvent、 onTrackballEvent等方法,可以轻松地处理游戏中的事件信息。所以,在继承View时,需要重载这几个方法,当有按键按下或弹起等事件时, 按键代码自动会传输给这些相应的方法来处理。

    游戏的核心是不断地绘图和刷新界面,图我们已经通过onDraw 方法绘制了,下面来分析如何刷新界面。Android中提供了 invalidate 方法来实现界面刷新,注意,invalidate 不能直接在线程中调用, 就是不可以在子线程中调用明白乎?因为它违背了 Android的单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI 线程中执行,因此Android中最常用的方法就是利用Handler来实现UI线程的更新。 其实用 AsyncTask 也可以。

   下面是这样一个例子 我 画了一个在屏幕上不停变换颜色的矩形 我们定义一些 事件 可以通过 模拟器的 上下键 调节矩形的位置,比如把这个矩形向上移动或者把这个矩形向下移动。  下边们看一下运行效果。




我们一共有2个类一个继承了View用来画图 另外Activity类用来刷新我们的视图 这2类分别是 Activity01  和 GameView
GameView类

Java代码  收藏代码
  1. package com.yarin.android.Examples_05_01;  
  2. import android.content.Context;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Color;  
  5. import android.graphics.Paint;  
  6. import android.view.View;  
  7.   
  8. public class GameView extends View {  
  9.     int miCount = 0;  
  10.     int y = 0;  
  11.   
  12.     public GameView(Context context) {  
  13.         super(context);  
  14.     }  
  15.   
  16.     // 画图类  
  17.     public void onDraw(Canvas canvas) {  
  18.         if (miCount < 100) {  
  19.             miCount++;  
  20.         } else {  
  21.             miCount = 0;  
  22.         }  
  23.         // 绘图  
  24.         Paint mPaint = new Paint();  
  25.         switch (miCount % 4) {  
  26.         case 0:  
  27.             mPaint.setColor(Color.BLUE);  
  28.             break;  
  29.         case 1:  
  30.             mPaint.setColor(Color.GREEN);  
  31.             break;  
  32.         case 2:  
  33.             mPaint.setColor(Color.RED);  
  34.             break;  
  35.         case 3:  
  36.             mPaint.setColor(Color.YELLOW);  
  37.             break;  
  38.         default:  
  39.             mPaint.setColor(Color.WHITE);  
  40.             break;  
  41.         }  
  42.         // 绘制矩形  
  43.         canvas.drawRect((320 - 80) / 2, y, (320 - 80) / 2 + 80, y + 40, mPaint);  
  44.     }  
  45. }  



Activity01  这个类主要用来 刷新我们的视图

Java代码  收藏代码
  1. package com.yarin.android.Examples_05_01;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.view.KeyEvent;  
  8. import android.view.MotionEvent;  
  9.   
  10. public class Activity01 extends Activity {  
  11.     private static final int REFRESH = 0x000001;  
  12.   
  13.     /* 声明GameView类对象 */  
  14.     private GameView mGameView = null;  
  15.   
  16.     /** Called when the activity is first created. */  
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.   
  21.         /* 实例化GameView对象 */  
  22.         this.mGameView = new GameView(this);  
  23.   
  24.         // 设置显示为我们自定义的View(GameView)  
  25.         setContentView(mGameView);  
  26.   
  27.         // 开启线程  
  28.         new Thread(new GameThread()).start();  
  29.     }  
  30.   
  31.     Handler myHandler = new Handler() {  
  32.         //接收到消息后处理  
  33.         public void handleMessage(Message msg) {  
  34.   
  35.             switch (msg.what) {  
  36.             case Activity01.REFRESH:  
  37.   //注意这里的刷新界面实际上是在UI 线程中执行的 不是另外开启一个线程这里要搞清楚  
  38.                 mGameView.invalidate();  
  39.                 break;  
  40.             }  
  41.             super.handleMessage(msg);  
  42.         }  
  43.     };  
  44.   
  45.     class GameThread implements Runnable {  
  46.         public void run() {  
  47.             while (!Thread.currentThread().isInterrupted()) {  
  48.                 Message message = new Message();  
  49.                 message.what = Activity01.REFRESH;  
  50.                 //发送消息  
  51.                 Activity01.this.myHandler.sendMessage(message);  
  52.                 try {  
  53.                     Thread.sleep(1000);  
  54.                 } catch (InterruptedException e) {  
  55.                     Thread.currentThread().interrupt();  
  56.                 }  
  57.             }  
  58.         }  
  59.     }  
  60.   
  61.     /** 
  62.      * 当然可以将GameThread类这样写 
  63.      * 同样可以更新界面,并且不在需要 
  64.      * Handler在接受消息 
  65.     class GameThread implements Runnable 
  66.     { 
  67.         public void run() 
  68.         { 
  69.             while (!Thread.currentThread().isInterrupted()) 
  70.             { 
  71.                 try 
  72.                 { 
  73.                     Thread.sleep(100); 
  74.                 } 
  75.                 catch (InterruptedException e) 
  76.                 { 
  77.                     Thread.currentThread().interrupt(); 
  78.                 } 
  79.                 //使用postInvalidate可以直接在线程中更新界面   
  80. //我认为它这个方法也是给主线程发送消息 最后刷新界面的工作还是在主线程中执行的 
  81. //如果我的看法错误 还请 大家疯狂留言。 
  82.                 mGameView.postInvalidate(); 
  83.             } 
  84.         } 
  85.     } 
  86.      */  
  87.   
  88.     //详细事件处理见第三章  
  89.     //当然这些事件也可以写在GameView中  
  90.     //触笔事件  
  91.     public boolean onTouchEvent(MotionEvent event) {  
  92.         return true;  
  93.     }  
  94.   
  95.     //按键按下事件  
  96.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  97.         return true;  
  98.     }  
  99.   
  100.     //按键弹起事件  
  101.     public boolean onKeyUp(int keyCode, KeyEvent event) {  
  102.         switch (keyCode) {  
  103.         //上方向键  
  104.         case KeyEvent.KEYCODE_DPAD_UP:  
  105.             mGameView.y -= 3;  
  106.             break;  
  107.         //下方向键  
  108.         case KeyEvent.KEYCODE_DPAD_DOWN:  
  109.             mGameView.y += 3;  
  110.             break;  
  111.         }  
  112.         return false;  
  113.     }  
  114.   
  115.     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {  
  116.         return true;  
  117.     }  
  118. }  



  在Android中还提供了一个更新界面的方法postInvalidate,该方法使用起来更加简单,不在需要Handler,可以直接在线程中更新。 我想至于怎么实现 大家在注释部分已经看到了。希望大家能同时掌握2中方法,并熟练运用。这个大家多学看看 android 的线程 消息 队列方面的东西了。
android 2.0 平台  APILEVEL 5

posted on 2013-02-26 20:22  爱哎唉  阅读(162)  评论(0)    收藏  举报