3D开发学习-初识SurfaceView
来源:互联网 发布:原生js实现find方法 编辑:程序博客网 时间:2024/06/04 19:19
在android上开发已经有三年多了,这次跳槽来到的是一个做VR的公司,但是我却对3D几乎等于是0基础,一跳漫长的学习道路必然不能少了.
在实际开发中,一把那是用view直接去做动画的,但是基于3D的学习,我们现在用SurfaceView来做一个简单的2D动画.对于图SurfaceView一般是去继承他,然后还需要实现SurfaceHolder.Callback接口.onDraw方法是SurfaceView的绘制方法,没触发一次绘制一帧.
在SurfaceHolder.Callback中有2D界面的3个生命周期回调方法:
1.surfaceCreated(SurfaceHolder holder);该方法在SurfaceView创建的时候被调用;
2.surfaceChanged(SurfaceHolder holder, int format, int width, int height);该方法在SurfaceView变化时被调用,在创建后至少调用一次;
3.surfaceDestroyed(SurfaceHolder holder);该方法在SurfaceView销毁的时候调用;
此动画首先做X做匀速移动,Y轴上抛运动,然后爆炸,效果如下图:
接着对下列实现代码做介绍:
1.控制类MainActivity.java:主要作为SurfaceView的控制类
@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方法如下:
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); }
3.DrawThread绘制线程类run方法如下:
@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(); } } }
4.炮弹实体类Bullet类:
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
- 3D开发学习-初识SurfaceView
- Molehill 初识--flash 3d 开发基础
- 初识3D
- 初识Unity 3D
- 【Android 2d游戏开发(3)】——贪吃蛇(基于surfaceview框架,精讲)
- 3D开发&机器学习
- Android 初识SurfaceView
- Android 使用SurfaceView进行2D动画的开发
- Android开发学习SurfaceView显示动画效果
- android 学习笔记 view和surfaceView的2D绘图
- 初识3D游戏引擎
- SurfaceView学习
- surfaceView学习
- SurfaceView学习
- SurfaceView学习
- SurfaceView学习
- SurfaceView学习
- SurfaceView学习
- Android Fragment(动态,静态)碎片详解及总结
- QListWidget制作聊天列表
- codeforces 743 C. Vladik and fractions(构造)
- 关于多层 nested loop的估值问题
- Angular.js的数据绑定以及模块作用域
- 3D开发学习-初识SurfaceView
- Java 多线程学习笔记 线程通讯 wait notify notifyAll的理解
- Spring学习笔记之Bean的作用域
- 通过获取鼠标的点击位置来动态定位元素
- 解题报告:POJ 3162 Walking Race 树型DP+单调RMQ
- 位与字节
- Android ORMLite 多表联查
- TSQL 字符串函数:截断和查找
- Lesson 12: 索引缓存