当前位置: 首页 > news >正文

【Android2D游戏开发之二】剖析游戏开发用view还是sarfaceView

 在Android游戏当中充当主要的除了控制类外就是显示类,在J2ME中我们用Display和Canvas来实现这些,而Google Android中涉及到显示的为view类,Android游戏开发中比较重要和复杂的就是显示和游戏逻辑的处理。 

这里我们说下android.view.View和android.view.SurfaceView。SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView,到底有哪些优势呢? SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了SurfaceHolder类,使用getHolder方法获取,相关的有Canvas lockCanvas() 
Canvas lockCanvas(Rect dirty) 、void removeCallback(SurfaceHolder.Callback callback)、void unlockCanvasAndPost(Canvas canvas) 控制图形以及绘制,而在SurfaceHolder.Callback 接口回调中可以通过重写下面方法实现。 

使用的SurfaceView的时候,一般情况下要对其进行创建,销毁,改变时的情况进行监视,这就要用到 SurfaceHolder.Callback. 
class XxxView extends SurfaceView implements SurfaceHolder.Callback { 

public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){} 
//看其名知其义,在surface的大小发生改变时激发 
public void surfaceCreated(SurfaceHolder holder){} 
//同上,在创建时激发,一般在这里调用画图的线程。 
public void surfaceDestroyed(SurfaceHolder holder) {} 
//同上,销毁时激发,一般在这里将画图的线程停止、释放。 



对于Surface相关的,Android底层还提供了GPU加速功能,所以一般实时性很强的应用中主要使用SurfaceView而不是直接从View构建,同时后来做android 3d OpenGL中的GLSurfaceView也是从该类实现。 


SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。 
那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。 
当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。 

所以基于以上,根据游戏特点,一般分成两类。 

1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。 

2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

3.Android中的SurfaceView类就是双缓冲机制。因此,开发游戏时尽量使用SurfaceView而不要使用View,这样的话效率较高,而且SurfaceView的功能也更加完善。

 考虑以上几点,所以我一直都选用 SurfaceView 来进行游戏开发。

那么在以后源码实例中,我都会以继承sarfaceView框架来进行演示。下一章将详细剖析sarfaceview ,以及附上本人写的游戏开发架构

相关文章:

  • android中 自定义两个View进行画图,如何让其各自刷新重绘
  • ActivityGroup实现Tab分页标签
  • 自定义Menu(TabMenu)
  • Android上图像处理-倒影,圆角,渐变
  • Activity的任务堆栈学习笔记(一)
  • activity的任务堆栈学习笔记二
  • Android 简史
  • android textview 中超出屏幕宽度的字符 省略号显示
  • 【原创·视频·教程】大话优酷、酷六类视频网站Android端软件开发
  • Android线程相关
  • 横竖屏切换时候activity的生命周期 android:configChanges
  • 以Dialog形式显示Activity
  • Android面试题
  • Windows下JNI生成头文件
  • Android如何改变模拟器大小
  • CentOS从零开始部署Nodejs项目
  • express如何解决request entity too large问题
  • HTML中设置input等文本框为不可操作
  • k8s 面向应用开发者的基础命令
  • Wamp集成环境 添加PHP的新版本
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 飞驰在Mesos的涡轮引擎上
  • 数组大概知多少
  • 学习ES6 变量的解构赋值
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​iOS安全加固方法及实现
  • ​油烟净化器电源安全,保障健康餐饮生活
  • !!Dom4j 学习笔记
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #14vue3生成表单并跳转到外部地址的方式
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (汇总)os模块以及shutil模块对文件的操作
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)【Hibernate总结系列】使用举例
  • .gitignore文件—git忽略文件
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET6 命令行启动及发布单个Exe文件
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .NET正则基础之——正则委托
  • /*在DataTable中更新、删除数据*/
  • [ C++ ] STL---string类的使用指南
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [AIGC] Redis基础命令集详细介绍
  • [Android Pro] listView和GridView的item设置的高度和宽度不起作用
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]
  • [leetcode] 3Sum
  • [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列
  • [Linux] 进程间通信基础