1440用英语怎么说:【Android游戏开发十四】深入Animation,在SurfaceView中照样使用A...

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 17:07:08


【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!

  Himi  原创, 转载请注明! 谢谢。

  原文地址:http://blog.csdn.net/xiaominghimi/archive/2011/01/04/6116089.aspx


很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块;请点击下面联系进入阅读:

【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!

 

     之前在【Android2D游戏开发之四】中我给大家介绍了一张13帧的png的图,利用设置可视区域的方式来实现动画效果,但是这些属于我们自己来实现动画的方式,其实Android给我们的有两类自定义动画方式:

 

第一类:Frame By Frame 帧动画( 不推荐游戏开发中使用)

            所谓帧动画,就是顺序播放事先做好的图像,类似于放电影;

            分析: 此种方式类似我之前的那种利用设置可视区域的方式来实现动画效果,不仅类似而且还不如!所以此种方式在此不予分析;

 

第二类:Tween Animation 渐变动画

            即通过对对象不断做图像变换(平移、缩放、旋转)产生动画效果!实现方式其实就是预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。这些指令可以是以 XML 文件方式定义,也可以是以源代码方式定义。程序沿着时间线执行这些指令就可以实现动画 效果。

 

  总结:那么在Android 游戏开发中我们优先选用两种方式:第一种设置可视区域的方式来实现动画效果(帧动画),需要童鞋们手动实现,那么在之前我的博文【Android2D游戏开发之四】中已经有了相应的源码!大家可以去下载研究;那么这里就主要为大家详细分析 Tween Animation!

 

在讲述SurfaceView添加动画之前,我们先来看看在View中如何实现Tween Animation以及Tween 中的四种效果;

 

MyViewAnimation .java

