位置: 编程技术 - 正文

SurfaceView游戏框架(surface游戏模式)

编辑:rootadmin

推荐整理分享SurfaceView游戏框架(surface游戏模式),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:surface小游戏,surfacebook游戏,surface 游戏,surfacepro5游戏,surface pro x 游戏,surface pro x 游戏,surface小游戏,surface 游戏,内容如对您有帮助,希望把文章链接给更多的朋友!

这段时间在看Android游戏编程,感觉SurfaceView这个框架挺好的。分享一下:

1.建立一个工程,在该工程下自定义一个类“MySurfaceView”,此类继承SurfaceView,除此以外还要实现android.view.SurfaceHolder.Callback接口,代码如下:

本类中有很多需要注意的地方,按照代码由上到下的顺序详解说明:

(1)线程标识位

在代码中“boolean flag;”语句声明一个布尔&#;,它主要用于以下两点;

1.1便于消亡线程

大家知道一个线程一旦启动,就会执行其run()函数,run()函数执行结束后,线程也伴随着消亡。由于游戏开发中使用的线程一般都会在run()函数中使用一个while死循环,在这个循环会调用绘图和逻辑函数,使得不断的刷新画布和更新逻辑,那么如果游戏暂停或者游戏结束时,为了便于销毁线程在此设置一个标识位来控制。

1.2防止重复创建线程及异常

为什么会重复创建线程,首先从Android系统的手机说起。熟悉或者接触过Android系统的人都知道,android手机上一般都会有“Back (返回)”与Home(小房子)按键;

不管当前手机运行的是什么程序,只要单击back或者home按键的时候,默认会将当前的程序切入到系统后台运行(程序中没有截获这两个按钮的前提下);也正是因为如此,会造成SurfaceView视图的状态的发生改变。下面来讲解这两个按钮按下以及重新回到程序时SurfaceView都执行到了哪些函数。

首先单击back按钮当前程序切入后台,然后单击项目重新回到程序中,SurfaceView的状态变化为:surfaceDestroyed--->构造函数-->surfaceCreated--->surfaceChanged.

然后单击“Home”按钮使当前程序切入后台,然后单击项目重新回到程序中,SurfaceView的状态变化为:surfaceDestroyed--->surfaceCreated--->surfaceChanged.

通过SurfaceView的状态变化可以很明显的看到,但点击back按键并重新进入程序的过程要比home按键多执行一个构造函数,也就是说,当点击“back”返回按键时,SurfaceView视图会被重新加载。

正是因为这个原因,如果线程的初始化是在视图的构造函数或者在视图构造函数之前,那么线程启动也要放在视图构造函数中进行。

千万不要把线程的初始化放在surfaceCreated视图创建函数之前,而线程的启动却放在surfaceCreated视图创建的函数中,否则程序一旦被玩家点击home按键后再重新回到游戏时,程序会抛出ILLegalThreadStateException:Thread already started;

异常是因为线程已经启动造成的,原因很简单,因为程序被home键切入后台再从后台回复时,就会直接进入surfaceCreated视图创建函数中,又执行了一遍线程启动!

能够想到的解决方法是,可以将线程的初始化和启动都放到视图的构造函数中,或者都放在视图的创建函数中,但是又会有新的问题,如果将线程的初始化和启动都放在视图的构造函数中,那么程序被back键切入后台再从后台恢复时,线程的数量会增多,反复多次,就会反复多出对应的线程。

那么大家可能又会想到将flag这个线程的标识符在视图摧毁时让其&#;改为false,从而使当前这个线程的run方法执行完毕,以达到摧毁掉线程的目的,不幸的是,这也是错误的,大家想想,即使在视图销毁时利用flag标识位摧毁游戏线程,但是如果点击home键,当程序恢复时,程序就不在执行了,也就是说重绘和逻辑函数都不在执行。

所以最完美的做法就是:线程的初始化与线程的启动都写在视图的surfaceCreated创建函数中,并将线程标识位在视图摧毁时将其&#;改为false,这样既可以避免线程已经启动异常,还可以避免点击back按键无限增加线程数的问题。

SurfaceView游戏框架(surface游戏模式)

2获取视图的宽和高

在SurfaceView视图中获取视图的宽和高的方法:

this.getWidth();获取视图宽度。

this.getHeight();获取视图高度。

在SurfaceView视图中获取视图的宽高,一定要在视图创建之后才可以获取到,也就是在surfaceCreated函数之后获取,在此函数执行之前获取到的永远是零,因为当前视图还没有创建,是没有宽高&#;的。

(3)绘图try一下

因为当SurfaceView不可编辑或者尚未创建时,调用lockCanvas()函数返回null,Canvas进行绘图时也会出现不可预知的问题,所以要对绘制函数中进行try....catch处理;既然lockCanvas函数有可能获取为null,那么为了避免其他使用canvas实例进行绘制的函数报错,在使用Canvas开始绘制时,需要对其进行判定是否为null。

(4)提交画布必须放在finally中

绘图的时候可能会出现不可预知的Bug,虽然使用try语句包起来了,不会导致程序崩溃;但是一旦在提交画布之前出错,那么解锁提交画布函数则无法被执行到,这样会导致下次通过lockCanvas来获取Canvas时程序抛出异常,原因是因为画布上次没有解锁提交!所以画布将解锁提交的函数应放在fanally语句块中。

还要注意,虽然这样保证了每次能正常提交解锁画布,但是提交解锁之前要保证画布不为空的前提,所以还需要判断Canvas是否为空,这样一来就完美了。

