且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

AndEngine引擎学习之绘制矩形Rectangle

更新时间:2022-09-27 14:09:38

   上一次我们通过Line类来绘制直线,这一次我们来绘制一下矩形并添加了触摸截屏的功能,参考AngineExamples的例子。AngineExamples的例子很全面,写得很不错,这里对其进行分析以及修改。

1、1、创建完android项目,引入AndEngine的项目类库。

主Activity继承SimpleBaseGameActivity:

 


  1. package com.xzw.drawrect; 
  2.  
  3. import org.andengine.engine.camera.Camera; 
  4. import org.andengine.engine.options.EngineOptions; 
  5. import org.andengine.engine.options.ScreenOrientation; 
  6. import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; 
  7. import org.andengine.entity.Entity; 
  8. import org.andengine.entity.primitive.Rectangle; 
  9. import org.andengine.entity.scene.IOnSceneTouchListener; 
  10. import org.andengine.entity.scene.Scene; 
  11. import org.andengine.entity.scene.background.Background; 
  12. import org.andengine.entity.util.FPSLogger; 
  13. import org.andengine.entity.util.ScreenCapture; 
  14. import org.andengine.entity.util.ScreenCapture.IScreenCaptureCallback; 
  15. import org.andengine.input.touch.TouchEvent; 
  16. import org.andengine.ui.activity.SimpleBaseGameActivity; 
  17. import org.andengine.util.FileUtils; 
  18.  
  19. import android.util.DisplayMetrics; 
  20. import android.util.Log; 
  21. import android.widget.Toast; 
  22.  
  23. /** 
  24.  *  
  25.  * @author xuzw13@gmail.com 
  26.  * weibo:http://weibo.com/xzw1989 
  27.  */ 
  28. public class MainActivity extends SimpleBaseGameActivity { 
  29.      
  30.     private static final String TAG = "MainActivity";  
  31.        
  32.     //设置屏幕的显示大小 
  33.     /*private static final int CAMERA_WIDTH = 720; 
  34.     private static final int CAMERA_HEIGHT = 480;*/ 
  35.      
  36.     private static  int camera_width = 720
  37.     private static  int camera_height = 480
  38.    
  39.      
  40.     /** 
  41.      * 创建引擎的选项(这里我的理解是初始化过程,和activity的onCreate一样) 
  42.      */ 
  43.     @Override 
  44.     public EngineOptions onCreateEngineOptions() { 
  45.         Log.i(TAG, "--onCreateEngineOptions()--"); 
  46.         //初始化屏幕显示区域的大小。 
  47.         setSceenDisplay(); 
  48.          
  49.         /** 
  50.          * 该类即我们常说的游戏摄像机,在AndEngine的Camera有两种作用, 
  51.          * 一是用以调节屏幕的显示区域,二是利用HUD类实际绘制游戏屏幕于手机之上。 
  52.          */ 
  53.         final Camera camera = new Camera(00, camera_width, camera_height); 
  54.          
  55.         return new EngineOptions(true,  
  56.                 ScreenOrientation.LANDSCAPE_FIXED,  
  57.                 new RatioResolutionPolicy(camera_width, camera_height), 
  58.                 camera); 
  59.     } 
  60.  
  61.     @Override 
  62.     protected void onCreateResources() {  
  63.         Log.i(TAG, "--onCreateResources()--"); 
  64.     } 
  65.     /** 
  66.      * 创建场景 
  67.      */ 
  68.     @Override 
  69.     protected Scene onCreateScene() { 
  70.         Log.i(TAG, "--onCreateScene()--"); 
  71.         this.mEngine.registerUpdateHandler(new FPSLogger()); 
  72.         /** 
  73.          * 场景容器,作用类似于LGame中的Screen, 
  74.          * 能够将某一特定场景作为游戏模块进行调用 
  75.          * ,我们可以利用它来切换当前游戏的画面与触摸屏监听, 
  76.          * 切换方法是利用Engine.setScene。 
  77.          */ 
  78.         final Scene scene = new Scene(); 
  79.         //截屏 
  80.         final ScreenCapture screenCapture = new ScreenCapture(); 
  81.          //加入截屏功能。 
  82.         scene.attachChild(screenCapture); 
  83.          
  84.         //场景触摸事件 
  85.         scene.setOnSceneTouchListener(new IOnSceneTouchListener() { 
  86.              
  87.             @Override 
  88.             public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) { 
  89.                  
  90.                 if(pSceneTouchEvent.isActionDown()){//屏幕点击的时候开始截屏 
  91.                   
  92.                     screenCapture.capture(18060360360, FileUtils.getAbsolutePathOnExternalStorage(MainActivity.this"Screen_"+System.currentTimeMillis()+".png"),  
  93.                             new IScreenCaptureCallback() { 
  94.                                  
  95.                                 public void onScreenCaptured(final String pFilePath) { 
  96.                                      MainActivity.this.runOnUiThread(new Runnable() { 
  97.                                          
  98.                                         @Override 
  99.                                         public void run() { 
  100.                                             Toast.makeText(MainActivity.this"Screenshot: " + pFilePath + " taken!", Toast.LENGTH_LONG).show(); 
  101.                                              
  102.                                         } 
  103.                                     }); 
  104.                                 } 
  105.                                   
  106.                                 public void onScreenCaptureFailed(final String pFilePath, Exception pException) { 
  107.                                      MainActivity.this.runOnUiThread(new Runnable() { 
  108.                                              
  109.                                             @Override 
  110.                                             public void run() { 
  111.                                                 Toast.makeText(MainActivity.this"FAILED capturing Screenshot: " + pFilePath + " !", Toast.LENGTH_LONG).show(); 
  112.                                                  
  113.                                             } 
  114.                                         }); 
  115.                                     } 
  116.                             }); 
  117.                 } 
  118.                  
  119.                 return true
  120.             } 
  121.         }); 
  122.          
  123.         //设置场景背景色 
  124.         scene.setBackground(new Background(0,0,0)); 
  125.          
  126.         /*创建矩形*/ 
  127.         final Rectangle rect1 = this.makeColoredRectangle(-180, -180100); 
  128.         final Rectangle rect2 = this.makeColoredRectangle(0, -180010); 
  129.         final Rectangle rect3 = this.makeColoredRectangle(00001); 
  130.         final Rectangle rect4 = this.makeColoredRectangle(-1800110); 
  131.         //实体 
  132.         final Entity rectangleGroup = new Entity(camera_width/2,camera_height/2); 
  133.          
  134.         rectangleGroup.attachChild(rect1); 
  135.         rectangleGroup.attachChild(rect2); 
  136.         rectangleGroup.attachChild(rect3); 
  137.         rectangleGroup.attachChild(rect4); 
  138.           
  139.         scene.attachChild(rectangleGroup); 
  140.          
  141.         return scene; 
  142.     } 
  143.     /** 
  144.      * 创建有颜色的矩形 
  145.      * @param pX 
  146.      * @param pY 
  147.      * @param pRed 
  148.      * @param pGreen 
  149.      * @param pBlue 
  150.      * @return 
  151.      */ 
  152.     private Rectangle makeColoredRectangle(final float pX, final float pY, final float pRed, final float pGreen, final float pBlue){ 
  153.          
  154.         Rectangle colorRectangle = new Rectangle(pX, pY, 180180this.getVertexBufferObjectManager()); 
  155.         colorRectangle.setColor(pRed,pGreen,pBlue); 
  156.         return colorRectangle; 
  157.     } 
  158.       
  159.     /** 
  160.      * 初始化界面大小设置 
  161.      */ 
  162.     private void  setSceenDisplay(){ 
  163.         DisplayMetrics dm = new DisplayMetrics(); 
  164.         getWindowManager().getDefaultDisplay().getMetrics(dm); 
  165.         camera_width = dm.widthPixels; 
  166.         camera_height = dm.heightPixels; 
  167.     } 
  168.       
  169.    