view plain·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package com.himi.frameAnimation;    
  2. import android.content.Context;    
  3. import android.graphics.Bitmap;    
  4. import android.graphics.BitmapFactory;    
  5. import android.graphics.Canvas;    
  6. import android.graphics.Color;    
  7. import android.graphics.Paint;    
  8. import android.view.KeyEvent;    
  9. import android.view.View;    
  10. import android.view.animation.AlphaAnimation;    
  11. import android.view.animation.Animation;    
  12. import android.view.animation.RotateAnimation;    
  13. import android.view.animation.ScaleAnimation;    
  14. import android.view.animation.TranslateAnimation;    
  15. /**  
  16.  *@author Himi  
  17.  *@AlphaAnimation 渐变透明度动画效果  
  18.  *@ScaleAnimation 渐变尺寸伸缩动画效果  
  19.  *@TranslateAnimation 画面转换位置移动动画效果  
  20.  *@RotateAnimation 画面转移旋转动画效果  
  21.  */    
  22. public class MyViewAnimation extends View {    
  23.     private Paint paint;    
  24.     private Bitmap bmp;    
  25.     private int x = 50;    
  26.     private Animation mAlphaAnimation;    
  27.     private Animation mScaleAnimation;    
  28.     private Animation mTranslateAnimation;    
  29.     private Animation mRotateAnimation;    
  30.     public MyViewAnimation(Context context) {    
  31.         super(context);    
  32.         paint = new Paint();    
  33.         paint.setAntiAlias(true);    
  34.         bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);    
  35.         this.setFocusable(true);//只有当该View获得焦点时才会调用onKeyDown方法     
  36.     }    
  37.     @Override    
  38.     protected void onDraw(Canvas canvas) {    
  39.         super.onDraw(canvas);    
  40.         canvas.drawColor(Color.BLACK);    
  41.         paint.setColor(Color.WHITE);    
  42.         canvas.drawText("Himi", x, 50, paint);//备注1    
  43.         canvas.drawText("方向键↑ 渐变透明度动画效果", 80, this.getHeight() - 80, paint);    
  44.         canvas.drawText("方向键↓ 渐变尺寸伸缩动画效果", 80, this.getHeight() - 60, paint);    
  45.         canvas.drawText("方向键← 画面转换位置移动动画效果", 80, this.getHeight() - 40, paint);    
  46.         canvas.drawText("方向键→ 画面转移旋转动画效果", 80, this.getHeight() - 20, paint);    
  47.         canvas.drawBitmap(bmp, this.getWidth() / 2 - bmp.getWidth() / 2,     
  48.                 this.getHeight() / 2 - bmp.getHeight() / 2, paint);    
  49.         x += 1;    
  50.     }    
  51.     public boolean onKeyDown(int keyCode, KeyEvent event) {    
  52.         if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {//渐变透明度动画效果    
  53.             mAlphaAnimation = new AlphaAnimation(0.1f, 1.0f);    
  54.             //第一个参数fromAlpha 为动画开始时候透明度    
  55.             //第二个参数toAlpha 为动画结束时候透明度    
  56.             //注意:取值范围[0-1];[完全透明-完全不透明]    
  57.             mAlphaAnimation.setDuration(3000);    
  58.             ////设置时间持续时间为3000 毫秒=3秒    
  59.             this.startAnimation(mAlphaAnimation);    
  60.         } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {//渐变尺寸伸缩动画效果    
  61.             mScaleAnimation = new ScaleAnimation(0.0f, 1.5f, 0.0f, 1.5f, Animation    
  62.                     .RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f);    
  63.             //第一个参数fromX为动画起始时X坐标上的伸缩尺寸    
  64.             //第二个参数toX为动画结束时X坐标上的伸缩尺寸    
  65.             //第三个参数fromY为动画起始时Y坐标上的伸缩尺寸    
  66.             //第四个参数toY 为动画结束时Y 坐标上的伸缩尺寸    
  67.             //注意:    
  68.             //0.0表示收缩到没有    
  69.             //1.0表示正常无伸缩    
  70.             //值小于1.0表示收缩    
  71.             //值大于1.0表示放大    
  72.             //-----我这里1-4参数表明是起始图像大小不变,动画终止的时候图像被放大1.5倍    
  73.             //第五个参数pivotXType 为动画在X 轴相对于物件位置类型    
  74.             //第六个参数pivotXValue 为动画相对于物件的X 坐标的开始位置    
  75.             //第七个参数pivotXType 为动画在Y 轴相对于物件位置类型    
  76.             //第八个参数pivotYValue 为动画相对于物件的Y 坐标的开始位置    
  77.             //提示:位置类型有三种,每种效果大家自己尝试哈~这里偷下懒~    
  78.             //毕竟亲眼看到效果的区别才记忆深刻~    
  79.             //Animation.ABSOLUTE 、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT    
  80.             mScaleAnimation.setDuration(2000);    
  81.             this.startAnimation(mScaleAnimation);    
  82.         } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {//画面转换位置移动动画效果    
  83.             mTranslateAnimation = new TranslateAnimation(0, 100, 0, 100);    
  84.             //第一个参数fromXDelta为动画起始时X坐标上的移动位置    
  85.             //第二个参数toXDelta为动画结束时X坐标上的移动位置    
  86.             //第三个参数fromYDelta为动画起始时Y坐标上的移动位置    
  87.             //第四个参数toYDelta 为动画结束时Y 坐标上的移动位置    
  88.             mTranslateAnimation.setDuration(2000);    
  89.             this.startAnimation(mTranslateAnimation);    
  90.         } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {//画面转移旋转动画效果    
  91.             mRotateAnimation = new RotateAnimation(0.0f, 360.0f,     
  92.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);    
  93.             //第一个参数fromDegrees为动画起始时的旋转角度    
  94.             //第二个参数toDegrees 为动画旋转到的角度    
  95.             //第三个参数pivotXType 为动画在X 轴相对于物件位置类型    
  96.             //第四个参数pivotXValue 为动画相对于物件的X 坐标的开始位置    
  97.             //第五个参数pivotXType 为动画在Y 轴相对于物件位置类型    
  98.             //第六个参数pivotYValue 为动画相对于物件的Y 坐标的开始位置    
  99.             mRotateAnimation.setDuration(3000);    
  100.             this.startAnimation(mRotateAnimation);    
  101.         }    
  102.         return super.onKeyDown(keyCode, event);    
  103.     }    
  104. }  


补充:有童鞋说对三种相对位置不太理解,那么我简单说补充下:

//Animation.ABSOLUTE 相对位置是屏幕左上角,绝对位置! //Animation.RELATIVE_TO_SELF 相对位置是自身View;取值为0,是自身左上角,取值为1是自身的右下角; //Animation.RELATIVE_TO_PARENT 相对父类View的位置

当设定了位置类型之后,会让你传入X或者Y的值,这里的X,Y可以理解成为一个点坐标!比如是旋转动画,那么这个(X,Y)就是旋转中心点!


OK,对于Tween Animation下的每种动画效果的实例化的每个参数都解释的很详细了!其实动画的实现不光用代码可以实现,在xml中注册实现也是可以的,这里就不多写了,大家可以自己去尝试写一下,那么在view中我们播放一种特效动画,只要实例化其对象,然后设置下参数,然后startAnimation()就好了,步骤很简单,只是每个动画实例化的参数确有着千变万化的改法,这些我也没法子一一来给大家演示,大家可以自己改改参数看看实际的效果!当然对于每种动画我们不光有设置播放的时候,还有一些属性和方法可以调用,比如Animation.restart()重放动画,getTransformation()此方法返回假,说明动画完成等等很多属性,请各位童鞋自定实验 o(∩_∩)o 哈哈~

 

