歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 基於OPhone 2.0的2D動畫實踐(三)

基於OPhone 2.0的2D動畫實踐(三)

日期:2017/3/1 10:55:41   编辑:Linux編程

 本系列文章主要介紹了OPhone 2.0 SDK提供的兩種實現2D動畫的方式:幀動畫和補間動畫。文章的每個知識點都提供了精彩的實例以向讀者展示2D動畫的具體實現方法。通過對本系列文章的學習,讀者可利用2D動畫實現非常絢麗的界面效果。

相關閱讀:

基於OPhone 2.0的2D動畫實踐(一) http://www.linuxidc.com/Linux/2011-11/48125.htm

基於OPhone 2.0的2D動畫實踐(二) http://www.linuxidc.com/Linux/2011-11/48124.htm

基於OPhone 2.0的2D動畫實踐(三) http://www.linuxidc.com/Linux/2011-11/48126.htm

  旋轉補間動畫
  通過<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.   import android.app.Activity;
  3.   import android.os.Bundle;
  4.   import android.view.animation.Animation;
  5.   import android.view.animation.AnimationUtils;
  6.   import android.widget.ImageView;
  7.   public class Main extends Activity
  8.   {
  9.   @Override
  10.   public void onCreate(Bundle savedInstanceState)
  11.   {
  12.   super.onCreate(savedInstanceState);
  13.   setContentView(R.layout.main);
  14.   ImageView ivEarth = (ImageView) findViewById(R.id.ivEarth);
  15.   ImageView ivHesper = (ImageView) findViewById(R.id.ivHesper);
  16.   ImageView ivSun = (ImageView) findViewById(R.id.ivSun);
  17.   Animation earthAnimation = AnimationUtils.loadAnimation(this,R.anim.earth);
  18.   Animation hesperAnimation = AnimationUtils.loadAnimation(this,R.anim.hesper);
  19.   Animation sunAnimation = AnimationUtils.loadAnimation(this, R.anim.sun);
  20.   ivEarth.startAnimation(earthAnimation);
  21.   ivHesper.startAnimation(hesperAnimation);
  22.   ivSun.startAnimation(sunAnimation);
  23.   }
  24.   }

  透明度補間動畫
  通過<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.   import android.app.Activity;
  3.   import android.graphics.drawable.AnimationDrawable;
  4.   import android.media.MediaPlayer;
  5.   import android.os.Bundle;
  6.   import android.view.MotionEvent;
  7.   import android.view.View;
  8.   import android.view.View.OnTouchListener;
  9.   import android.view.animation.Animation;
  10.   import android.view.animation.AnimationUtils;
  11.   import android.view.animation.Animation.AnimationListener;
  12.   import android.widget.ImageView;
  13.   public class Main extends Activity implements OnTouchListener,AnimationListener
  14.   {
  15.   private ImageView ivMissile;
  16.   private MyImageView ivBlast;
  17.   private AnimationDrawable animationDrawable;
  18.   private Animation missileAnimation;
  19.   @Override
  20.   public boolean onTouch(View view, MotionEvent event)
  21.   {
  22.   // 觸摸炸彈後,開始播放動畫
  23.   ivMissile.startAnimation(missileAnimation);
  24.   return false;
  25.   }
  26.   @Override
  27.   public void onAnimationEnd(Animation animation)
  28.   {
  29.   // 在播放投擲炸彈動畫結束後,顯示MyImageView組件,並將顯示炸彈的ImageView組件隱藏
  30.   ivBlast.setVisibility(View.VISIBLE);
  31.   ivMissile.setVisibility(View.INVISIBLE);
  32.   try
  33.   {
  34.   // ���始播放爆炸的聲音
  35.   MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bomb);
  36.   mediaPlayer.stop();
  37.   mediaPlayer.prepare();
  38.   mediaPlayer.start();
  39.   }
  40.   catch (Exception e)
  41.   {
  42.   }
  43.   animationDrawable.stop();
  44.   // 播放爆炸效果動畫
  45.   animationDrawable.start();
  46.   }
  47.   @Override
  48.   public void onAnimationRepeat(Animation animation)
  49.   {
  50.   }
  51.   @Override
  52.   public void onAnimationStart(Animation animation)
  53.   {
  54.   }
  55.   @Override
  56.   public void onCreate(Bundle savedInstanceState)
  57.   {
  58.   super.onCreate(savedInstanceState);
  59.   setContentView(R.layout.main);
  60.   ivMissile = (ImageView) findViewById(R.id.ivMissile);
  61.   ivMissile.setOnTouchListener(this);
  62.   ivBlast = (MyImageView) findViewById(R.id.ivBlast);
  63.   ivBlast.setBackgroundResource(R.anim.blast);
  64.   Object backgroundObject = ivBlast.getBackground();
  65.   animationDrawable = (AnimationDrawable) backgroundObject;
  66.   ivBlast.animationDrawable = animationDrawable;
  67.   missileAnimation = AnimationUtils.loadAnimation(this, R.anim.missile);
  68.   missileAnimation.setAnimationListener(this);
  69.   // 在程序啟動後,將顯示爆炸效果的MyImageView組件隱藏
  70.   ivBlast.setVisibility(View.INVISIBLE);
  71.   ivBlast.ivMissile = ivMissile;
  72.   }
  73.   }

  總結
  本文主要介紹了旋轉補間動畫和透明度補間動畫。通過將四種補間動畫結合使用,可以實現非常有趣的動畫效果。

Copyright © Linux教程網 All Rights Reserved