在android上开发已经有三年多了,此次跳槽来到的是一个作VR的公司,可是我却对3D几乎等因而0基础,一跳漫长的学习道路必然不能少了.java
在实际开发中,一把那是用view直接去作动画的,可是基于3D的学习,咱们如今用SurfaceView来作一个简单的2D动画.对于图SurfaceView通常是去继承他,而后还须要实现SurfaceHolder.Callback接口.onDraw方法是SurfaceView的绘制方法,没触发一次绘制一帧.android
在SurfaceHolder.Callback中有2D界面的3个生命周期回调方法:git
1.surfaceCreated(SurfaceHolder holder);该方法在SurfaceView建立的时候被调用;github
2.surfaceChanged(SurfaceHolder holder, int format, int width, int height);该方法在SurfaceView变化时被调用,在建立后至少调用一次;canvas
3.surfaceDestroyed(SurfaceHolder holder);该方法在SurfaceView销毁的时候调用;ide
此动画首先作X作匀速移动,Y轴上抛运动,而后爆炸,效果以下图:学习
接着对下列实现代码作介绍:动画
1.控制类MainActivity.java:主要做为SurfaceView的控制类this
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 设置window没有标题并且全屏 */ requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN); //设置屏幕的方向为横向 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mCustomSurfaceView = new CustomSurfaceView(this); /tContentView(R.layout.activity_main); setContentView(mCustomSurfaceView); }
2.CustomSurfaceView显示类:绘制是由onDeaw方法实现,另外对于实现的Callback方法以下:spa
DrawThread mDrawThread; //用于实现绘制的线程 Bitmap mBgBitmap; //背景图 Bitmap mBulletBitmap; //炮弹位图 Bitmap[] mExplodeBmps;//爆炸效果图 Bullet mBullet;//炮弹实体类
@Override public void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 首先绘制本身的背景 * 而后绘制炮弹本身 */ canvas.drawBitmap(mBgBitmap , 0 , 0 , mPaint); mBullet.drawSelf(canvas , mPaint); }
@Override public void surfaceCreated(SurfaceHolder holder) { mPaint = new Paint(); //抗锯齿 mPaint.setAntiAlias(true); //加载炮弹图片 mBulletBitmap = BitmapFactory.decodeResource(getResources() , R.mipmap.bullet); mBgBitmap = BitmapFactory.decodeResource(getResources() , R.mipmap.bg); mExplodeBmps = new Bitmap[]{ BitmapFactory.decodeResource(getResources() , R.mipmap.explode0) , BitmapFactory.decodeResource(getResources() , R.mipmap.explode1) , BitmapFactory.decodeResource(getResources() , R.mipmap.explode2) , BitmapFactory.decodeResource(getResources() , R.mipmap.explode3) , BitmapFactory.decodeResource(getResources() , R.mipmap.explode4) , BitmapFactory.decodeResource(getResources() , R.mipmap.explode5) }; //建立炮弹对象 mBullet = new Bullet(this , mBulletBitmap , mExplodeBmps , 200 , 290 , 1.3f , -5.9f ); mDrawThread = new DrawThread(this); mDrawThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mDrawThread.setFlag(false); }
@Override public void run() { super.run(); Canvas canvas; while (mFlag){ canvas = null; //锁定画布 try { canvas = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder){ //绘制每一帧 mCustomSurfaceView.onDraw(canvas); } } finally { if (canvas != null){ //释放锁 mSurfaceHolder.unlockCanvasAndPost(canvas); } } try { //睡眠一下子 Thread.sleep(mSleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Bullet { CustomSurfaceView mCustomSurfaceView; //位图 private Bitmap mBulletBitmap; //爆炸动画图组 private Bitmap[] mExplodeBmps; //X轴位置 float mX; float mY; //X轴速度 float mVx; float mVy; //生存时间 private float mLiveTime; //时间间隔 private float mSpanTime = 0.5f; //炮弹尺寸 private int mBulletSize; //是否绘制炮弹标记位 private boolean isExplosion; //爆炸对象的引用 private Explosion mExplosion; public Bullet(CustomSurfaceView customSurfaceView, Bitmap bulletBitmap, Bitmap[] explodeBmps, float x, float y, float vx, float vy) { mCustomSurfaceView = customSurfaceView; mBulletBitmap = bulletBitmap; mExplodeBmps = explodeBmps; mX = x; mY = y; mVx = vx; mVy = vy; mBulletSize = bulletBitmap.getHeight(); } /** * 绘制本身 * @param canvas 画板 * @param paint 画笔 */ public void drawSelf(Canvas canvas, Paint paint) { if (isExplosion && mExplosion != null){ mExplosion.drawSelf(canvas , paint); }else { go(); canvas.drawBitmap(mBulletBitmap , mX , mY , paint); } } /** * 绘制炮弹前进的方法 */ private void go() { //在水平方向上作匀速运动 mX += mVx * mLiveTime; //在竖直方向上作上抛运动 mY += mVy * mLiveTime + 0.5f + Constant.G * mLiveTime * mLiveTime; //爆炸点 if (mX >= Constant.EXPLOSION_X || mY >= Constant.SCREEN_HEIGHT){ mExplosion = new Explosion(mCustomSurfaceView , mExplodeBmps , mX , mY); //不在绘制炮弹 isExplosion = true; return; } //更新生存时间 mLiveTime += mSpanTime; } }
此项目仅做为学习用,github项目地址:https://github.com/ynztlxdeai/Bullet-anim