顺便先解释下MyViewAnimation .java 类中onDraw()方法里的(备注1)!其实这里我是想跟大家说明下Android Animation实现机制

                                                 【启动任意一种动画效果之前 和 之后 的对比图】

 

            

 

很明显、"Himi"字样在动画开始前和开始后出现了移动,而且在MyViewAnimation.java中我没有使用Runnable接口,也没有调用刷新的函数,那么我来给各位童鞋解释下原因:

 

  动画的每种变换其实内部都是一次矩阵运算。在Android 中,Canvas 类中包含当前矩阵,当调用 Canvas.drawBitmap (bmp, x, y, Paint) 绘制时,android 会先把 bmp 做一次矩阵运算,然后将运算的结果显示在 Canvas 上,然后不断修改 Canvas 的矩阵并刷新屏幕,View 里的对象就会不停的做图形变换,动画就形成了。

 

还有一点提醒大家:动画的播放是对整个游戏画布进行的操作,这一点要知道哟~

 

那么下面就要给大家介绍如何在我们的SurfaceView中运用Tween Animation!


 

MySurfaceViewAnimation.java 

view plain·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package com.himi.frameAnimation;  
  2. import android.content.Context;  
  3. import android.graphics.Bitmap;  
  4. import android.graphics.BitmapFactory;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;   
  7. import android.graphics.Paint;   
  8. import android.util.Log;  
  9. import android.view.KeyEvent;  
  10. import android.view.SurfaceHolder;  
  11. import android.view.SurfaceView;  
  12. import android.view.SurfaceHolder.Callback;  
  13. import android.view.animation.AlphaAnimation;  
  14. import android.view.animation.Animation;  
  15. import android.view.animation.RotateAnimation;  
  16. import android.view.animation.ScaleAnimation;   
  17. import android.view.animation.TranslateAnimation;  
  18. /** 
  19.  *@author Himi 
  20.  */  
  21. public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {  
  22.     private Thread th = new Thread(this);  
  23.     private SurfaceHolder sfh;  
  24.     private Canvas canvas;  
  25.     private Paint paint;  
  26.     private Bitmap bmp;  
  27.     ///   
  28. private Animation mAlphaAnimation;  
  29. private Animation mScaleAnimation;  
  30. private Animation mTranslateAnimation;  
  31. private Animation mRotateAnimation;  
  32. public MySurfaceViewAnimation(Context context) {  
  33.     super(context);  
  34.     Log.v("Himi", "MySurfaceView");  
  35.     this.setKeepScreenOn(true);  
  36.     bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);  
  37.     sfh = this.getHolder();  
  38.     sfh.addCallback(this);  
  39.     paint = new Paint();  
  40.     paint.setAntiAlias(true);  
  41.     setFocusable(true);  
  42.     setFocusableInTouchMode(true);  
  43. //  this.setBackgroundResource(R.drawable.icon);//备注2  
  44. }  
  45. public void surfaceCreated(SurfaceHolder holder) {  
  46.     Log.v("Himi", "surfaceCreated");  
  47.     th.start();  
  48. }  
  49. public void draw() {  
  50.     try {  
  51.         canvas = sfh.lockCanvas();  
  52.         if (canvas != null) {  
  53.             canvas.drawColor(Color.BLACK);  
  54.             paint.setColor(Color.WHITE);  
  55.             canvas.drawText("方向键↑ 渐变透明度动画效果", 80, this.getHeight() - 80, paint);  
  56.             canvas.drawText("方向键↓ 渐变尺寸伸缩动画效果", 80, this.getHeight() - 60, paint);  
  57.             canvas.drawText("方向键← 画面转换位置移动动画效果", 80, this.getHeight() - 40, paint);  
  58.             canvas.drawText("方向键→ 画面转移旋转动画效果", 80, this.getHeight() - 20, paint);  
  59.             canvas.drawBitmap(bmp, this.getWidth() / 2 - bmp.getWidth() / 2,   
  60.                     this.getHeight() / 2 - bmp.getHeight() / 2, paint);  
  61.         }  
  62.     } catch (Exception e) {  
  63.         Log.v("Himi", "draw is Error!");  
  64.     } finally {  
  65.         sfh.unlockCanvasAndPost(canvas);  
  66.     }  
  67. }  
  68. @Override  
  69. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  70.     if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {//渐变透明度动画效果  
  71.         mAlphaAnimation = new AlphaAnimation(0.1f, 1.0f);  
  72.         mAlphaAnimation.setDuration(3000);  
  73.         this.startAnimation(mAlphaAnimation);  
  74.     } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {//渐变尺寸伸缩动画效果  
  75.         mScaleAnimation = new ScaleAnimation(0.0f, 2.0f,   
  76.                 1.5f, 1.5f, Animation.RELATIVE_TO_PARENT,   
  77.                 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f);  
  78.         mScaleAnimation.setDuration(2000);  
  79.         this.startAnimation(mScaleAnimation);  
  80.     } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {//画面转换位置移动动画效果  
  81.         mTranslateAnimation = new TranslateAnimation(0, 100, 0, 100);  
  82.         mTranslateAnimation.setDuration(2000);  
  83.         this.startAnimation(mTranslateAnimation);  
  84.     } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {//画面转移旋转动画效果  
  85.         mRotateAnimation = new RotateAnimation(0.0f, 360.0f,   
  86.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);  
  87.         mRotateAnimation.setDuration(3000);  
  88.         this.startAnimation(mRotateAnimation);  
  89.     }  
  90.     return super.onKeyDown(keyCode, event);  
  91. }  
  92. public void run() {  
  93.     // TODO Auto-generated method stub  
  94.     while (true) {  
  95.         draw();  
  96.         try {  
  97.             Thread.sleep(100);  
  98.         } catch (Exception ex) {  
  99.         }  
  100.     }  
  101. }  
  102. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  103.     Log.v("Himi", "surfaceChanged");  
  104. }  
  105. public void surfaceDestroyed(SurfaceHolder holder) {  
  106.     Log.v("Himi", "surfaceDestroyed");  
  107.     }  
  108. }  

 

  动画代码实现跟View中的做法一样,运行模拟器发现按键没效果,不是按键没触发是本来就存在问题, - -。但是!大家可以把此类里有一行,也就是(备注2)的注释打开,我们给设置背景图,然后在模拟器上的运行效果如下图:

 

                                       

 

