基于Android平台的星际射击游戏的设计与实现(5)
来源:56doc.com 资料编号:5D10234 资料等级:★★★★★ %E8%B5%84%E6%96%99%E7%BC%96%E5%8F%B7%EF%BC%9A5D10234
资料介绍
/> </LinearLayout> </RelativeLayout> 在Activity中通过函数setContentView(R.layout.welcome)应用该布局文件。本界面包括一背景图片,和两个控制按钮,效果图如图5-1。 图5-1 菜单选择界面 5.1.2 设置界面的设计与实现 本界面主要用到Android内部提供的对话框控件,对话框采用自定义对话框,布局文件dialog.xml如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:orientation="vertical" Android:layout_width="fill_parent" Android:layout_height="fill_parent"> <TextView Android:text="背景音乐" Android:layout_width="wrap_content" Android:layout_height="wrap_content"/> <RadioGroup Android:id="@+id/rg1" Android:orientation="horizontal" Android:layout_height="wrap_content" Android:layout_width="wrap_content"> <RadioButton Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:id="@+id/rb1" Android:text="开" Android:checked="true"/> <RadioButton Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:id="@+id/rb2" Android:text="关"/> </RadioGroup> <TextView Android:text="音效" Android:layout_width="wrap_content" Android:layout_height="wrap_content"/> <RadioGroup Android:id="@+id/rg2" Android:orientation="horizontal" Android:layout_height="wrap_content" Android:layout_width="wrap_content"> <RadioButton Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:id="@+id/rb3" Android:text="开" Android:checked="true"/> <RadioButton Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:id="@+id/rb4" Android:text="关"/> </RadioGroup> </LinearLayout> 通过Builder类中setView(int)方法应用dialog.xml布局。具体效果图如图5-2。 图5-2 设置界面 5.1.3 游戏主界面 游戏主界面是通过自定义View实现,而不是通过xml文件设计,自定义MyView通过继承SurfaceView,并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView,SurfaceHolder.Callback在底层的Surface状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口: (1) surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不能在这个函数中绘制Surface。 (2) surfaceChanged(SurfaceHolder holder, int format, int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。 (3) surfaceDestroyed(SurfaceHolder holder):当Surface被摧毁前会调用该函数,该函数被调用后就不能继续使用Surface,一般在该函数中来清理使用的资源。通过SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface就在SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或则Canvas lockCanvas(Rect dirty)函数来获取Canvas对象,通过在Canvas上绘制内容来修改Surface中的数据。如果Surface不可编辑或者尚未创建调用该函数会返回null,在unlockCanvas()和lockCanvas()中Surface的内容是不缓存的,所以需要完全重绘Surface的内容,为了提高效率只重绘变化的部分则可以调用lockCanvas(Rect dirty)函数来指定一个dirty区域,这样该区域外的内容会缓存起来。在调用lockCanvas函数获取Canvas后,SurfaceView会获取Surface的一个同步锁直到调用unlockCanvasAndPost(Canvas canvas)函数才释放该锁,这里的同步机制保证在Surface绘制过程中不会被改变(被摧毁、修改)。 Canvas中绘制完成后,调用函数unlockCanvasAndPost(Canvas canvas)来通知系统Surface已经绘制完成,这样系统会把绘制完的内容显示出来。为了充分利用不同平台的资源,发挥平台的最优效果可以通过SurfaceHolder的setType函数来设置绘制的类型,目前接收如下的参数: SURFACE_TYPE_NORMAL:用RAM缓存原生数据的普通Surface。 SURFACE_TYPE_HARDWARE:适用于DMA(Direct memory access)引擎和硬件加速的Surface。 SURFACE_TYPE_GPU:适用于GPU加速的Surface。 SURFACE_TYPE_PUSH_BUFFERS:表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,由Camera负责提供给预览Surface数据,这样图像预览会比较流畅;如果设置这种类型则就不能调用lockCanvas来获取Canvas对象。 |