callback接口:

只要继承SurfaceView类并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView了,SurfaceHolder.Callback在底层的Surface状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口:

surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。

    surfaceChanged(SurfaceHolder holder, int format, int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。

SurfaceHolder 类:

  它是一个用于控制surface的接口,它提供了控制surface 的大小,格式,上面的像素,即监视其改变的。

  SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface 就在SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或则Canvas lockCanvas()函数来获取Canvas对象,通过在Canvas上绘制内容来修改Surface中的数据。如果Surface不可编辑或则尚未创建调用该函数会返回null,在 unlockCanvas() 和 lockCanvas()中Surface的内容是不缓存的,所以需要完全重绘Surface的内容,为了提高效率只重绘变化的部分则可以调用lockCanvas(Rect rect)函数来指定一个rect区域,这样该区域外的内容会缓存起来。在调用lockCanvas函数获取Canvas后,SurfaceView会获取Surface的一个同步锁直到调用unlockCanvasAndPost(Canvas canvas)函数才释放该锁,这里的同步机制保证在Surface绘制过程中不会被改变(被摧毁、修改)。

// 备注2

  我没有在该surfaceview的初始化函数中将其 ScreenW 与 ScreenH 进行赋值,这里要特别注意,如果你在初始化调用ScreenW = this.getWidth();和ScreenH = this.getHeight();那么你将得到很失望的值 全部为0;原因是和接口Callback接口机制有关,当我们继承callback接口会重写它的surfaceChanged()、surfaceCreated()、surfaceDestroyed(),这几个函数当surfaceCreated()被执行的时候,真正的view才被创建,也就是说之前得到的值为0 ,是因为初始化会在surfaceCreated()方法执行以前执行,view没有的时候我们去取屏幕宽高肯定是0,所以这里要注意这一点;

//备注3

  这里我把draw的代码都try起来,主要是为了当画的内容中一旦抛出异常了,那么我们也能 在finally中执行该操作。这样当代码抛出异常的时候不会导致Surface出去不一致的状态。

  surfaceview中确实有 onDraw这个方法,但是surfaceview不会自己去调用!!!

  而我代码中的ondraw 也好 draw 也好,都是我自己定义的一个方法。。。放在线程中不断调用的,一定要注意!!

,在继承view中,因为onDraw方法是系统自动调用的,不像在surfaceview这里这样去在run里面自己去不断调用, 在view中我们可以抵用 invalidate()/postInvalidate() 这两种方法实现让系统调用onDraw方法,这里也是和surfaceview中的不同之一!

其实这就是一个简单的游戏架构了,当然还少了按键处理,声音播放等等......

剖析游戏开发用view还是sarfaceView

1: 在J2ME中我们用Display和Canvas来实现这些,而Google Android中涉及到显示的为view类,Android游戏开发中比较重要和复杂的就是显示和游戏逻辑的处理

2: SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView,到底有哪些优势呢? SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了SurfaceHolder类

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

4:SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。

5:当使用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 来进行游戏开发。

终于做到在SurfaceView中添加组件!!!!并且相互交互数据!!!!

那么在SurfaceView 中并一同显示组件也就到底完结了,回顾下,一共分为3步,1.将我们的SurfaceView 作为一个组件view 和其他组件一同放置到布局中,当然布局的方式和显示的方式大家自己随自己喜欢定义! 2.在我们的SurfaceView中一定要使用两个构造函数的构造函数,一定!一定! 就这里有区别,别的还是该怎么处理就怎么处理,就是构造函数换了 3.交互数据,对其按键的绑定在 activity中完成,别把view绑定在咱们的SurfaceView中啊,否则报错- -、 \\\

游戏中添加音频-详解MediaPlayer与SoundPool的利弊以及各个在游戏中的用途

使用MediaPlayer来播放音频文件存在一些不足:

例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。

这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,例如在对时间精准度要求相对较高的游戏开发中。

相对于使用SoundPool存在的一些问题:

1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能使用一些很短的声音片段,而不是用它来播放歌曲或者游戏背景音乐(背景音乐可以考虑使用JetPlayer来播放)。

2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。 
3. 音频格式建议使用OGG格式。使用WAV格式的音频文件存放游戏音效,经过反复测试,在音效播放间隔较短的情况下会出现异常关闭的情况(有说法是SoundPool目前只对16bit的WAV文件有较好的支持)。后来将文件转成OGG格式,问题得到了解决。

4.在使用SoundPool播放音频的时候,如果在初始化中就调用播放函数进行播放音乐那么根本没有声音,不是因为没有执行,而是SoundPool需要一准备时间!囧。当然这个准备时间也很短,不会影响使用,只是程序一运行就播放会没有声音罢了,所以我把SoundPool播放写在了按键中处理了

SoundPool最大只能申请1M的内存空间,这就意味着我们只能使用一些很短的声音片段

触屏事件中的Bug解决方案以及禁止横屏和竖屏切换

在某些游戏中我们可能需要禁止横屏和竖屏切换,其实实现这个要求很简单,只要在

AndroidManifest.xml 里面加入这一行 android :screenOrientation="landscape "(landscape 是横向,portrait 是纵向)。

在android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置。在activity加上android:configChanges="keyboardHidden|orientation"属性,就不会重启activity.而是去调用onConfigurationChanged(Configuration newConfig). 这样就可以在这个方法里调整显示方式.

第一点:

在surfaceview中我们的onKeyDown 虽然是重写了view的函数,但是仍然需要在初始化的时候去声明获取焦点,setFocusable(true); 如果不调用此方法,那么会造成按键无效。原因是因为如果是自己定义一个继承自View的类,重新实现onKeyDown方法后,只有当该View获得焦点时才会调用onKeyDown方法,Actvity中的onKeyDown方法是当所有控件均没有处理该按键事件时,才会调用.

第二点:

也是今天主要需要讲得的触屏响应的函数,onTouchEvent()! 重写此函数的时候默认最后一句是依照基类的返回方式,return super.onTouchEvent(event); 然后我们在其中去判定 MotionEvent.ACTION_MOVE、MotionEvent.ACTION_DOWN、MotionEvent.ACTION_UP 相对应触屏操作的 拖动、按下、抬起;对此一切都是正确的,但是真正的的运行起项目的时候发现 Log.v("Himi", "ACTION_MOVE"); 这里log的"ACTION_MOVE",永远不会执行!!!为此我找到了解决方法,那么先解释下为什么会出现此类情况。

剖析 SurfaceView Callback以及SurfaceHolder相关推荐

  1. SurfaceView 使用及SurfaceHolder.Callback() 回调方法分析

    Demo,点击按钮,在子线程内绘制颜色切换的矩形 activity_main.xml <?xml version="1.0" encoding="utf-8&quo ...

  2. Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

    转载请包含网址:http://blog.csdn.net/pathuang68/article/details/7351317 一.Surface Surface就是"表面"的意思 ...

  3. surfacecontrol.java_简单说说JAVA层中Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系...

    1.Surface Surface extends Object implements Parcelable java.lang.Object android.view.Surface Class O ...

  4. Android之——Surface、SurfaceView与SurfaceHolder.Callback初探

    一.Surface    Surface在SDK的文档中的描述是这样的:Handle onto a raw buffer that is being managed by the screen com ...

  5. android surfaceholder的数据,Surface、SurfaceView、SurfaceHolder详解

    一.Surface Surface就是"表面"的意思.在SDK的文档中,对Surface的描述是这样的:"Handle onto a raw buffer that is ...

  6. SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceHolder、Surface

    SurfaceView.GLSurfaceViewe\SurfaceTexture.TextureView.SurfaceHolder.Surface 一.简介 SurfaceTexture: Sur ...

  7. SurfaceView、SurfaceHolder与Surface

    相关文章 SurfaceView.SurfaceHolder与Surface TextureView.SurfaceTexture与Surface 按照官方文档的说法,SurfaceView继承自Vi ...

  8. android中的surfaceSurface、SurfaceHolder及SurfaceHolder.Callback

    一.Surface     Surface在SDK的文档中的描述是这样的:Handle onto a raw buffer that is being managed by the screen co ...

  9. SurfaceView surface SurfaceHolder制作简单的相机

    简单的相机界面布局 <?xml version="1.0" encoding="utf-8"?> <android.support.desig ...

最新文章

  1. iOS toolchain based on clang for linux
  2. Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构
  3. UVa 11466 - Largest Prime Divisor
  4. POJ3666序列最小差值
  5. 秒懂数据类型的真谛—Python基础前传(4)
  6. Python 模板语言
  7. 114.maven+springmvc+spring+mybaties 项目整合
  8. 【剑指Offer】15顺时针打印矩阵
  9. MFC (opencv配置) 应用程序无法正常启动(0xc000007b)请单击“确定关闭应用程序 的解决方法
  10. Dev-C++的下载和安装
  11. word字体放大后只显示一半_word字体显示不全或是显示一半怎么回事如何解决
  12. 【性能监测】前端性能监测方法总结(非监测平台)
  13. 移植 μC/OS-III 到 STM32
  14. linux下kegg注释软件,网页工具KOBAS进行KEGG富集分析
  15. labview 霍夫曼树_Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)
  16. ffmpeg - 视频裁剪
  17. ProcessStartInfo处理方法
  18. 网络直播不应只是秀场,新的场景机会在哪?
  19. java getiotype_坑爹微信之读取PKCS12流时出现的java.io.IOException: DerInputStream.getLength...
  20. oracle计算两个日期的相差的小时数、分钟数、秒数

热门文章

  1. 东方PHP授权系统修复版盗版检测源码
  2. PHP响应式H5图片网盘外链系统源码 自适应PC手机端
  3. C# 使用Task执行异步操作
  4. Bootstrap 3 响应式上传图片,时间拾取器和表单认证 Fileinput, Date/Time Pickr, Validator...
  5. Ubuntu连接SSHHow to: Connect SSH, SFTP and FTP Servers using Nautilus ubuntu 13.04
  6. python画图入门
  7. eclipse 取消自动括号补全
  8. DNS服务器 安装部署 以及子域授权和转发
  9. mysql 字符,索引
  10. 【notebook】常用在线notebook总结