(5)刷帧时间尽可能保证一致

虽然在线程循环中,设置了休眠时间,但是这样并不完善,比如当前项目中,run的while循环中除了调用绘图函数还一直调用处理游戏逻辑的logic()函数,虽然在当前项目的逻辑函数中并没有写任何的代码,但是假设这个逻辑函数logic()中写了几千行逻辑,那么系统在处理逻辑时,时间的开销是否与上次的相同,这是无法预料的,但是可以尽可能地让其时间差&#;趋于相同。假设游戏线程的休眠时间为X毫秒,一般线程的休眠写法为:

Thread.sleep(x);

优化写法步骤如下:

步骤一:

首先通过系统获取到一个事件戳;

步骤二:

处理以上所有的函数之后,再次通过系统函数获取一个时间戳;

步骤三:

通过两个时间戳的差&#;,就可以知道这些函数所消耗的时间;如果end - start > X,那线程就完全没有必要去休眠;如果end - start < X ,那线程的休眠时间应该为:X - (end - start).

一般游戏中刷新时间在~毫秒之间,也就是每秒~帧左右;当然还要视具体情况和项目而定。

Android游戏:弹弹球(打砖块) 新学android,试手了第一个游戏:弹弹球(其实就是打砖块),代码粗糙,只为练手。游戏只有六关,按菜单键开始和暂停,每两关玩法界面不一样,砖

Android骰子游戏案例 终于等到上班了(转行业真不容易,泪奔),带我的学长布置的第一个任务是做一个骰子的小游戏~~~~好吧,貌不太难,我把写好的源码拿上来给大家分

android游戏地图编辑器 概念地图编辑器读取和使用游戏资源,并按照游戏程序规约输出相应式的地图数据,游戏程序(客户端和服务器)通过地图数据构建游戏场景,将其呈现给

标签: surface游戏模式

本文链接地址:https://www.jiuchutong.com/biancheng/371187.html 转载请保留说明!

上一篇:微信5.0 Android版飞机大战破解无敌模式手记(安卓微信5.0版本下载)

下一篇:Android游戏:弹弹球(打砖块)(手机弹窗游戏)

  • 未投入使用房屋怎么处理
  • 商品削价准备怎么算
  • 小规模纳税人开普票免税
  • 用现金购买的股票
  • 企业用于在建工程购入的材料
  • 物业公司收取的电费怎么确认收入
  • 新公司第一个月报税怎么弄
  • 提前报废资产损失税前扣除
  • 建筑施工企业开立临时账户
  • 同一笔销售业务的收入和成本
  • 劳务派遣企业差额扣除占比过高怎么办
  • 2017年消费税税率
  • 合伙企业对外投资收益怎么纳税
  • 进项税转出如何申报纳税
  • 租赁厂房水电费怎么算
  • 房地产企业预缴增值税什么时候结转
  • 去银行打印公户流水需要带什么
  • 多缴纳的增值税怎么申请抵税
  • 怎么防止电脑被别人远程控制
  • wifi认证失败怎么办
  • 小规模计提增值税的会计科目
  • deepin安装windows字体
  • 按简易办法征收增值税的行为有
  • koeids.dll
  • autorun.exe无法运行
  • php中的类型提示是什么
  • php完整教程
  • 鼓励证券投资基金的政策
  • JavaScript includes() 方法
  • 阿尔莫什
  • 申报表30栏一直不填写会怎么样
  • 应收借方表示什么
  • html盒子边框圆角
  • 机票报销属于什么费
  • Yii2——使用数据库操作汇总(增删查改、事务)
  • 个税申报工资比实发工资少,但没超过5000可以举报吗
  • 现金流量表期初现金余额怎么计算
  • 2020信息采集
  • 结转损益利息收入在哪方
  • 织梦dedecms如何升级ckeditor
  • 小规模季度交税分录怎么做
  • 入股资金打入公司账户
  • 工资发放凭证原件指什么意思
  • 同一控制和非同一控制的区别图解
  • 食堂辅助账的账务处理
  • 代销产品如何做会计分录
  • 进货没开票销售开票了
  • 银行存款收入范围有哪些
  • 暂估成本多久要冲掉
  • 业务协作费计入什么科目
  • 预收账款过多,税务让说明原因
  • 个体工商户记账报税教程
  • 对外投资的会计科目
  • 外账会计做什么
  • 2021年会计做账报税详细流程
  • c3p0连接池提供了哪些方式来配置连接池的参数
  • vc6运行程序
  • win8如何添加启动项
  • 简述linux系统中有哪些文件类型?
  • centos如何添加监听端口
  • 电脑win7在哪
  • macbookpro如何开启查找我的mac
  • centos配置网络地址命令
  • Olehelp.exe - Olehelp是什么进程 有什么用
  • win7怎么开不了机
  • linux apt apt-get
  • 3dmax创建图形怎么用
  • node.js创建服务
  • vue 父子组件通信
  • 深入理解python特性 pdf
  • De facto standard 世界上不可思议的事实标准
  • jquery和css的区别
  • javascript的dom操作
  • js编写一个标准的单例模式类
  • 餐饮专票可以抵扣吗
  • 河南新乡地税局罗姓病逝
  • 南昌高新税务局上班时间
  • 广东省电子税务局app下载官网
  • 现行会计法律法规汇编2022版
  • 缴纳耕地占用税的好处
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设