很明显的看到,我们的动画正常运行了,虽然效果并不是我们想到的!但是这里可以说明一点问题:

                                                SurfaceView 本身具备双缓冲机制!!!!!

      有些文章里说“给SurfaceView添加双缓冲”,其实是在画蛇添足 - -,而且介绍的时候拿着单线程与双线程例子来解释双缓冲更高效的实现方法;我想弱弱的问什么是双缓冲??? 如果SurfaceView不具备双缓冲,那敢问上面这张截图如何解释????

      其实要实现双缓冲,只需要是新建一个Bitmap和Canvas,用这个新建的Canvas把正弦波画到新建的Bitmap,画完再通过sfh.lockCanvas获取SurfaceView对应的Canvas,用这个Canvas把新建的Bitmap画到SurfaceView上去,这才叫双缓冲; 还有双缓存和多线程没关系!

 

 那么View中动画的实现机制是在不断的刷屏不断的重复调用重写的onDraw()方法、而在Surfaceview的那张截图确实也正常的动画操作了,原因又何在?而且我们设置的背景图覆盖我们draw出来的字体!!效果很不理想;那么经过考虑我决定利用布局把View和SurfaceView都一并显示,用View主要去完成动画部分,(那么关于如何一并显示,或者说同时在SurfaceView中添加组件,在之前的【Android 2D开发之六】 和 【Android 2D开发之七】都有了详细讲解,那么在这里),当然一并显示也会有问题,比如我们存在了view和Surfaceiew,那么按键的时候触发的哪个?或者说如何去控制这两个View?放心,我下面就跟大家一一来讲解!

   

下面先让我们把我们的view 和 Surfaceview 先同时显示出来:【黑色的是MyView (View),白色是MySurfaceView(SurfaceView)

 

                                                        先上张运行截图:  (图4)


                                

 

main.xml中的代码

view plain·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1.   
  2.     android:orientation="vertical"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     >   
  6.     
  7.             android:layout_width="fill_parent"  
  8.             android:layout_height="wrap_content"  
  9.             android:layout_weight="1" >  
  10.        
  11.             android:layout_width="fill_parent"  
  12.             android:layout_height="fill_parent"/>     
  13.     
  14.             android:layout_width="fill_parent"  
  15.             android:layout_height="fill_parent"/>     
  16.          
  17.   

xml中我们注册了我们自定义的view-MyView 和 SurfaceView-MySurfaceView;

需要强调的有两点:

