那个更适合开发游戏,或者说开发什么样的游戏用那个更适合。
SurfaceView双缓冲,主动刷新,线程调用,GL等特点更适合开发画面刷新比较快的游戏。即时类游戏
View适合开发一些被动更新的游戏。如棋盘类,益智类的,有人触发游戏画面在更新的游戏。
-----------------------------------------------------------------------------------------------------------------------------------
下面是是我学习中看到的两位网友博客中的讲解原文如下:
在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 来进行游戏开发。
那么在以后源码实例中,我都会以继承surfaceView框架来进行演示。下一章将详细剖析sarfaceview ,以及附上本人写的游戏开发架构
原文地址: http://blog.csdn.net/xiaominghimi/archive/2010/12/21/6089594.aspx
----------------------------------------------------------------------------------------------------------------------------------
1.view
view在api中的结构
java.lang.Object
android.view.View
直接子类:
AnalogClock, ImageView, KeyboardView, ProgressBar, SurfaceView, TextVie, ViewGroup, ViewStub
间接子类:
AbsListView, AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView<T extends Adapter>, AppWidgetHostView, AutoCompleteTextView, Button, CheckBox, CheckedTextView, Chronometer, CompoundButton, DatePicker, DialerFilter, DigitalClock,EditView, ExpandableListView, ExtractEditText, FrameLayout, GLSurfaceView, Gallery, GestureOverlayView, GridView, HorizontalScrollView, ImageButton, ImageSwitcher, LinearLayout, ListView, MediaController, MultiAutoCompleteTextView, QuickContactBadge, RadioButton, RadioGroup, RatingBar, RelativeLayout, ScrollView, SeekBar, SlidingDrawer, Spinner, TabHost, TabWidget, TableLayout, TableRow, TextSwitcher, TimePicker, ToggleButton, TwoLineListItem, VideoView, ViewAnimator, ViewFlipper, ViewSwitcher, WebView, ZoomButton, ZoomControls
由此可见View类属于Android开发绘制中的显示老大,任何与绘制有关系的控件都是它的子类。在这篇文章中我主要讲View 与SurFaceView 使用线程刷新屏幕绘制方面的知识。开发中如何去选择使用View还是SurFaceView。我相信读过我前几篇博客的朋友应该知道我在刷新屏幕的时候使用invalidate()方法来重绘,下面我详细的说明一下Andooid刷新屏幕的几种方法。
第一种: 在onDraw方法最后调用invalidate()方法,它会通知UI线程重绘 这样 View会重新调用onDraw方法,实现刷新屏幕。 这样写看起来代码非常简洁漂亮,但是它也同时存在一个很大的问题,它和游戏主线程是分开的 它违背了单线程模式,这样操作绘制的话是很不安全的,举个例子 比如程序先进在Activity1中 使用invalidate()方法来重绘, 然后我跳到了Activity2这时候Activity1已经finash()掉 可是Activity1中 的invalidate() 的线程还在程序中,Android的虚拟机不可能主动杀死正在运行中的线程所以这样操作是非常危险的。因为它是在UI线程中被动掉用的所以很不安全。
invalidate() 更新整个屏幕区域
invalidate(Rect rect) 更新Rect区域
invalidate(l, t, r, b) 更新指定矩形区域
public void onDraw(Canvas canvas){
DosomeThing();
invalidate();
}
第二种:使用postInvalidate();方法来刷新屏幕 ,调用后它会用handler通知UI线程重绘屏幕,我们可以 new Thread(this).start(); 开启一个游戏的主线程 然后在主线程中通过调用postInvalidate();方法来刷新屏幕。postInvalidate();方法 调用后 系统会帮我们调用onDraw方法 ,它是在我们自己的线程中调用 通过调用它可以通知UI线程刷新屏幕 。由此可见它是主动调用UI线程的。所以建议使用postInvalidate()方法通知UI线程来刷新整个屏幕。
@Override
public void run() {
while (mIsRunning) {
try {
Thread.sleep(100);
postInvalidate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
View中用到的双缓冲技术
重绘的原理是 程序根据时间来刷新屏幕 如果有一帧图形还没有完全绘制结束 程序就开始刷新屏幕这样就会造成瞬间屏幕闪烁 画面很不美观,所以双缓冲的技术就诞生了。它存在的目的就是解决屏幕闪烁的问题,下面我说说在自定义View中如何实现双缓冲。
首先我们需要创建一张屏幕大小的缓冲图片,我说一下第三个参数 ARGB 分别代表的是 透明度 红色 绿色 蓝色
Bitmap.Config ARGB_4444 ARGB 分别占四位
Bitmap.Config ARGB_8888 ARGB 分别占八位
Bitmap.Config RGB_565 没有透明度(A) R占5位 G 占6位 B占5位
一般情况下我们使用ARGB_8888 因为它的效果是最好了 当然它也是最占内存的。
mBufferBitmap = Bitmap.createBitmap(mScreenWidth,mScreenHeight,Config.ARGB_8888);
创建一个缓冲的画布,将内容绘制在缓冲区mBufferBitmap中
Canvas mCanvas = new Canvas();
mCanvas.setBitmap(mBufferBitmap);
最后一次性的把缓冲区mBufferBitmap绘制在屏幕上,怎么样 简单吧 呵呵。
@Override
protected void onDraw(Canvas canvas) {
/**这里先把所有须要绘制的资源绘制到mBufferBitmap上**/
/**绘制地图**/
DrawMap(mCanvas,mPaint,mBitmap);
/**绘制动画**/
RenderAnimation(mCanvas);
/**更新动画**/
UpdateAnimation();
if(isBorderCollision) {
DrawCollision(mCanvas,"与边界发生碰撞");
}
if(isAcotrCollision) {
DrawCollision(mCanvas,"与实体层发生碰撞");
}
if(isPersonCollision) {
DrawCollision(mCanvas,"与NPC发生碰撞");
}
/**最后通过canvas一次性的把mBufferBitmap绘制到屏幕上**/
canvas.drawBitmap(mBufferBitmap, 0,0, mPaint);
super.onDraw(canvas);
}
由此可见view属于被动刷新, 因为我们做的任何刷新的操作实际上都是通知UI线程去刷新。所以在做一些只有通过玩家操作以后才会刷新屏幕的游戏 并非自动刷新的游戏 可以使用view来操作。
2.SurfaceView
从API中可以看出SurfaceView属于View的子类 它是专门为制作游戏而产生的,它的功能非常强大,最重要的是它支持OpenGL ES库,2D和3D的效果都可以实现。创建SurfaceView的时候需要实现SurfaceHolder.Callback接口,它可以用来监听 SurfaceView的状态,SurfaceView的改变 SurfaceView的创建 SurfaceView 销毁 我们可以在相应的方法中做一些比如初始化的操作 或者 清空的操作等等。
使用SurfaceView构建游戏框架它的绘制原理是绘制前先锁定画布 然后等都绘制结束以后 在对画布进行解锁 最后在把画布内容显示到屏幕上。
代码中是如何实现SurfaceView
首先需要实现 Callback 接口 与Runnable接口
public class AnimView extends SurfaceView implements Callback,Runnable
获取当前mSurfaceHolder 并且把它加到CallBack回调函数中
SurfaceHolder mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
通过callBack接口监听SurfaceView的状态, 在它被创建的时候开启游戏的主线程,结束的时候销毁。这里说一下在View的构造函数中是拿不到view有关的任何信息的,因为它还没有构建好。 所以通过这个监听我们可以在surfaceCreated()中拿到当前view的属性 比如view的宽高 等等,所以callBack接口还是非常有用处的。
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// surfaceView的大小发生改变的时候
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
/**启动游戏主线程**/
mIsRunning = true;
mThread = new Thread(this);
mThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// surfaceView销毁的时候
mIsRunning = false;
}
在游戏主线程循环中在绘制开始 先拿到画布canvas 并使用mSurfaceHolder.lockCanvas()锁定画布,等绘制结束以后 使用mSurfaceHolder.unlockCanvasAndPost(mCanvas)解锁画布, 解锁画布以后画布上的内容才会显示到屏幕上。
try {
long startTime=System.currentTimeMillis();
canvas=sfh.lockCanvas();
logic();
draw(canvas, paint);
long endTime=System.currentTimeMillis();
long useTime=endTime-startTime;
//固定屏幕刷新的时间为50ms
if(useTime<50){
Thread.sleep(50-useTime);
}
} catch (Exception e) {
Log.e("Error", "刷屏线程出错了"+e);
}finally{
if(canvas!=null){
sfh.unlockCanvasAndPost(canvas);
}
}
由此可见SurfaceView 属于主动刷新 ,重绘过程完全是在我们自己的线程中完成 , 由于游戏中肯定会执行各种绚丽的动画效果如果使用被动刷新的View就有可能就会阻塞UI线程,所以SurfaceView 更适合做游戏。
原文地址:http://blog.csdn.net/xys289187120/article/details/6632125
-----------------------------------------------------------------------------------------------------------------------------------
分享到:
相关推荐
在Android游戏开发中,将一个`Button`控件悬浮于`SurfaceView`之上是一项常见的需求。这通常是为了解决在游戏界面中添加交互元素,如暂停、设置或返回按钮,以便用户可以随时进行操作。本篇文章将深入探讨如何实现这...
总的来说,Android开发中的View和SurfaceView各有其适用场景。理解它们的底层工作原理和差异,有助于我们选择合适的方式来构建高性能、低延迟的游戏框架。在构建游戏时,需要权衡性能需求、交互需求以及开发复杂性,...
以上就是关于"迷你小鸟"Android游戏使用SurfaceView开发的详细讲解,希望对你在Android游戏编程的学习之路上有所帮助。接下来,你可以尝试添加更多的元素和功能,比如音效、动画效果,让游戏更加丰富有趣。祝你在...
标题提到的"VIEW双缓冲与SurfaceView比较"是Android系统中处理复杂图形动画时的两种重要技术。本文将深入探讨这两种技术,以及它们在实际开发中的应用场景和优缺点。 首先,让我们来理解一下双缓冲(Double ...
在Android平台上进行游戏开发,SurfaceView是一个至关重要的组件,它为高效、低延迟的图形绘制提供了可能,尤其适合用于创建动态、高性能的游戏画面。本文将深入探讨如何利用SurfaceView进行游戏开发,以及与之相关...
SurfaceView是Android系统提供的一个特殊的View,它拥有自己的独立绘制表面,可以与主线程分离,从而在单独的线程中进行连续的图像更新,避免阻塞UI线程。这对于游戏开发来说,能够确保游戏画面流畅,提高用户体验。...
本示例“Android开发--仿景点通景区地图SurfaceView实现”聚焦于使用SurfaceView来创建一个交互式地图应用,提供了双击放大、多点触摸缩放、地图拖拽以及添加地图标记等功能。下面将详细阐述这些知识点: 1. **...
在Android开发中,View和SurfaceView是两种常用的用于在屏幕上绘制图形和处理用户交互的组件。它们在构建游戏框架时尤为关键,因为游戏通常需要高效地更新和渲染图像。本Demo旨在展示如何利用这两种组件来创建一个...
在Android平台上开发游戏时,SurfaceView是一个至关重要的组件,它为高效、低延迟的图形渲染提供了可能。SurfaceView是Android系统提供的一种特殊视图,它有自己的独立绘制表面,与主线程分离,使得游戏或者视频这类...
在Android开发中,View和SurfaceView是两种非常重要的视图组件,它们被广泛用于构建用户界面和处理图形绘制。这两个类都是Android系统提供用来显示动态内容的机制,但它们之间存在一些关键的区别。 **View组件** ...
在Android开发中,SurfaceView是一种特殊的视图,它允许开发者在应用程序中创建高性能的图形界面,比如游戏或者视频播放器。SurfaceView具有自己的绘制表面,与主线程分离,因此可以进行独立于UI线程的高性能渲染。...
### Android游戏与应用开发最佳学习路线图 #### 一、路线图概览 本学习路线图旨在为初学者提供一个全面且系统的学习路径,帮助其掌握Android应用与游戏开发的核心技能。通过本路线图的学习,学员将能够从零开始...
在Android开发中,View与SurfaceView是两种常用的用于在屏幕上绘制图形和显示内容的组件。它们各有特点,适用场景也有所不同。以下是对这两个组件的区别和用法的详细说明。 首先,View是Android UI系统的基础,它是...
6. **SurfaceView与View的区别** - SurfaceView有自己的Surface,可以在独立的线程中进行绘制,而View必须在主线程中操作。 - SurfaceView的更新不会引起主线程的阻塞,而View的频繁更新可能影响UI的流畅性。 7. ...
#### 一、SurfaceView与游戏开发 在Android平台上开发游戏时,SurfaceView是一个非常重要的组件。它提供了低延迟的显示功能,并且支持双缓冲机制,这对于实时渲染图像非常关键。相比于传统的View组件,SurfaceView...
在Android开发中,SurfaceView是一种特殊的视图,它允许开发者在应用程序中创建一个独立的、高性能的绘图表面。SurfaceView通常用于视频播放、游戏或者需要频繁更新图像的场景。然而,有时候当我们尝试在SurfaceView...
在Android开发中,View和SurfaceView是两种非常重要的视图组件,它们用于在屏幕上显示内容和处理用户交互。本文将详细解析View和SurfaceView的基本概念、用法以及它们之间的区别,通过实例代码来帮助理解。 **一、...
在安卓开发中,`SurfaceView` 是一个非常重要的视图组件,它允许开发者在应用程序中创建一个独立于窗口管理器的表面,这个表面可以用于显示持续更新的图像,如视频播放或者游戏画面。`SurfaceView` 提供了一个优化的...
在Android平台上,SurfaceView是一种特殊的View,用于处理高性能、低延迟的图形绘制,尤其是在开发游戏或者视频播放等需要高效刷新率的应用时。本测试Demo旨在展示如何有效地利用SurfaceView进行游戏开发。以下是对...