打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android游戏开发----动画SurfaceView详解

   SurfaceView在游戏开发中占着举足轻重的地位。今天好好找资料看了看。附带自己写的例子。   

     写变化不太快的画面时,用View就足够了,用View写太快的画面变化时,可能会出现屏幕闪烁。当写如像植物大战僵尸、水果忍者等游戏时,用View就不能满足要求了。Android提供了SurfaceView,它是专门用来做动画,它是View的子类。
    在SurfaceView自带2级缓存,当写变换比较快的游戏时,二级缓存会让游戏画面的变化看起来比较连贯一些。2级缓存的作用就是提前把将要绘制的图片放到内存里面。
一、实现最基本的SurfaceView只需基础即可,再按4个步骤来做即可。直接上代码,详细看代码里里面的注释。
[java] 
public class GameView extends SurfaceView 

    SurfaceHolder surfaceHolder; 
 
    public GameView(Context context) 
    { 
        super(context); 
        //1. 获得SurfaceView下是SurfaceHolder, surfaceHolder相当于一个遥控器来控制SurfaceView 
        surfaceHolder = this.getHolder(); 
        //这个是回调方法, 必须有. 否则会报空指针异常. 意思是surface创建, 销毁,改变 
        surfaceHolder.addCallback(new Callback() 
        { 
 
            @Override 
            public void surfaceDestroyed(SurfaceHolder holder) 
            { 
 
            } 
 
            @Override 
            public void surfaceCreated(SurfaceHolder holder) 
            { 
                //2. 在surface创建后锁定画布 
                Canvas canvas = surfaceHolder.lockCanvas(); 
                //3. 可以在画布上进行任意的绘画操作( 下面是画一条红色 的线 ) 
                Paint paint = new Paint(); 
                paint.setColor(Color.RED); 
                canvas.drawLine(0, 0, 100, 100, paint); 
                //4. 将画布解锁并显示在屏幕上 
                surfaceHolder.unlockCanvasAndPost(canvas); 
            } 
 
            @Override 
            public void surfaceChanged(SurfaceHolder holder, int format, 
                    int width, int height) 
            { 
 
            } 
        }); 
 
    } 

当然,这样写很明显不是最好的。只有SurfaceView很明显不能实现动画,当然要与线程结合起来。用线程来刷屏。
二、使用SurfaceView来写动画的一般写法。直接上代码,详细解释请看代码里里面的注释。

[java] 
public class GameViewOK extends SurfaceView implements Callback, Runnable 

    SurfaceHolder surfaceHolder; 
    private boolean isThreadRunning = true; 
    Canvas canvas; 
    float r = 10; 
 
    public GameViewOK(Context context) 
    { 
        super(context); 
        surfaceHolder = this.getHolder(); 
        surfaceHolder.addCallback(this);//注册回调方法 
    } 
 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
            int height) 
    { 
 
    } 
 
    @Override 
    public void surfaceCreated(SurfaceHolder holder) 
    { 
        //创建surfaceView时启动线程 
        new Thread(this).start(); 
    } 
 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
        //当surfaceView销毁时, 停止线程的运行. 避免surfaceView销毁了线程还在运行而报错. 
        isThreadRunning = false; 
        //第三种方法防止退出时异常. 当surfaceView销毁时让线程暂停300ms . 醒来再执行run()方法时,isThreadRunning就是false了.  
        try 
        { 
            Thread.sleep(300); 
        } catch (InterruptedException e) 
        { 
            e.printStackTrace(); 
        } 
    } 
 
    /**
     * 将绘图的方法单独写到这个方法里面.
     */ 
    private void drawVieW() 
    { 
        try 
        {//第一种方法防止退出时异常: 当isThreadRunning为false时, 最后还是会执行一次drawView方法, 但此时surfaceView已经销毁 
            //因此才来判断surfaceHolder 
            if (surfaceHolder != null) 
            { 
                //1. 在surface创建后锁定画布 
                canvas = surfaceHolder.lockCanvas(); 
                //2. 可以在画布上进行任意的绘画操作( 下面是画一条红色 的线 ) 
                Paint paint = new Paint(); 
                paint.setColor(Color.BLUE); 
                //paint.setStyle(Style.STROKE);//只有边框 
                paint.setStrokeWidth(5); 
                canvas.drawCircle(100, 100, r++, paint); 
            } 
        } catch (Exception e) 
        { 
            e.printStackTrace(); 
        } finally 
        { 
            //canvas是根据surfaceHolder得到的, 最后一次surfaceView已经销毁, canvas当然也不存在了. 
            if (canvas != null) 
                //3. 将画布解锁并显示在屏幕上 
                surfaceHolder.unlockCanvasAndPost(canvas); 
        } 
 
    } 
 
    @Override 
    public void run() 
    { 
        //每隔100ms刷新屏幕 
        while (isThreadRunning) 
        { 
            drawVieW(); 
            try 
            { 
                Thread.sleep(100); 
            } catch (Exception e) 
            { 
                e.printStackTrace(); 
            } 
        } 
    } 
 
    /*
     * 这个是第二种方法解决退出是报错的问题. 当按下返回键时, 提前设置isThreadRunning为false, 让线程结束.
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_BACK)
        {
            isThreadRunning = false;
        }
        return super.onKeyDown(keyCode, event);
    }
    */ 

运行效果:不断增大的圆形

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
SurfaceView的使用
Android游戏框架SurfaceView介绍(附代码)
Android中的Surface和SurfaceView
用SurfaceView和MediaPlayer做一个Android视频播放器
MediaPlayer 用法(一) - 一切皆有可能 - JavaEye技术网站
Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服