推箱子游戏开发(1) surfaceView 实现动画效果

推箱子游戏开发(一) surfaceView 实现动画效果
SurfaceView是View的子类,常用于实现游戏中的动画效果。SurfaceView最大的特点就是:从主线程中,把具体的绘图线程独立出来。这样做的好处在于:当绘图任务比较繁重时,避免主线程的阻塞,从而提高主线程的反应速度。

        废话少说,言归正传,下面用几个例子说明surfaceview的使用。

(一) 基本功能:用SurfaceView显示一副背景图片。 运行后的效果很简单,就是在屏幕上显示一副图片。 推箱子游戏开发(1) surfaceView 实现动画效果

[java] view plaincopyprint?
  1. package com.pushBox; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.Context; 
  5. import android.graphics.Bitmap; 
  6. import android.graphics.BitmapFactory; 
  7. import android.graphics.Canvas; 
  8. import android.os.Bundle; 
  9. import android.view.SurfaceHolder; 
  10. import android.view.SurfaceView; 
  11.  
  12. public class PushBoxActivity extends Activity { 
  13.     //欢迎界面 
  14.     WelcomeView welcomeView = null;  
  15.      
  16.     /** Called when the activity is first created. */ 
  17.     @Override 
  18.     public void onCreate(Bundle savedInstanceState) { 
  19.         super.onCreate(savedInstanceState); 
  20.          
  21.         //显示欢迎界面 
  22.         welcomeView = new WelcomeView( this );         
  23.         setContentView( welcomeView );  
  24.     } 
  25.      
  26.     //内部类,欢迎界面 
  27.     class WelcomeView extends SurfaceView implements SurfaceHolder.Callback 
  28.     { 
  29.         private SurfaceHolder holder;     
  30.         private WelcomeViewDrawThread welcomeViewDrawThread; 
  31.         //背景图片,大小640 * 480 
  32.         Bitmap background; 
  33.          
  34.         //图片显示的位置 
  35.         int backgroundX = 0
  36.         int backgroundY = 0
  37.          
  38.         public WelcomeView( Context context ) 
  39.         { 
  40.             super( context );            
  41.             holder = this.getHolder(); 
  42.             holder.addCallback( this );          
  43.             background = BitmapFactory.decodeResource( getResources(), R.drawable.background ); 
  44.             //创建一个绘图线程 
  45.             welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder ); 
  46.         } 
  47.          
  48.         //自定义的绘图函数,具体的绘图在这里完成 
  49.         public void onDraw( Canvas c ) 
  50.         { 
  51.             c.drawBitmap( background, backgroundX, backgroundY, null );          
  52.         } 
  53.          
  54.         @Override 
  55.         public void surfaceChanged(SurfaceHolder holder, int format, int width, 
  56.                 int height) { 
  57.             // TODO Auto-generated method stub           
  58.         } 
  59.         @Override 
  60.         public void surfaceCreated(SurfaceHolder holder) { 
  61.             // TODO Auto-generated method stub 
  62.             //启动绘图线程 
  63.             welcomeViewDrawThread.setFlag( true ); 
  64.             welcomeViewDrawThread.start(); 
  65.         } 
  66.         @Override 
  67.         public void surfaceDestroyed(SurfaceHolder holder) { 
  68.             // TODO Auto-generated method stub 
  69.             welcomeViewDrawThread.setFlag( false ); 
  70.         } 
  71.     }     
  72.          
  73.     //内部类,欢迎界面的绘图线程 
  74.     class WelcomeViewDrawThread extends Thread 
  75.     { 
  76.         private WelcomeView welcomeView; 
  77.         private SurfaceHolder holder; 
  78.         private boolean isRun;   
  79.         private int sleepSpan = 200
  80.          
  81.         public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder ) 
  82.         { 
  83.             this.welcomeView = welcomeView; 
  84.             this.holder = holder; 
  85.             isRun = true
  86.         } 
  87.         public void setFlag( boolean flag ) 
  88.         { 
  89.             isRun = flag; 
  90.         } 
  91.  
  92.         @Override 
  93.         public void run() { 
  94.             // TODO Auto-generated method stub 
  95.             while( isRun ) 
  96.             { 
  97.                 Canvas c = null
  98.                 try 
  99.                 { 
  100.                     c = holder.lockCanvas(); 
  101.                     synchronized( holder ) 
  102.                     { 
  103.                         //调用绘图函数 
  104.                         welcomeView.onDraw( c );                         
  105.                     } 
  106.                 }finally 
  107.                 { 
  108.                     if( c != null
  109.                     { 
  110.                         holder.unlockCanvasAndPost( c ); 
  111.                     } 
  112.                 } 
  113.                  
  114.                 try
  115.                     //睡眠200毫秒 
  116.                     Thread.sleep( sleepSpan ); 
  117.                 } 
  118.                 catch(Exception e){ 
  119.                     e.printStackTrace(); 
  120.                 } 
  121.             } 
  122.         }        
  123.     } 


