上一次我们通过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);
- }
- @Override
- protected void onCreateResources() {
- Log.i(TAG, "--onCreateResources()--");
- }
- /**
- * 创建场景
- */
- @Override
- 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) {
- MainActivity.this.runOnUiThread(new Runnable() {
- @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;
- }
- }
这样就完成矩形的绘制了。效果如图:
上面的程序有个问题,就是屏幕触摸时候,无法保存截屏。报了以下错误:
报错说无法报错该截屏的文件。查看了下源码,原因是未创建目录,导致无法报错文件。
这里需要修改的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() {
- Log.i(TAG, "--onCreateScene()--");
- this.mEngine.registerUpdateHandler(new FPSLogger());
- /**
- * 场景容器,作用类似于LGame中的Screen,
- * 能够将某一特定场景作为游戏模块进行调用
- * ,我们可以利用它来切换当前游戏的画面与触摸屏监听,
- * 切换方法是利用Engine.setScene。
- */
- final Scene scene = new Scene();
- //设置场景背景色
- 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);
- //截屏
- 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) {
- MainActivity.this.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(MainActivity.this, "FAILED capturing Screenshot: " + pFilePath + " !", Toast.LENGTH_LONG).show();
- }
- });
- }
- });
- }
- return true;
- }
- });
- return scene;
- }
这样就完成了绘制矩形以及截屏的功能了。
能力有限,请大家多多指教。