计算机游戏程序设计.doc_第1页
计算机游戏程序设计.doc_第2页
计算机游戏程序设计.doc_第3页
计算机游戏程序设计.doc_第4页
计算机游戏程序设计.doc_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机游戏程序设计一、游戏背景介绍随着手持式终端的日渐强大,移动手持设备在模拟现实方面的技术日趋成熟。人们在移动设备上可以体验到比以往更加真实的视觉冲击和立体效果,同时伴随着人们对模拟现实类游戏的青睐,使得此类手机休闲游戏得到了迅速的发展。现在快节奏的生活让人们无时无刻不存在着紧张感,无论是生活还是工作,上班还是下班,学习还是工作,烦恼紧张无处不在。这个时代下车辆已经相当普及,所以老司机也不在少数,这就催生了很多模拟驾驶汽车游戏的诞生,这些游戏既放松了心情又锻炼了技术因此深受大众欢迎。也正因为如此,市场上大多数的驾驶类游戏都是驾驶着机车运送货物或者搭载人。这些游戏极其考验技术,在保证正常行驶的情况下也必须保证所要运送货物或者搭载乘客的安全,像3D巴士驾驶员、3D学校驾驶如图-1、图-2所示都是此类游戏中很不错的典型。 图-1 3D 巴士驾驶员 图-2 3D 学校驾驶“泥路卡车”是使用OpenGL ES 3.0开发的一款基于Android平台的休闲类游戏,本游戏利用了JBullet物理引擎,下面将对本游戏进行详细的介绍。上面简单地介绍了本游戏的开发背景,现在将对该游戏的主要功能进行简单的介绍。包括游戏UI界面的展示,按钮的功能详细介绍以及游戏场景的展示。(1)运行游戏,首先进入的是欢迎界面,如图-3所示。经过欢迎界面后进入游戏的加载界面,如图-4所示,这里是游戏中所有资源加载的界面,在这里进度条将随着资源加载的进度而进行读条,资源加载完毕同时读条也完毕。 图-3 欢迎界面 图-4 加载界面(2)读条完毕后进入本游戏的主菜单界面,如图-5所示,从这里可以通过单击不同的功能按钮进入到不同的界面。点击主菜单界面的设置按钮进入设置界面,如图-6所示,设置界面包含音乐与音效两个开关,点击该界面ON/OFF部分即可实现音乐与音效的开关。 图-5主菜单界面 图-6 设置界面(3)点击主菜单界面的帮助按钮进入帮助界面,如图-7所示,帮助界面显示了本游戏的基本操作以及需要注意的事项。点击关于按钮进入游戏的关于界面,如图-8所示,关于界面显示了我们的开发团队的具体信息以及警示信息用以保护版权归属。 图-7 帮助界面 图-8关于界面(4)点击退出游戏按钮时会弹出一个toast,如图-9所示,这是为了防止玩家无意按中退出键来提示玩家是否真的退出游戏。接下来便是游戏的主体部分,点击开始游戏后,如图-10所示,进入选关界面,玩家可以点击第一关或者第二关开始游戏。 图-9 退出界面toast 图-10 选关界面(5)进入游戏以后玩家就可以正式开启游戏之旅了,如图-11所示,游戏过程中玩家会遇到各种障碍或者凹凸不平、高低起伏的路面,这些阻碍会使车上箱子掉下车去。一旦车上箱子数目少于俩个便会结束游戏,如图-12所示。 图-11 游戏第一关界面 图-12 游戏输之后界面(6)有时候玩家小心翼翼地开车为了不使箱子从车上掉下去从而忽视了游戏界面顶端的剩余时间,这个时间是限定玩家必须在规定时间内将货物送达终点,玩家若是单方面注意箱子数量而不注意时间的话在时间快结束便会出现警报并伴随着警报声,如图-13所示。 图-13 警报界面 图-14 暂停界面(7)游戏过程中玩家可以点击右上角的按钮暂停,如图-14所示,这是为了游戏途中玩家在现实中有事而设计的。玩家在规定时间内完成了任务,终于能进入到下一关时便会弹出如图-15所示的图片,此时玩家根据自己情况进而选择下一关或者重新进行。 图-15 第一关结束界面 图-16 游戏第二关界面(8)每一关的游戏难度不同,规定时间也有所不同,但是最终目标都是将货物在规定时间内送到规定地点,若玩家完成第一关游戏后想要继续挑战更难的则可以点击进入下一关,如图-16所示,本关将会有较上一关更难的地形与,趣味与紧张并存。二、核心算法思想在游戏中,经常需要进行碰撞检测的实现,例如判断前面是否有障碍以及判断子弹是否击中飞机,都是检测两个物体是否发生碰撞,然后根据检测的结果做出不同的处理。进行碰撞检测的物体可能有些的形状和复杂,这些需要进行组合碰撞检测,就是将复杂的物体处理成一个一个的基本形状的组合,然后分别进行不同的检测。碰撞问题包括碰撞检测和碰撞响应两个方面的内容。碰撞检测用来检测不同对象之间是否发生了碰撞,碰撞响应是在碰撞发生后,根据碰撞点和其他参数促使发生碰撞的对象作出正确的动作,以反映真实的动态效果。碰撞检测方法:按照对象所处的空间分:二维平面碰撞检测和三维空间碰撞检测。按检测的方法长区分为:空间分解法,层次包围盒法。一般规则的物体碰撞都可以处理成矩形碰撞,实现的原理就是检测两个矩形是否重叠。我们假设矩形1的参数是:左上角的坐标是(x1,y1),宽度是w1,高度是h1;矩形2的参数是:左上角的坐标是(x2,y2),宽度是w2,高度是h2。在检测时,数学上可以处理成比较中心点的坐标在x和y方向上的距离和宽度的关系。即两个矩形中心点在x方向的距离的绝对值小于等于矩形宽度和的二分之一,同时y方向的距离的绝对值小于等于矩形高度和的二分之一。下面是数学表达式:x方向:|(x1+w1/2)(x2+w2/2)|(w1+w2)/2|y方向:|(y1+h1/2)(y2+h2/2)|(h1+h2)/2|在程序中,只需要将上面的条件转换成代码就可以实现了,但是矩形碰撞只是一种比较粗糙的碰撞检测方法。例如本游戏中的树、石头等物体的碰撞形状并没有采用本身的形状,因为采用采用本身形状顶点太多,计算量过大影响性能,便用胶囊状代替,在视觉上没有什么太大区别。除了碰撞检测的实现外本游戏中还开发了多线程架构,游戏中多线程架构首先需要开一个物理计算线程,将游戏中需要进行物理计算的部分写到该线程中,进行完一轮物理计算后将车身刚体信息、车轮刚体信息、箱子的刚体信息的计算结果存入到本地的变量组中。然后加锁将本地变量组中的这些数据送入到全局数据中,此时一轮物理计算线程完毕。物理线程一轮一轮的运行,在每轮运行之前会判断是否继续运行,每一轮运行结束后也会视情况休息一段时间。物理线程计算完之后还需要开一个绘制线程,本游戏中的绘制线程就是游戏界面中的绘制方法,在每轮绘制线程开始时都会加锁从全局数据中读取数据进本地数据,读取结束后绘制线程根据本地数据中的各数据来绘制,因为绘制线程中绘制的物体是根据物理计算后得到物体,全局数据中的数据为物理线程经过物理计算后得到的物理数据结果数据,所以需要每轮都向全局数据中取得数据进行绘制,绘制完毕一轮绘制线程结束。三、核心算法流程图在游戏界面的绘制方法开始我们就在一直说本地数据、全局数据、物理计算线程等这些名词,这些贯穿游戏开发始终的东西都是多线程架构下的一部分内容,接下来我们来看一下此部分的架构图,如图-18所示为多线程的架构图。图-18 游戏多线程架构图如架构图所示,物理线程中运行过程先进行物理计算,计算完毕后计算的结果会存到物理线程自身的本地变量组中,作为临时存放处,之后便会将这些数据加锁送到全局数据中去。全局数据中声明了所有的物理计算所相关的数据对象数组,在每轮物理计算线程运行完毕时全局数据中都会储存着当前一轮物理计算的结果,之后绘制线程会加锁从全局数据中取出数据放到绘制线程中的本地数组中,之后绘制线程会取得这些数据,并根据这些数据进行绘制。这就是一轮多线程异步架构的进程。在不同界面切换时为了实现无延时切换也开发了一套算法,在接下来的代码部分会详细介绍这部分,如图-19所示为切换界面示意图。图-19 切换界面架构图游戏中GLsurfacView类是程序的主绘制类,其中包含了整个游戏的架构,游戏中所有的显示界面都是通过主绘制类的不同逻辑调用所实现的,其通过声明所有界面的父类对象,用这个对象指向不同对象实现不同界面的切换,其中在加载界面进行绘制时将游戏中所有资源都会加载完毕,之后的界面切换的延时肉眼是看不出来的。四、源代码GLSurfaceView类是整个游戏的绘制类,为整个游戏的呈现类。整个游戏除欢迎界面外其余所有界面均通过此类显示,包括加载界面、菜单界面、关于界面、设置界面、游戏界面、帮助界面等界面。开发该类的详细步骤如下。(1)首先开发的是GLSurfaceView类,GLSurfaceView类是主绘制类,其中包含了整个游戏的架构,游戏中所有的显示界面都是通过主绘制类的不同逻辑调用所实现的,其通过声明所有界面的父类对象,用这个对象指向不同对象实现不同界面的切换,具体代码如下。public class GlSurfaceView extends GLSurfaceView public static SelectViewBN selectview;/初始化界面public static GameViewBN gameview1;/第一关界面public static GameViewBN gameview2;/第二关界面public static BNAbstractView currView;/初始化游戏加载界面的父类public static LoadViewBN loadview;/加载界面GameActivity activity;SenceRenderer mRenderer;DiscreteDynamicsWorld dynamicsWorld;CarShadowData shadowdata = new CarShadowData();public float ratio;public GlSurfaceView(GameActivity activity,DiscreteDynamicsWorld dynamicsWorld) super(activity);this.activity = activity;this.dynamicsWorld = dynamicsWorld;this.setEGLContextClientVersion(3); / 设置使用OPENGL ES3.0this.setEGLConfigChooser(8, 8, 8, 8, 16, 8);mRenderer = new SenceRenderer();/ 创建场景渲染器this.setRenderer(mRenderer);/ 设置渲染器/ 设置渲染模式为主动渲染this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);Overridepublic boolean onTouchEvent(MotionEvent e) if (currView = null) return false;return currView.onTouchEvent(e);class SenceRenderer implements GLSurfaceView.Renderer Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) / 设置屏幕背景色RGBAGLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);/ 打开深度检测GLES30.glEnable(GLES30.GL_DEPTH_TEST);/ 打开背面剪裁GLES30.glEnable(GLES30.GL_CULL_FACE);GLES30.glBlendFunc(GLES30.GL_SRC_ALPHA,GLES30.GL_ONE_MINUS_SRC_ALPHA);/ 初始化变换矩阵MatrixState.setInitStack();/ 初始化光源方向MatrixState.setLightDirection(-2f,1,0);ShaderManager.loadShaderScriptAndCompiled(GlSurfaceView.this.getResources();loadview=new LoadViewBN(dynamicsWorld, activity, GlSurfaceView.this);currView=loadview;Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) GLES30.glViewport(int) Constant.sx, (int) Constant.sy,(int) (1920 * Constant.ratio), (int) (1080 * Constant.ratio);/ 计算GLSurfaceView的宽高比ratio = (float) 1920/1080;Overridepublic void onDrawFrame(GL10 gl) if (currView != null) currView.drawView(gl);/ 绘制界面信息(2)接下来开发的是除欢迎界面之外所有界面的父类界面类BNAbstractView,该类有三个抽象方法需要每个继承该类的子类重写,进而在主界面GLSurfaceView中实现不同界面的方法到该类去具体调用不同的方法以完成不同的目的。public abstract class BNAbstractView public abstract void initView();/初始化资源public abstract boolean onTouchEvent(MotionEvent e);/触控public abstract void drawView(GL10 gl);/绘制界面(3)加下来开发的是欢迎界面类,欢迎界面是进入游戏的第一个界面,该界面显示了游戏的出处,进入后会发现欢迎图片的透明度会发生改变,代码中是通过控制图片的透明度来达到欢迎动画的效果,具体开发如下。public class WelcomeView extends SurfaceView implements SurfaceHolder.Callback/实现生命周期回调接口static Bitmap logos;/logo图片数组static boolean loadFlag=false;/是否加载图片的标志位GameActivity activity;/activity的引用Bitmap currentLogo;/当前logo图片引用Paint paint; /画笔int currentAlpha=0; /当前的不透明值int sleepSpan=50; /动画的时延msfloat currentX; /图片位置float currentY;ScreenScaleResult ssr;public WelcomeView(GameActivity activity)super(activity);this.activity = activity; this.loadBitmap();/加载图片this.getHolder().addCallback(this); /设置生命周期回调接口的实现者paint = new Paint(); /创建画笔paint.setAntiAlias(true); /打开抗锯齿 /将图片加载进内存的方法public void loadBitmap() currentLogo=BitmapFactory.decodeResource(this.getResources(),R.drawable.flash); /重写onDraw方法 public void onDraw(Canvas canvas)if(canvas!=null)canvas.save();canvas.scale(Constant.ratio,Constant.ratio); canvas.translate(Constant.sx,Constant.sy);/绘制黑填充矩形清背景paint.setColor(Color.BLACK);/设置画笔颜色paint.setAlpha(255);canvas.drawRect(0, 0,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论