天天看点

AndEngine引擎学习之绘制矩形Rectangle

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

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

主Activity继承SimpleBaseGameActivity:

package com.xzw.drawrect; 

import org.andengine.engine.camera.Camera; 

import org.andengine.engine.options.EngineOptions; 

import org.andengine.engine.options.ScreenOrientation; 

import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; 

import org.andengine.entity.Entity; 

import org.andengine.entity.primitive.Rectangle; 

import org.andengine.entity.scene.IOnSceneTouchListener; 

import org.andengine.entity.scene.Scene; 

import org.andengine.entity.scene.background.Background; 

import org.andengine.entity.util.FPSLogger; 

import org.andengine.entity.util.ScreenCapture; 

import org.andengine.entity.util.ScreenCapture.IScreenCaptureCallback; 

import org.andengine.input.touch.TouchEvent; 

import org.andengine.ui.activity.SimpleBaseGameActivity; 

import org.andengine.util.FileUtils; 

import android.util.DisplayMetrics; 

import android.util.Log; 

import android.widget.Toast; 

/** 

 *  

 * @author [email protected] 

 * weibo:http://weibo.com/xzw1989 

 */ 

public class MainActivity extends SimpleBaseGameActivity { 

    private static final String TAG = "MainActivity";  

    //设置屏幕的显示大小 

    /*private static final int CAMERA_WIDTH = 720; 

    private static final int CAMERA_HEIGHT = 480;*/ 

    private static  int camera_width = 720; 

    private static  int camera_height = 480; 

    /** 

     * 创建引擎的选项(这里我的理解是初始化过程,和activity的onCreate一样) 

     */ 

    @Override 

    public EngineOptions onCreateEngineOptions() { 

        Log.i(TAG, "--onCreateEngineOptions()--"); 

        //初始化屏幕显示区域的大小。 

        setSceenDisplay(); 

        /** 

         * 该类即我们常说的游戏摄像机,在AndEngine的Camera有两种作用, 

         * 一是用以调节屏幕的显示区域,二是利用HUD类实际绘制游戏屏幕于手机之上。 

         */ 

        final Camera camera = new Camera(0, 0, camera_width, camera_height); 

        return new EngineOptions(true,  

                ScreenOrientation.LANDSCAPE_FIXED,  

                new RatioResolutionPolicy(camera_width, camera_height), 

                camera); 

    } 

    protected void onCreateResources() {  

        Log.i(TAG, "--onCreateResources()--"); 

     * 创建场景 

    protected Scene onCreateScene() { 

        Log.i(TAG, "--onCreateScene()--"); 

        this.mEngine.registerUpdateHandler(new FPSLogger()); 

         * 场景容器,作用类似于LGame中的Screen, 

         * 能够将某一特定场景作为游戏模块进行调用 

         * ,我们可以利用它来切换当前游戏的画面与触摸屏监听, 

         * 切换方法是利用Engine.setScene。 

        final Scene scene = new Scene(); 

        //截屏 

        final ScreenCapture screenCapture = new ScreenCapture(); 

         //加入截屏功能。 

        scene.attachChild(screenCapture); 

        //场景触摸事件 

        scene.setOnSceneTouchListener(new IOnSceneTouchListener() { 

            @Override 

            public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) { 

                if(pSceneTouchEvent.isActionDown()){//屏幕点击的时候开始截屏 

                    screenCapture.capture(180, 60, 360, 360, FileUtils.getAbsolutePathOnExternalStorage(MainActivity.this, "Screen_"+System.currentTimeMillis()+".png"),  

                            new IScreenCaptureCallback() { 

                                public void onScreenCaptured(final String pFilePath) { 

                                     MainActivity.this.runOnUiThread(new Runnable() { 

                                        @Override 

                                        public void run() { 

                                            Toast.makeText(MainActivity.this, "Screenshot: " + pFilePath + " taken!", Toast.LENGTH_LONG).show(); 

                                        } 

                                    }); 

                                } 

                                public void onScreenCaptureFailed(final String pFilePath, Exception pException) { 

                                            @Override 

                                            public void run() { 

                                                Toast.makeText(MainActivity.this, "FAILED capturing Screenshot: " + pFilePath + " !", Toast.LENGTH_LONG).show(); 

                                            } 

                                        }); 

                                    } 

                            }); 

                } 

                return true; 

            } 

        }); 

        //设置场景背景色 

        scene.setBackground(new Background(0,0,0)); 

        /*创建矩形*/ 

        final Rectangle rect1 = this.makeColoredRectangle(-180, -180, 1, 0, 0); 

        final Rectangle rect2 = this.makeColoredRectangle(0, -180, 0, 1, 0); 

        final Rectangle rect3 = this.makeColoredRectangle(0, 0, 0, 0, 1); 

        final Rectangle rect4 = this.makeColoredRectangle(-180, 0, 1, 1, 0); 

        //实体 

        final Entity rectangleGroup = new Entity(camera_width/2,camera_height/2); 

        rectangleGroup.attachChild(rect1); 

        rectangleGroup.attachChild(rect2); 

        rectangleGroup.attachChild(rect3); 

        rectangleGroup.attachChild(rect4); 

        scene.attachChild(rectangleGroup); 

        return scene; 

     * 创建有颜色的矩形 

     * @param pX 

     * @param pY 

     * @param pRed 

     * @param pGreen 

     * @param pBlue 

     * @return 

    private Rectangle makeColoredRectangle(final float pX, final float pY, final float pRed, final float pGreen, final float pBlue){ 

        Rectangle colorRectangle = new Rectangle(pX, pY, 180, 180, this.getVertexBufferObjectManager()); 

        colorRectangle.setColor(pRed,pGreen,pBlue); 

        return colorRectangle; 

     * 初始化界面大小设置 

    private void  setSceenDisplay(){ 

        DisplayMetrics dm = new DisplayMetrics(); 

        getWindowManager().getDefaultDisplay().getMetrics(dm); 

        camera_width = dm.widthPixels; 

        camera_height = dm.heightPixels; 

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

<a href="http://blog.51cto.com/attachment/201211/140529574.jpg" target="_blank"></a>

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

<a href="http://blog.51cto.com/attachment/201211/140643334.jpg" target="_blank"></a>

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

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

private static void saveCapture(final Bitmap pBitmap, final String pFilePath) throws FileNotFoundException { 

    FileOutputStream out = null; 

    try{ 

        File file = new File(pFilePath); 

        if(!file.getParentFile().exists()){//判断父目录是否存在 

            if(!file.getParentFile().mkdirs()){ //创建文件 

                throw new FileNotFoundException("create dir fail."); 

        } 

        out = new FileOutputStream(pFilePath); 

        pBitmap.compress(CompressFormat.PNG, 100, out); 

    } catch (final FileNotFoundException e) { 

        StreamUtils.flushCloseStream(out); 

        Debug.e("Error saving file to: " + pFilePath, e); 

        throw e; 

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

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

public static String getAbsolutePathOnExternalStorage(final Context pContext, final String pFilePath) { 

    return Environment.getExternalStorageDirectory() + "/Android/data/" + pContext.getApplicationInfo().packageName + "/files/" + pFilePath; 

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

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

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

protected Scene onCreateScene() { 

        final Scene scene = new Scene();  

        scene.attachChild(screenCapture);  

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

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

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