基于OPhone 2.0的2D动画实践(三)


 本系列文章主要介绍了OPhone 2.0 SDK提供的两种实现2D动画的方式:帧动画和补间动画。文章的每个知识点都提供了精彩的实例以向读者展示2D动画的具体实现方法。通过对本系列文章的学习,读者可利用2D动画实现非常绚丽的界面效果。

相关阅读:

基于OPhone 2.0的2D动画实践(一)

基于OPhone 2.0的2D动画实践(二)

基于OPhone 2.0的2D动画实践(三)

  旋转补间动画
  通过<rotate>标签可以定义旋转补间动画。下面的代码定义了一个标准的旋转补间动画。
 

 
  1. <rotate xmlns:Android="http://schemas.android.com/apk/res/android"   android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"   android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"   android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>  
 其中<rotate>标签有两个特殊的属性。它们的含义如下:
   android:fromDegrees:表示旋转的起始角度。
   android:toDegrees:表示旋转的结束角度。
  在<rotate>标签中还使用如下两个属性设置旋转的次数和模式。
   android:repeatCount:设置旋转的次数。该属性需要设置一个整数值。如果该值为0,表示不重复显示动画。也就是说,对于上面的旋转补间动画,只从0度旋转到360度,动画就会停止。如果属性值大于0,动画会再次显示该属性指定的次数。例如,如果android:repeatCount属性值为1。动画除了正常显示一次外,还会再显示一次。也就是说,前面的旋转补间动画会顺时针自转两周。如果想让补间动画永不停止,可以将android:repeatCount属性值设为"infinite"或-1。该属性的默认值是0。
   android:repeatMode:设置重复的模式。默认值是restart。该属性只有当android:repeatCount设置成大于0的数或infinite才起作用。android:repeatMode属性值除了可以是restart外,还可以设为reverse,表示偶数次显示动画时会做与动画文件定义的方向相反的动作。例如,上面定义的旋转补间动画会在第1、3、5、...、2n - 1圈顺时针旋转,而在2、4、6、...、2n圈逆时针旋转。如果想使用Java代码来设置该属性,可以使用Animation类的setRepeatMode方法。该方法只接收一个int类型参数。可取的值是Animation.RESTART和Animation.REVERSE。
  如果想通过Java代码实现旋转补间动画,可以创建android.view.animation.RotateAnimation对象。RotateAnimation类构造方法的定义如下:   
  1. public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY);  

  通过RotateAnimation类的构造方法可以设置旋转开始角度(fromDegrees)、旋转结束角度(toDegrees)、旋转支点横坐标(pivotX)和旋转支点纵坐标(pivotY)。


  旋转补间动画实例
  本例实现了两颗行星绕着一颗恒星旋转的效果。其中恒星会顺时针和逆时针交替旋转(android:repeatMode属性值为reverse)。效果如图1所示。

  图1  旋转的星系
 

  两颗行星和一颗恒星分别对应于一个动画文件。行星对应的两个动画文件的内容如下:

 
  1. hesper.xml   
  2.   <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.   android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"  
  4.   android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"  
  5.   android:duration="5000" android:repeatMode="restart" android:repeatCount="infinite"/>  

 

 
  1. earth.xml   
  2.   <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.   android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"  
  4.   android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"  
  5.   android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>  
  恒星对应的动画文件的内容如下:  
  1. sun.xml   
  2.   <rotate xmlns:android="http://schemas.android.com/apk/res/android"  
  3.   android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"  
  4.   android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"  
  5.   android:duration="20000" android:repeatMode="reverse" android:repeatCount="infinite"/>  
 本例的主程序相对简单,只需要装载这3个动画文件,并开始动画即可,代码如下:
   
  1. package net.blogjava.mobile;   
  2.   
  3.   import android.app.Activity;   
  4.   import android.os.Bundle;   
  5.   import android.view.animation.Animation;   
  6.   import android.view.animation.AnimationUtils;   
  7.   import android.widget.ImageView;   
  8.   
  9.   public class Main extends Activity   
  10.   {   
  11.   @Override  
  12.   public void onCreate(Bundle savedInstanceState)   
  13.   {   
  14.   super.onCreate(savedInstanceState);   
  15.   setContentView(R.layout.main);   
  16.   ImageView ivEarth = (ImageView) findViewById(R.id.ivEarth);   
  17.   ImageView ivHesper = (ImageView) findViewById(R.id.ivHesper);   
  18.   ImageView ivSun = (ImageView) findViewById(R.id.ivSun);   
  19.   Animation earthAnimation = AnimationUtils.loadAnimation(this,R.anim.earth);   
  20.   Animation hesperAnimation = AnimationUtils.loadAnimation(this,R.anim.hesper);   
  21.   Animation sunAnimation = AnimationUtils.loadAnimation(this, R.anim.sun);   
  22.   ivEarth.startAnimation(earthAnimation);   
  23.   ivHesper.startAnimation(hesperAnimation);   
  24.   ivSun.startAnimation(sunAnimation);   
  25.   }   
  26.   }  

  透明度补间动画
  通过<alpha>标签可以定义透明度补间动画。下面的代码定义了一个标准的透明度补间动画。

 
  1. <alpha xmlns:android="http://schemas.android.com/apk/res/android"  
  2.       android:interpolator="@android:anim/accelerate_interpolator"  
  3.   android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="2000" />  