1 : 当我们xml中注册我们的View时,我们View类中的构造函数必须要用

      public MyView(Context context, AttributeSet attrs) {} 两个参数的形式,以前的文章有讲解。

 

2 : 当我们在Xml中注册两个View的时候,它们显示的次序就是根据xml注册的顺序来显示,比如上面我们先注册了MySurfaceView,然后注册的MyView ,那么显示的时候会把后添加进去的MyView显示在最上层!

 

下面我们来看MySurfaceView.java中的代码:

 

view plain·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package com.himi;  
  2. import android.content.Context;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Color;  
  5. import android.graphics.Paint;  
  6. import android.util.AttributeSet;  
  7. import android.view.KeyEvent;   
  8. import android.view.SurfaceHolder;  
  9. import android.view.SurfaceView;   
  10. import android.view.SurfaceHolder.Callback;    
  11. /** 
  12.  *  
  13.  * @author Himi 
  14.  * 
  15.  */  
  16. public class MySurfaceView extends SurfaceView implements Callback, Runnable {  
  17.     public static MySurfaceView msrv ;//----备注1  
  18.     private int move_x = 2, x = 20;  
  19.     private Thread th;  
  20.     private SurfaceHolder sfh;  
  21.     private Canvas canvas;  
  22.     private Paint p;   
  23.     public MySurfaceView(Context context, AttributeSet attrs) {   
  24.         super(context, attrs);  
  25.         msrv=this;  
  26.         p = new Paint();   
  27.         p.setAntiAlias(true);  
  28.         sfh = this.getHolder();  
  29.         sfh.addCallback(this);  
  30.         th = new Thread(this);  
  31.         this.setKeepScreenOn(true);   
  32.          this.setFocusable(true);// ----备注2  
  33.     }   
  34.     public void surfaceCreated(SurfaceHolder holder) {  
  35.         th.start();   
  36.     }   
  37.     public void draw() {  
  38.         canvas = sfh.lockCanvas();  
  39.         if(canvas!=null){  
  40.             canvas.drawColor(Color.WHITE);  
  41.             canvas.drawText("我是   - Surfaceview", x + move_x, 280, p);  
  42.             sfh.unlockCanvasAndPost(canvas);  
  43.         }   
  44.     }  
  45.     private void logic() {    
  46.         x += move_x;  
  47.         if (x > 200 || x < 80) {  
  48.             move_x = -move_x;  
  49.         }  
  50.     }  
  51.     @Override  
  52.     public boolean onKeyDown(int key, KeyEvent event) { //备注2  
  53.         return super.onKeyDown(key, event);  
  54.     }   
  55.        
  56.     public void run() {  
  57.         // TODO Auto-generated method stub  
  58.         while (true) {  
  59.             draw();  
  60.             logic();  
  61.             try {  
  62.                 Thread.sleep(100);  
  63.             } catch (Exception ex) {  
  64.             }  
  65.         }  
  66.     }    
  67.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  68.             int height) {   
  69.     }   
  70.     public void surfaceDestroyed(SurfaceHolder holder) {   
  71.     }  
  72. }  

 

代码都很熟悉了, 主要我们来给大家解释下备注1,备注2:

备注1:

   我在两个MyView 和 MySurfaceView中都定义了本类一个静态对象,然后在初始化的时候都利用=this的形式进行了实例化;

注意:=this; 的这种实例形式要注意!只能在当前程序中仅存在一个本类对象才可使用!

       为什么要实例两个View的实例而且定义成静态,这样做主要为了类之间方便调用和操作!比如在我们这个项目中,我这样做是为了在MainActivity中去管理两个View按键焦点!下面我会给出MainActivity的代码,大家一看便知;

 

备注2:   

 我在两个MyView 和 MySurfaceView中都对获取按键焦点注释掉了,而是在别的类中的调用其View的静态实例对象就可以任意类中对其设置!这样就可以很容易去控制到底谁来响应按键了。

 

这里还要强调一下:当xml中注册多个 View的时候,当我们点击按键之后,Android会先判定哪个View setFocusable(true)设置焦点了,如果都设置了,那么Android 会默认响应在xml中第一个注册的view ,而不是两个都会响应。那么为什么不同时响应呢?我解释下:

上面这截图是Android SDK Api的树状图,很明显SurfaceView继承了View,它俩是基继承关系,那么不管是子类还是基类一旦响应了按键,其基类或者父类就不会再去响应;

 

下面我们来看MainActivity.java:

 