(二) 初露锋芒:用SurfaceView显示一个动态打开的门。运行后的效果,左右两扇门缓缓打开。推箱子游戏开发(1) surfaceView 实现动画效果     推箱子游戏开发(1) surfaceView 实现动画效果

        如果只用SurfaceView显示一副背景图片,那绝对是“大炮打蚊子”------大材小用。从主线程中拉出一个单独的线程,就是为了处理动态效果。这里具体实现的时候有两个线程:welcomeViewGoThread和welcomeViewDrawThread。welcomeViewGoThread只负责修改图片显示的坐标,welcomeViewDrawThread负责在具体的位置显示图片。这种进一步分离,使得各模块的功能更加独立和明确。

[java] view plaincopyprint?
  1. package com.pushBox; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.Context; 
  5. import android.graphics.Bitmap; 
  6. import android.graphics.BitmapFactory; 
  7. import android.graphics.Canvas; 
  8. import android.os.Bundle; 
  9. import android.view.SurfaceHolder; 
  10. import android.view.SurfaceView; 
  11.  
  12. public class PushBoxActivity extends Activity { 
  13.     //欢迎界面 
  14.     WelcomeView welcomeView = null;  
  15.     //欢迎界面的动画线程 
  16.     WelcomeViewGoThread welcomeViewGoThread = null
  17.      
  18.     /** Called when the activity is first created. */ 
  19.     @Override 
  20.     public void onCreate(Bundle savedInstanceState) { 
  21.         super.onCreate(savedInstanceState); 
  22.          
  23.         //显示欢迎界面 
  24.         welcomeView = new WelcomeView( this );         
  25.         setContentView( welcomeView );  
  26.         welcomeViewGoThread = new WelcomeViewGoThread( welcomeView ); 
  27.         //启动动画线程 
  28.         welcomeViewGoThread.start(); 
  29.     } 
  30.      
  31.     //内部类,欢迎界面 
  32.     class WelcomeView extends SurfaceView implements SurfaceHolder.Callback 
  33.     { 
  34.         private SurfaceHolder holder;     
  35.         private WelcomeViewDrawThread welcomeViewDrawThread; 
  36.         //背景图片,大小640 * 480 
  37.         Bitmap background; 
  38.         //左边的木门,大小180 * 450 
  39.         Bitmap leftWood; 
  40.         Bitmap rightWood; 
  41.          
  42.         //图片显示的位置 
  43.         int backgroundX = 0
  44.         int backgroundY = 0
  45.         int leftWoodX = 10
  46.         int leftWoodY = 15
  47.         int rightWoodX = 150
  48.         int rightWoodY = 15
  49.          
  50.         public WelcomeView( Context context ) 
  51.         { 
  52.             super( context );            
  53.             holder = this.getHolder(); 
  54.             holder.addCallback( this );          
  55.             background = BitmapFactory.decodeResource( getResources(), R.drawable.background ); 
  56.             leftWood = BitmapFactory.decodeResource( getResources(), R.drawable.image33 ); 
  57.             rightWood = BitmapFactory.decodeResource( getResources(), R.drawable.image3 ); 
  58.              
  59.             //创建一个绘图线程 
  60.             welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder ); 
  61.         } 
  62.          
  63.         //自定义的绘图函数,具体的绘图在这里完成 
  64.         public void onDraw( Canvas c ) 
  65.         { 
  66.             c.drawBitmap( background, backgroundX, backgroundY, null );   
  67.             c.drawBitmap( leftWood, leftWoodX, leftWoodY, null );  
  68.             c.drawBitmap( rightWood, rightWoodX, rightWoodY, null );  
  69.         } 
  70.          
  71.         @Override 
  72.         public void surfaceChanged(SurfaceHolder holder, int format, int width, 
  73.                 int height) { 
  74.             // TODO Auto-generated method stub           
  75.         } 
  76.         @Override 
  77.         public void surfaceCreated(SurfaceHolder holder) { 
  78.             // TODO Auto-generated method stub 
  79.             //启动绘图线程 
  80.             welcomeViewDrawThread.setFlag( true ); 
  81.             welcomeViewDrawThread.start(); 
  82.         } 
  83.         @Override 
  84.         public void surfaceDestroyed(SurfaceHolder holder) { 
  85.             // TODO Auto-generated method stub 
  86.             welcomeViewDrawThread.setFlag( false ); 
  87.         } 
  88.     }  
  89.      
  90.     //内部类,欢迎界面的动画线程,只修改坐标,不负责具体显示 
  91.     class WelcomeViewGoThread extends Thread 
  92.     { 
  93.         private WelcomeView welcomeView; 
  94.         private int sleepSpan = 200
  95.         private boolean isRun; 
  96.          
  97.         public WelcomeViewGoThread( WelcomeView welcomeView ) 
  98.         { 
  99.             this.welcomeView = welcomeView; 
  100.             isRun = true
  101.         } 
  102.         public void setFlag( boolean flag ) 
  103.         { 
  104.             isRun = flag; 
  105.         } 
  106.          
  107.         @Override 
  108.         public void run() { 
  109.             // TODO Auto-generated method stub 
  110.             while( isRun ) 
  111.             { 
  112.                 // 修改木门坐标 
  113.                 welcomeView.leftWoodX -= 2
  114.                 welcomeView.rightWoodX += 2
  115.                 if( welcomeView.leftWoodX < -90
  116.                 { 
  117.                     welcomeView.leftWoodX = 10
  118.                     welcomeView.rightWoodX = 150
  119.                 }                
  120.                 try
  121.                     //睡眠200毫秒 
  122.                     Thread.sleep( sleepSpan ); 
  123.                 } 
  124.                 catch(Exception e){ 
  125.                     e.printStackTrace(); 
  126.                 } 
  127.             } 
  128.         }        
  129.     } 
  130.          
  131.     //内部类,欢迎界面的绘图线程 
  132.     class WelcomeViewDrawThread extends Thread 
  133.     { 
  134.         private WelcomeView welcomeView; 
  135.         private SurfaceHolder holder; 
  136.         private boolean isRun;   
  137.         private int sleepSpan = 200
  138.          
  139.         public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder ) 
  140.         { 
  141.             this.welcomeView = welcomeView; 
  142.             this.holder = holder; 
  143.             isRun = true
  144.         } 
  145.         public void setFlag( boolean flag ) 
  146.         { 
  147.             isRun = flag; 
  148.         } 
  149.  
  150.         @Override 
  151.         public void run() { 
  152.             // TODO Auto-generated method stub 
  153.             while( isRun ) 
  154.             { 
  155.                 Canvas c = null
  156.                 try 
  157.                 { 
  158.                     c = holder.lockCanvas(); 
  159.                     synchronized( holder ) 
  160.                     { 
  161.                         //调用绘图函数 
  162.                         welcomeView.onDraw( c );                         
  163.                     } 
  164.                 }finally 
  165.                 { 
  166.                     if( c != null
  167.                     { 
  168.                         holder.unlockCanvasAndPost( c ); 
  169.                     } 
  170.                 } 
  171.                  
  172.                 try
  173.                     //睡眠200毫秒 
  174.                     Thread.sleep( sleepSpan ); 
  175.                 } 
  176.                 catch(Exception e){ 
  177.                     e.printStackTrace(); 
  178.                 } 
  179.             } 
  180.         }        
  181.     } 

(三) 脱胎换骨:修改程序框架。

           上述的程序框架有问题,所有代码都放在一个文件里。下面要做的就是把相关的class都独立出来。代码改起来也很简单,只要把几个内部类单独写到一个文件即可。推箱子游戏开发(1) surfaceView 实现动画效果

(四) 重出江湖:用SurfaceView实现一个完整的欢迎界面

推箱子游戏开发(1) surfaceView 实现动画效果推箱子游戏开发(1) surfaceView 实现动画效果推箱子游戏开发(1) surfaceView 实现动画效果推箱子游戏开发(1) surfaceView 实现动画效果