其中android:fromAlpha和android:toAlpha属性分别表示起始透明度和结束透明度。这两个属性的值都在0.0和1.0之间。属性值为0.0表示完全透明,属性值为1.0表示完全不透明。
  如果想通过Java代码实现透明度补间动画,可以创建android.view.animation.AlphaAnimation对象。AlphaAnimation类构造方法的定义如下:
  1. public AlphaAnimation(float fromAlpha, float toAlpha);  
通过AlphaAnimation类的构造方法可以设置起始透明度(fromAlpha)和结束透明度(toAlpha)


  透明度补间动画实例
  本例将前面介绍的多种动画效果进行结合实现了投掷炸弹,并爆炸的特效。在本例中采用的动画类型有帧动画、移动补间动画、缩放补间动画和透明度补间动画。
  其中使用了帧动画播放了一个爆炸的GIF动画;使用移动补间动画实现了炸弹被投下仍然会向前移动的偏移效果;缩放补间动画实现了当炸弹被投下时逐渐缩小的效果。透明度补间动画实现了炸弹被投下时逐渐模糊的效果。当运行本例后,会在屏幕下方正中间显示一个炸弹,如图2所示。然后触摸这个炸弹,炸弹开始投掷,逐渐变小和模糊,如图3所示。当炸弹变得很小、很模糊时,会播放GIF动画来显示爆炸效果,并播放爆炸的声音。如图4所示。

  图2  初始状态的炸弹

   

  图3 炸弹逐渐变小和模糊

  图4  炸弹爆炸的效果
 

  本例的实现代码如下: 

 
  1. package net.blogjava.mobile;   
  2.   
  3.   import android.app.Activity;   
  4.   import android.graphics.drawable.AnimationDrawable;   
  5.   import android.media.MediaPlayer;   
  6.   import android.os.Bundle;   
  7.   import android.view.MotionEvent;   
  8.   import android.view.View;   
  9.   import android.view.View.OnTouchListener;   
  10.   import android.view.animation.Animation;   
  11.   import android.view.animation.AnimationUtils;   
  12.   import android.view.animation.Animation.AnimationListener;   
  13.   import android.widget.ImageView;   
  14.   
  15.   public class Main extends Activity implements OnTouchListener,AnimationListener   
  16.   {   
  17.   private ImageView ivMissile;   
  18.   private MyImageView ivBlast;   
  19.   private AnimationDrawable animationDrawable;   
  20.   private Animation missileAnimation;   
  21.   @Override  
  22.   public boolean onTouch(View view, MotionEvent event)   
  23.   {   
  24.   //  触摸炸弹后,开始播放动画   
  25.   ivMissile.startAnimation(missileAnimation);   
  26.   return false;   
  27.   }   
  28.   @Override  
  29.   public void onAnimationEnd(Animation animation)   
  30.   {   
  31.   //  在播放投掷炸弹动画结束后,显示MyImageView组件,并将显示炸弹的ImageView组件隐藏   
  32.   ivBlast.setVisibility(View.VISIBLE);   
  33.   ivMissile.setVisibility(View.INVISIBLE);   
  34.   try  
  35.   {   
  36.   //  开始播放爆炸的声音   
  37.   MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bomb);   
  38.   mediaPlayer.stop();   
  39.   mediaPlayer.prepare();   
  40.   mediaPlayer.start();   
  41.   }   
  42.   catch (Exception e)   
  43.   {           
  44.   }   
  45.   animationDrawable.stop();   
  46.   //  播放爆炸效果动画   
  47.   animationDrawable.start();   
  48.   }   
  49.   @Override  
  50.   public void onAnimationRepeat(Animation animation)   
  51.   {   
  52.   }   
  53.   @Override  
  54.   public void onAnimationStart(Animation animation)   
  55.   {   
  56.   }   
  57.   @Override  
  58.   public void onCreate(Bundle savedInstanceState)   
  59.   {   
  60.   super.onCreate(savedInstanceState);   
  61.   setContentView(R.layout.main);   
  62.   ivMissile = (ImageView) findViewById(R.id.ivMissile);   
  63.   ivMissile.setOnTouchListener(this);   
  64.   ivBlast = (MyImageView) findViewById(R.id.ivBlast);   
  65.   ivBlast.setBackgroundResource(R.anim.blast);   
  66.   Object backgroundObject = ivBlast.getBackground();   
  67.   animationDrawable = (AnimationDrawable) backgroundObject;   
  68.   ivBlast.animationDrawable = animationDrawable;   
  69.   missileAnimation = AnimationUtils.loadAnimation(this, R.anim.missile);   
  70.   missileAnimation.setAnimationListener(this);   
  71.   //  在程序启动后,将显示爆炸效果的MyImageView组件隐藏   
  72.   ivBlast.setVisibility(View.INVISIBLE);   
  73.   ivBlast.ivMissile = ivMissile;   
  74.   }   
  75.   }  

  总结
  本文主要介绍了旋转补间动画和透明度补间动画。通过将四种补间动画结合使用,可以实现非常有趣的动画效果。

相关内容