view plain·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package com.himi;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;   
  4. import android.view.KeyEvent;  
  5. import android.view.Window;  
  6. import android.view.WindowManager;  
  7. /** 
  8.  *  
  9.  * @author Himi 
  10.  * 
  11.  */  
  12. public class MainActivity extends Activity {  
  13.     /** Called when the activity is first created. */   
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
  18.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  19.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  20.         setContentView(R.layout.main);   
  21.         MySurfaceView.msrv.setFocusable(false);//备注1  
  22.         MyView.mv.setFocusable(true);//备注1  
  23.     }  
  24.     @Override  
  25.     public boolean onKeyDown(int keyCode, KeyEvent event) {//备注2  
  26.         return super.onKeyDown(keyCode, event);  
  27.     }  
  28.       
  29. }  

 

备注1:

   这里是当程序运行的时候我们默认让我们的MyView(View)来响应按键。通过类名调用对应的View实例,然后设置获取焦点的函数;

备注2:

    这里要注意:不管你在xml中注册了多少个View ,也不管View是否都设置了获取焦点,只要你在 MainActivity 中重写onKeyDown()函数,Android 就会调用此函数。

 

那么直接在SurfaceView中进行实现动画的想法这里没有得到很好的解决,而是我利用布局的方式来一同显示的方式,希望各位童鞋如果有好的方法,在SurfaceView中直接能使用动画的建议和想法,希望留言给我,大家一起学习 讨论,谢谢 下面给出项目源码:

 

源码下载地址:http://download.csdn.net/source/2969602