这样就完成矩形的绘制了。效果如图: 

AndEngine引擎学习之绘制矩形Rectangle

上面的程序有个问题,就是屏幕触摸时候,无法保存截屏。报了以下错误:

 

AndEngine引擎学习之绘制矩形Rectangle

报错说无法报错该截屏的文件。查看了下源码,原因是未创建目录,导致无法报错文件。

这里需要修改的ScreenCapture类下的saveCapture方法:

 


  1. private static void saveCapture(final Bitmap pBitmap, final String pFilePath) throws FileNotFoundException { 
  2.     FileOutputStream out = null
  3.     try
  4.         File file = new File(pFilePath); 
  5.         if(!file.getParentFile().exists()){//判断父目录是否存在 
  6.             if(!file.getParentFile().mkdirs()){ //创建文件 
  7.                 throw new FileNotFoundException("create dir fail."); 
  8.             } 
  9.         } 
  10.         out = new FileOutputStream(pFilePath); 
  11.         pBitmap.compress(CompressFormat.PNG, 100, out); 
  12.     } catch (final FileNotFoundException e) { 
  13.         StreamUtils.flushCloseStream(out); 
  14.         Debug.e("Error saving file to: " + pFilePath, e); 
  15.         throw e; 
  16.     } 

然后运行代码,创建成功了。文件保存在SD卡下的/Android/data/您的项目报名/files/下。

