Canvas,在英语中,这个单词的意思是帆布。在Android中,则把Canvas当做画布,只要我们借助设置好的画笔(Paint类)就可以在画布上绘制我们想要的任何东西;另外它也是显示位图(Bitmap类)的核心类。随用户的喜好,Canvas还可设置一些关于画布的属性,比如,画布的颜色、尺寸等。Canvas提供了如下一些方法:
Canvas(): 创建一个空的画布,可以使用setBitmap()方法来设置绘制具体的画布。
Canvas(Bitmap bitmap): 以bitmap对象创建一个画布,则将内容都绘制在bitmap上,因此bitmap不得为null。
Canvas(GL gl): 在绘制3D效果时使用,与OpenGL相关。
drawColor: 设置Canvas的背景颜色。
setBitmap: 设置具体画布。
clipRect: 设置显示区域,即设置裁剪区。
isOpaque:检测是否支持透明。
rotate: 旋转画布
translate:移动画布
scale:缩放画布
setViewport: 设置画布中显示窗口。
skew: 设置偏移量。
restore: 用来恢复上一次save之前的状态
save:用来保存Canvas的当前状态
注意: save方法、restore方法一般是成对出现的,save方法可多于restore方法,但restore方法不能多于save方法
上面列举了几个常用的方法。在游戏开发中,我们可能需要对某个精灵执行旋转、缩放和一些其它操作。我们可以通过旋转画布来实现,但是旋转画布时会旋转画布上的所有对象,而我们只是需要旋转其中的一个,这时就需要用到save 方法来锁定需要操作的对象,在操作之后通过 restore 方法来解除锁定。
package com.yarin.android.Examples_05_04; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; public class GameView extends View implements Runnable { /* 声明Paint对象 */ private Paint mPaint = null; public GameView(Context context) { super(context); /* 构建对象 */ mPaint = new Paint(); /* 开启线程 */ new Thread(this).start(); } public void onDraw(Canvas canvas) { super.onDraw(canvas); /* 设置画布的颜色 */ canvas.drawColor(Color.BLACK); /* 设置取消锯齿效果 */ mPaint.setAntiAlias(true); /* 设置裁剪区域 */ canvas.clipRect(10, 10, 280, 260); /* 线锁定画布 */ canvas.save(); /* 旋转画布 */ canvas.rotate(45.0f); /* 设置颜色及绘制矩形 */ mPaint.setColor(Color.RED); canvas.drawRect(new Rect(15, 15, 140, 70), mPaint); /* 解除画布的锁定 */ canvas.restore(); /* 设置颜色及绘制另一个矩形 */ mPaint.setColor(Color.GREEN); canvas.drawRect(new Rect(150, 75, 260, 120), mPaint); } // 触笔事件 public boolean onTouchEvent(MotionEvent event) { return true; } // 按键按下事件 public boolean onKeyDown(int keyCode, KeyEvent event) { return true; } // 按键弹起事件 public boolean onKeyUp(int keyCode, KeyEvent event) { return false; } public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return true; } public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } // 使用postInvalidate可以直接在线程中更新界面 postInvalidate(); } } }
1.本节要点:
1.之前绘制的动画场景都是单人物的,这节主要讲解如何实现多个AnimatedSprite在共用一个BitmapTextureAtlas下的应用
2.之前的精灵动画都没有交互性的,这节要实现触摸可以拖动精灵
3.实现屏幕的多点触摸
2.Texture的创建
1.本节用到4个精灵贴图:
要合理的利用BitmapTextureAtlas这个类进行封装这四个贴图成一个大的texture,首先了解下它的构造:
/** * Uses {@link BitmapTextureFormat#RGBA_8888}. * * @param pTextureOptions the (quality) settings of this {@link BitmapTextureAtlas}. */ public BitmapTextureAtlas(final TextureManager pTextureManager, final int pWidth, final int pHeight, final TextureOptions pTextureOptions) throws IllegalArgumentException { this(pTextureManager, pWidth, pHeight, BitmapTextureFormat.RGBA_8888, pTextureOptions, null); }
这里的BitmapTextureAtlas是指在内存中贴图集合,可以将多个图片同时放置在这里,本例子就是将四张大贴图放置期中;
另外一个值得注意的东西就是TiledTextureRegion,它可以从BitmapTextureAtlas中"扣"出一张贴图
3.细节处理
private static final int CAMERA_WIDTH = 800; private static final int CAMERA_HEIGHT = 480; private Camera mCamera; private RepeatingSpriteBackground mBackground; private BitmapTextureAtlas mTexture; private TiledTextureRegion mBanana; private TiledTextureRegion mFrog; private TiledTextureRegion mHelicopter; private TiledTextureRegion mSnapDragon;2.四张贴图中的分辨路分别为:132x70,96x32,96x84,400x180
考虑到BitmapTextureAtlas 的长与宽只能为2的n次方大小,所以要把贴图集设置为512x256大小
mTexture = new BitmapTextureAtlas(getTextureManager(), 512, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
然后要把四张精灵贴图放置在mTexture里面就需要动下脑筋了,为了更加合理的放置,我把4张图片放置在photoshop里,然后创建一张
512x256大小的图片,尝试拖动他们进去排布,最终比较合理的排布为:
程序上实现的方法为:
mSnapDragon = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "snapdragon_tiled.png", 0, 0, 4, 3); mHelicopter = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "helicopter_tiled.png", 400, 0, 2, 2); mBanana = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "banana_tiled.png", 0, 180, 4, 2); mFrog = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "frog.png", 132, 180, 3, 1); mTexture.load();
3.创建可以支持触摸拖动的AnimatedSprite精灵
自己根据需要创建TouchAnimatedSprite,并且集成AnimatedSprite的所有方法
public class TouchAnimatedSprite extends AnimatedSprite{ public TouchAnimatedSprite(float pX, float pY, float pWidth, float pHeight, ITiledTextureRegion pTiledTextureRegion, VertexBufferObjectManager pVertexBufferObjectManager) { super(pX, pY, pWidth, pHeight, pTiledTextureRegion, pVertexBufferObjectManager); // TODO Auto-generated constructor stub } @Override public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) { // TODO Auto-generated method stub switch(pSceneTouchEvent.getAction()){ case TouchEvent.ACTION_DOWN: case TouchEvent.ACTION_MOVE: this.setPosition(pSceneTouchEvent.getX()-this.getWidth()/2, pSceneTouchEvent.getY()-this.getHeight()/2); return true; } return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); } }
有了TouchAnimatedSprite这个类,就可以书写相关的初始化工作了,在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)方法
中添加场景等初始化资源
Scene mScene = new Scene(); mScene.setBackground(mBackground);接着在Scene中创建4个动画精灵
final TouchAnimatedSprite myBanana = new TouchAnimatedSprite(100, 50,64,64,mBanana, getVertexBufferObjectManager()); myBanana.animate(150); final TouchAnimatedSprite myFrog = new TouchAnimatedSprite(100,CAMERA_HEIGHT-100,64,64,mFrog,getVertexBufferObjectManager()); myFrog.animate(90); final TouchAnimatedSprite myHelicopter = new TouchAnimatedSprite(CAMERA_WIDTH - 140, CAMERA_HEIGHT - 100, 84,84,mHelicopter,getVertexBufferObjectManager()); myHelicopter.animate(new long[]{100,200,150,400},0,3,true); final TouchAnimatedSprite mySnapDragon = new TouchAnimatedSprite(CAMERA_WIDTH - 100,50,85,85,mSnapDragon,getVertexBufferObjectManager()); mySnapDragon.animate(90);
然后把四个精灵动画添加到场景中
mScene.attachChild(myBanana); mScene.attachChild(myFrog); mScene.attachChild(myHelicopter); mScene.attachChild(mySnapDragon);
场景中的人物布置好了之后,接着个场景中的人如添加触摸操作支持
mScene.registerTouchArea(myBanana); mScene.registerTouchArea(myFrog); mScene.registerTouchArea(myHelicopter); mScene.registerTouchArea(mySnapDragon); mScene.setTouchAreaBindingOnActionDownEnabled(true);
至此,整个设计已经完成了,但是屏幕只可以支持单点触摸的方式,毕竟咱们的手机大多数都是
支持多点触摸的,这样岂不是浪费并且不好玩.为了支持多点触摸可以在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)方法
初始化mScene后添加如下方法:
if(MultiTouch.isSupported(this))//添加多点触摸支持 { this.mEngine.setTouchController(new MultiTouchController()); this.mEngine.getEngineOptions().getTouchOptions().setNeedsMultiTouch(true); }这样做了之后是不是很完美了呢?哈哈哈~~~~~~~~~~~~~~~~~~~~~
好了,废话少说,看看效果再说吧!
本节源代码下载地址:http://download.csdn.net/detail/cen616899547/4707665
1.重启(当然这种方法一般情况下不管用)
2. 查看证书是否是正确的
3.PROJECT --> Info --> Deployment Target --> IOS Deployment Target 里面的值 要设置为 <=真机系统版本
TARGETS --> Summary --> IOS Application Target --> Deployment Target 里面的值 要设置为 <=真机系统版本
也要查看一下这两个是否正确
PROJECT --> Build Settings --> Deployment --> IOS Deployment Target
TARGETS --> Build Settings --> Deployment --> IOS Deployment Target