分享到: 查看评论
32楼 yq135314 2011-11-22 21:17发表 [回复]
楼主,有些地方不明白,双缓冲是否可以这么理解,相当于有两块画布,一块用来做准备,一块用来做显示,当准备的画布没有准备好时,显示画布也用不了该图片,该例子中把“备注2”去掉后就可以了,不明白设置View背景与动画有什么关系??
31楼 XL_tang 2011-11-14 16:24发表 [回复]
晕,看标题本来以为是在surfaceview自己实现的动画效果,一看变成了view怎么用tween动画的教程~~~
30楼 weixiaojulebu 2011-10-08 16:25发表 [回复]
例子在没有键盘的机器用不了
29楼 p569354158 2011-10-07 23:14发表 [回复]
今天实现PPT里的层叠效果时,屏幕闪的厉害,用surfaceview的刷新率设在多少好呢
28楼 c38funuk 2011-09-16 14:44发表 [回复]
如果不用animation,如何在surfaceview中实现透明化呢?
27楼 jakend 2011-08-26 10:32发表 [回复]
貌似类似 android应用开发揭秘里面的案例啊~~~
26楼 DUANLESINIAN 2011-08-23 11:05发表 [回复]
不知道是不是我没有理解楼主的意思~你不是说做游戏用surfaceView吗?然后这里为什么用view来做动画,那在以后的开发中,都是这样吗?请楼主帮我解疑一下~谢了!!!
Re: xiaominghimi 2011-08-23 17:28发表 [回复]
回复DUANLESINIAN:因为动画是在view下才能正常使用的。而一般游戏中动画都是自己去实现的
Re: DUANLESINIAN 2011-08-23 21:06发表 [回复]
回复xiaominghimi:楼主你的意思是Animation 在 SurfaceView 不好用,只能用在View里面,而在SurfaceView的动画,就靠自己去写代码了~是这个意思么??
Re: xiaominghimi 2011-08-24 03:19发表 [回复]
回复DUANLESINIAN:animation不易于控制;不管在view下还是surface view都尽可能自己去实现动画效果,因为系统提供的这个animation对于游戏开发来说基本无视;没啥好的效果;
Re: DUANLESINIAN 2011-08-23 20:37发表 [回复]
回复xiaominghimi:对了!楼主,问一下!我是刚学android的,准备做个游戏~但是总感觉android模拟器很卡~这样对游戏的测试岂不是问题很大??
Re: xiaominghimi 2011-08-24 03:17发表 [回复]
回复DUANLESINIAN:模拟器跟电脑硬件配置有关,一般win系统下2G内存比较卡,4G的也不会很流畅。不过在我的mac pro运行模拟器偏快。。。。。主要还是看真机的效果
Re: DUANLESINIAN 2011-08-24 10:17发表 [回复]
回复xiaominghimi:哈哈!太感谢楼主了!!大好人啊~~一直顶你!!!向你学习……
25楼 ZYW2011 2011-08-20 11:06发表 [回复]
你好,谢谢,非常好!我是一个初学者,现在想在AP中同时使用两个surfaceview,但不知道如何操作,还希望大师能指点一二,谢谢!
Re: xiaominghimi 2011-08-24 10:29发表 [回复]
回复ZYW2011:你的surface view都会在主的activity中利用setContentView(View view)中显示,你不管多少个 只要这里把你想用的 surface view更换上就好啦
24楼 gujinf2008 2011-08-04 15:14发表 [回复]
我还有另外一个不明白的,就是备注2是设置背景,俺我的理解就是,背景在最后面,draw函数里画的东西应该是画在背景上面的啊,怎么会被背景的图片遮住了呢,纠结啊。
Re: xiaominghimi 2011-08-04 16:16发表 [回复]
回复gujinf2008:就是因为双缓冲的缘故造成的,所谓双缓冲就是可以大致你理解为两个画布~
23楼 gujinf2008 2011-08-04 15:12发表 [回复]
如果SurfaceView不具备双缓冲,那敢问上面这张截图如何解释? 我也是看了这句感到很疑惑,也不知道什么是双缓冲,还特意去查了,也没明白楼主怎么能一看这张图就这样说,看了有人跟我一样的疑问,也看了楼主的解释,还是不怎么明白。如果像你回到的那样,两个画布,那是不是有一个画布是看不到的呢,就是内存中的那个,希望楼主再细解释解释,呵呵
22楼 cloverwinner 2011-08-02 17:18发表 [回复]
大哥,你给的源代码错的啊!
21楼 BIAOBIAOqi 2011-07-25 15:19发表 [回复]
另外,讨教一个问题。
我的SurfaceView 无法相应 KeyDownEvent .
View、Activity是可以的,我试过,但是在我的SurfaceView中却没有任何反映。
我看了这个贴,设置了 focus,但是还是不行。
不知到什么原因。求指导啊~~
Re: xiaominghimi 2011-07-25 21:17发表 [回复]
回复BIAOBIAOqi:有时见q我代码吧 肯定你代码写错了~你仔细看看你重写的方法名!
20楼 BIAOBIAOqi 2011-07-25 15:06发表 [回复]
先赞一下lz
不过lz对 SurfaceView双缓冲的解释似乎 有点问题哈。
前几天,凑巧经过了我的代码验证。我用一个变量记录了run()方法的执行次数,也就是我调用canvaslock绘图的次数,具体情况有点忘了,不过我记得某种情况下,画面的显示是一闪一闪的,似乎是由于我这边儿没有给它两个缓冲帧都读入图片的原因。
19楼 happy253650035 2011-05-12 14:19发表 [回复]
楼主大哥你好,小弟正在编一个android的益智类游戏,想在屏幕切换时实现淡入淡出效果,想想向楼主大哥请教一下如何实现啊!
18楼 arnold1989 2011-04-14 17:13发表 [回复]
楼主你好啊。。我想问您一个问题,就是我给imgview1和imgview2都添加了rotateAnimation,我一执行两个就一起转了。。。如何才能让imgview1转完imgview2再开始转呢。。。。非常感谢。。。
17楼 ttgart 2011-03-23 10:30发表 [回复]
楼主的文章让我受益良多,自己在开发的时候遇到个问题,想想楼主请教。
比如有个绘图方法刷新 sleep(100);
然后需要把这个刷的图保存为一张背景,用做另一个绘图的背景怎么实现啊。绘图的区块很大,大于canvas。
16楼 aa4790139 2011-03-08 00:21发表 [回复]
虽然是一个Activity中,同时显示了View和surfaceView,这种利用布局的方式确实没有达到我们想要的结果,等我试着去研究下,如果出来了就马上回..... 嘿嘿!
Re: xiaominghimi 2011-03-10 13:30发表 [回复]
回复 aa4790139:代码也可以实现,但是xml定义组件也要常用。
15楼 aa4790139 2011-03-07 15:58发表 [回复]
14楼 dh1314al 2011-02-24 16:29发表 [回复]
surfaceView的双缓存到底是什么,还是没有弄清楚!"如果SurfaceView不具备双缓冲,那敢问上面这张截图如何解释????"特别是这句话,把我弄糊涂了,为什么说那张背景图片能显示就说明surfaceView就有双缓存呢!博主指点一下,糊涂中。。。
Re: xiaominghimi 2011-03-10 13:30发表 [回复]
回复 dh1314al:双缓冲是游戏中常常用到的,为了避免绘制延迟导致屏幕闪烁的问题。一般如果屏幕不具备双缓冲,那么肯定就一个屏幕,但是有了双缓冲等同说是有个两个画布,不知道这样说能理解不~

    • 【李华明(Himi)—百度百科】
    • ▼Himi著作:《Android游戏编程之从零开始》—百度百科

    移动开发专家,专注于移动开发领域,多年 J2me、Android、iOS 平台游戏开发经验;

    CSDN、ITeye、51CTO、eoe-Android、泰然、中国移动开发者社区、微度网等多家技术论坛担任专家与版主;
    ★Himi技术交流QQ群★
    . 
    【Android】(高级群/超级群)
    Android 进阶①群:109367315
    Android 进阶②群:128410737
    Android 进阶③群:82911709
    Android 进阶④群:140352726
    Android 进阶⑤群:62867095
    【iOS】(高级群)
    Cocos2d-X: 190193804
    Cocos2d①群:190193003
    Cocos2d②群:192074417
    文章分类
  • 【 Android 游戏开发】(29)
  • 【—学习历程—】(1)
  • 【 iOS-Cocos2d 游戏开发】(25)
  • 【 iOS-Cocos2dX 游戏开发】(3)
  • 【Untiy3D 游戏开发】(1)
  • 【iOS、Object-C 语言随笔】(4)
  • 【 J2ME 3D 游戏开发】(3)
  • 【小记】(4)
    博客专栏
    iphone游戏开发专栏

    文章数:34篇

    阅读量:86402 Android游戏开发专栏

    文章数:29篇

    阅读量:217275
    Himi-腾讯微薄
    文章搜索
    最新评论
  • Himi浅谈3年游戏开发de自学历程!(仅供参考)【2011年11月9号_更新】

    trgree:@xiaominghimi:嗯,加油!!!我想请教下,如果没有美术功底,可不可以往游戏开发方面发展啊...

  • 【Android游戏开发之四】Android 游戏框架(一个游戏角色在屏幕行走的demo)

    sdmjhca:为什么我的在 R.drawable.enemy1这里报错,无法运行,求高人指点As of ADT 1...

  • 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!

    xp616316595:你好,我按照你这个代码写的IAP,就是在请求产品信息后,回调函数productsRequest一直都...

  • ▁▂▃ 【2011-9-22日前Himi所有博文锦集-CHM文档】+【Android和Cocos2d-iphone游戏开发系列博文以及源码,免费提供打包下载】▃▂▁

    wangkai11777:bu cuo

  • Himi浅谈3年游戏开发de自学历程!(仅供参考)【2011年11月9号_更新】

    xiaominghimi:@hmhm7442:感谢支持;谢谢

  • Himi浅谈3年游戏开发de自学历程!(仅供参考)【2011年11月9号_更新】

    hmhm7442:真心佩服,本来很忙,还是一个个的回复

  • 【iOS-Cocos2d游戏开发之七】在cocos2d中添加/删除系统组件,并解决View设置透明会影响View中的其他组件的问题!【11月28日更新解决添加组件Cocos2d动画停止播放的BUG】

    redparty:先支持个,明天再看,himi辛苦了。吼吼睡。

  • 【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)!

    shally131:感谢博主的分享精神,学习了不少东西

  • 【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)!

    shally131:CCSpeed *speed =[CCSpeed actionWithAction:; 运行通过了,...

  • ▁▂▃ 【2011-9-22日前Himi所有博文锦集-CHM文档】+【Android和Cocos2d-iphone游戏开发系列博文以及源码,免费提供打包下载】▃▂▁

    z88266088:多谢博主无私奉献

    评论排行
  • Himi浅谈3年游戏开发de自学历程!(... (629)
  • 【Android游戏开发之一】设置全屏以... (72)
  • ▁▂▃ 【2011-9-22日前Himi... (63)
  • 【Android游戏开发之三】剖析 Su... (56)
  • 【Android游戏开发之四】Andro... (56)
  • 【Android游戏开发十四】深入Ani... (54)
  • 【Android游戏开发二十】物理游戏之... (49)
  • 【Android游戏开发之六】在Surf... (46)
  • 【Android游戏开发二十一】Andr... (40)
  • 【Android游戏开发十一】手把手让你... (39)
    阅读排行
  • Himi浅谈3年游戏开发de自学历程!(... (36065)
  • 【Android游戏开发之一】设置全屏以... (16594)
  • 【Iphone 游戏开发】游戏引擎剖析 (15051)
  • 【Android游戏开发之四】Andro... (12972)
  • 【Android游戏开发十一】手把手让你... (12919)
  • 【Android游戏开发之三】剖析 Su... (10817)
  • 【Android游戏开发二十】物理游戏之... (10524)
  • 【Android游戏开发之二】剖析游戏开... (10463)
  • 【Android游戏开发二十一】Andr... (10358)
  • 【Android游戏开发十四】深入Ani... (9866)