FileUtils类下可以查看到该代码的路径:

 


  1. public static String getAbsolutePathOnExternalStorage(final Context pContext, final String pFilePath) { 
  2.     return Environment.getExternalStorageDirectory() + "/Android/data/" + pContext.getApplicationInfo().packageName + "/files/" + pFilePath; 

虽然图片截图报错成功了。但是打开时黑黑的一片。

找了下原因是ScreenCapture一开始就加入到了Scene中,导致无法截屏其他entity。

修改下代码把ScrenCapture放到最后去执行:

 


  1. protected Scene onCreateScene() { 
  2.         Log.i(TAG, "--onCreateScene()--"); 
  3.         this.mEngine.registerUpdateHandler(new FPSLogger()); 
  4.         /** 
  5.          * 场景容器,作用类似于LGame中的Screen, 
  6.          * 能够将某一特定场景作为游戏模块进行调用 
  7.          * ,我们可以利用它来切换当前游戏的画面与触摸屏监听, 
  8.          * 切换方法是利用Engine.setScene。 
  9.          */ 
  10.         final Scene scene = new Scene();  
  11.          
  12.         //设置场景背景色 
  13.         scene.setBackground(new Background(0,0,0)); 
  14.          
  15.         /*创建矩形*/ 
  16.         final Rectangle rect1 = this.makeColoredRectangle(-180, -180100); 
  17.         final Rectangle rect2 = this.makeColoredRectangle(0, -180010); 
  18.         final Rectangle rect3 = this.makeColoredRectangle(00001); 
  19.         final Rectangle rect4 = this.makeColoredRectangle(-1800110); 
  20.         //实体 
  21.         final Entity rectangleGroup = new Entity(camera_width/2,camera_height/2); 
  22.          
  23.         rectangleGroup.attachChild(rect1); 
  24.         rectangleGroup.attachChild(rect2); 
  25.         rectangleGroup.attachChild(rect3); 
  26.         rectangleGroup.attachChild(rect4); 
  27.           
  28.         scene.attachChild(rectangleGroup); 
  29.          
  30.         //截屏 
  31.         final ScreenCapture screenCapture = new ScreenCapture(); 
  32.          //加入截屏功能。 
  33.         scene.attachChild(screenCapture);  
  34.         //场景触摸事件 
  35.         scene.setOnSceneTouchListener(new IOnSceneTouchListener() { 
  36.              
  37.             @Override 
  38.             public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) { 
  39.                  
  40.                 if(pSceneTouchEvent.isActionDown()){//屏幕点击的时候开始截屏 
  41.                   
  42.                     screenCapture.capture(18060360360, FileUtils.getAbsolutePathOnExternalStorage(MainActivity.this"Screen_"+System.currentTimeMillis()+".png"),  
  43.                             new IScreenCaptureCallback() { 
  44.                                  
  45.                                 public void onScreenCaptured(final String pFilePath) { 
  46.                                      MainActivity.this.runOnUiThread(new Runnable() { 
  47.                                          
  48.                                         @Override 
  49.                                         public void run() { 
  50.                                             Toast.makeText(MainActivity.this"Screenshot: " + pFilePath + " taken!", Toast.LENGTH_LONG).show(); 
  51.                                              
  52.                                         } 
  53.                                     }); 
  54.                                 } 
  55.                                   
  56.                                 public void onScreenCaptureFailed(final String pFilePath, Exception pException) { 
  57.                                      MainActivity.this.runOnUiThread(new Runnable() { 
  58.                                              
  59.                                             @Override 
  60.                                             public void run() { 
  61.                                                 Toast.makeText(MainActivity.this"FAILED capturing Screenshot: " + pFilePath + " !", Toast.LENGTH_LONG).show(); 
  62.                                                  
  63.                                             } 
  64.                                         }); 
  65.                                     } 
  66.                             }); 
  67.                 } 
  68.                  
  69.                 return true
  70.             } 
  71.         }); 
  72.           
  73.          
  74.         return scene; 
  75.     } 

这样就完成了绘制矩形以及截屏的功能了。

能力有限,请大家多多指教。



本文转自xuzw13 51CTO博客,原文链接:http://blog.51cto.com/xuzhiwei/1050522,如需转载请自行联系原作者