OPhone平台2D游戏引擎实现——物理引擎

  • b3_375647
    了解作者
  • 2.1MB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-06 08:14
    上传日期
OPhone平台2D游戏引擎实现——物理引擎(一) OPhone平台开发, 2010-10-19 17:27:20 标签 : Ophone平台 2D 游戏 引擎   上一篇文章我们介绍了常见的各种游戏特效的实现,你现在可以很轻松的实现各种游戏中所需要的特效,但是,你可能已经意识到了,我们的游戏一般都需要进行碰撞检测,比如前面的火柴棍小人,我们需要检测子弹和敌人之间的碰撞;碰撞检测通常是游戏开发的难点,作为引擎必然少不了碰撞检测部分,这里我们还是按照cocos2d的构架,使用Box2d作为物理引擎,下面我们将通过在Ophone平台实现一个小游戏,来对Box2d物理引擎进行学习。   Box2d   Box2D是一个用于游戏的2D刚体仿真库,它可以使物体的运动更加真实,让游戏场景看起来更具交互性。2D物理引擎能增强游戏世界中物体如多边形(砖块,三角形,多边形)的动作的真实感从而提高游戏质量。该引擎通过用户设定的参数如重力,密度,摩擦,弹性等参数计算碰撞,角度,力和动力等。这些计算需要大量的数学,物理等知识,如果有兴趣也可以下载其源码来研究。 Box2d同时也提供了各种语言环境的实现,由于Ophone平台使用java作为变成语言,所以我们将选择使用Box2d的java版JBox2d,这也将产生一个问题,JBox2D是用processing库来处理图像显示,所以Ophone平台上则不适用,在Ophone平台上的图像渲染主要包括两种:Canvas和Opengl ES,因此我们可以任选其中一种,这里为了配合我们的引擎实现,选择通过Opengl ES来作为渲染部分,这部分就需要我们自己来实现,其实我们也可以不使用其图像渲染部分,因为我们主要是使用Box2d来做物理检测,稍后我们会通过一个实例游戏来介绍。 另外,比较优秀的2D物理引擎还有Chipmunk,对于谁好谁坏,我们这里不去评价,如果要使用Chipmunk作为物理引擎会比Box2d稍微苦难一些,因为Chipmunk目前没有Java版本,所以只能通过JNI方式来使用,这就需要使用NDK来开发原生的C程序,使用C语言来做,效率要高很多,但是开发,调试的难度也将增加,有机会我们将可以介绍如何使用NDK来编写C程序,并同时整合Chipmunk物理引擎。 这里只是我们对Box2d的一个简单介绍,让大家明白其用处,关于更多详细信息,大家可以参考其官方网站http://www.box2d.org/,图12-1则是cocs2d中演示的Box2d物理引擎效果,学完这部分内容,你也可以很轻松将其运行在Ophone平台上。   图12-1 cocos2d Iphone Box2d演示   图12-1中这每个方块都具有重力,摩擦力,碰撞检测规则,他们都处于同一个世界场景中,不必眼红Iphone开发者,下面就给大家看一下,我们在Ophone平台提供的示例物理小游戏。 在学习使用Box2D引擎之前,我们需要了解一下一些常用的概念: 刚体(rigid body) 一块十分坚硬的物质,它上面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。我们用物体(body)来代替刚体。 形状(shape) 一块严格依附于物体(body)的 2D 碰撞几何结构(collision geometry)。形状具有摩擦(friction)和恢复(restitution)的材料性质。 约束(constraint) 一个约束(constraint)就是消除物体自由度的物理连接。在 2D 中,一个物体有 3 个自由度。如果我们把一个物体钉在墙上(像摆锤那样),那我们就把它约束到了墙上。这样,此物体就只能绕着这个钉子旋转,所以这个约束消除了它 2 个自由度。 接触约束(contact constraint) 一个防止刚体穿透,以及用于模拟摩擦(friction)和恢复(restitution)的特殊约束。你永远都不必创建一个接触约束,它们会自动被 Box2D 创建。 关节(joint) 它是一种用于把两个或多个物体固定到一起的约束。Box2D 支持的关节类型有:旋转,棱柱,距离等等。关节可以支持限制(limits)和马达(motors)。 关节限制(joint limit) 一个关节限制(joint limit)限定了一个关节的运动范围。例如人类的胳膊肘只能做某一范围角度的运动。 关节马达(joint motor) 一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转。 世界(world) 一个物理世界就是物体,形状和约束相互作用的集合。Box2D 支持创建多个世界,但这通常是不必要的。 这里先给大家介绍就是让大家明白Box2d包括哪些内容,稍后对框架的介绍时就能更加容易理解,当然对于这些具体的功能,我们会在后面跟着示例代码一起学习。   Ophone Box2d   首先分析一下我们在Ophone平台上的Box2dDemo需要实现什么功能,首先我们将整个屏幕构建成一个盒子,然后再盒子中设置各种障碍,当我们触摸屏幕上任意位置时,就释放一个当前选择的物体,然后该物体将受到重力等因素的影响开始运动,直到最后静止下来。运行效果如图12-2所示。   图12-2 OphoneBox2d效果   屏幕中间的长条则是我们设置的障碍,而圆形和矩形都是我们在点击屏幕时要释放的物体,前面我们说过,JBox2d中的图形部分在Ophone中不能用,所以我们会专门介绍如何通过Opengl ES来对图形图像进行渲染,另外,该示例中的这些物体都是通过纹理映射来将图片映射到四边形上。为了大家能掌握图形系统相关内容,我们还实现了一个功能,玩家可以自己设置障碍,只需要点击Menu中,选择"编辑模式"就可以进入障碍编辑状态,如图12-3所似。   图12-3 障碍编辑状态   当障碍编辑完成之后再次选择编辑模式,则恢复到游戏中,此时我们所编辑的这些障碍都会正常的运行。当然该过程我们并没有使用引擎来完成,目的在于让大家更清楚渲染的原理,以及代码能够更多的重用,也就是说,大家可以直接拷贝代码到需要的游戏中去即可。同时大家也能掌握很多Opengl ES的相关知识。   Ophone平台如何使用JBox2d   要使用JBox2d我们首先需要获得其源码或者jar包,这个就不用多说了,知道其官方网站下载即可,这里我们下载了一个完整版本jbox2d-2.0.1-full.jar,让后将其放入我们所建立OphoneBox2d工程的lib文件夹下,JBox2d中大致包含了如图12-4所示的一些包:   图12-4 JBox2d结构图   其中org.jbox2d.collision比较重要,主要负责处理碰撞相关,包括对一些多边形的实现,这里所说的多边形主要是一些数据,比如多边形的位置,大小,重力,形状,质量等属性;org.jbox2d.common包主要用来设置一些全局的属性(Setting.java),调试时所使用的颜色(Color3f.java),以及其他的一些数学相关的内容,因为我们说了Box2d他主要不是来做渲染的,但是有时候我们需要知道所设置的这些物体是否正确,进行调试,就需要绘制这些简单的图形,并显示出来,供我们调试;org.jbox2d.dynamics包主要负责动力学相关的内容,下面是常见的功能包描述。 org.jbox2d.collision包 AABB:AABB坐标 OBB:OBB坐标 ContactID:接触ID ContactPoint:接触点 ManifoldPoint:繁殖点 Segment:线段 Shape:外形基类 ShapeDef:外形定义基类 CircleDef:圆外形定义 CircleShape:圆外形 FilterData:碰撞过滤器 MassData:质量运算器 PolygonDef:多边开定义 PolygonShape:凸多边形 org.jbox2d.common包 Color3f:调试绘图颜色 Settings:全局设置 Mat22:2*2 矩阵 Sweep:碰撞描述 Vec2:向量(x ,y) XForm:坐标转换,平移或旋转 标准的版本中还会存在Mat33表示3*3的矩阵和Vec3向量(x,y,z),该java版本中没有出现这些。 org.jbox2d.dynamics包 Body:刚体或叫物体 BodyDef:刚体定义 BoundaryListener:世界边界侦听 ContactFilter:继承这个类用来获取过滤碰撞 ContactListener:继承这个类用来获取碰撞结果 DebugDraw:调试绘图,用于调试 DestructionListener:关节或外形销毁时处理方法 World:物理世界 org.jbox2d.dynamics.contacts Contact:管理两个外形接触 ContactEdge:接触边用来连接多个物体和接触到一个接触表 ContactResult:记录接触结果 org.jbox2d.dynamics.Joints DistanceJoint:距离校正器 DistanceJointDef:距离连接定义 GearJoint:齿轮 GearJointDef:齿轮连接定义 Joint:连接基类 JointDef:连接定义基类 JointEdge:用于组合刚体或连接到一起.刚体相当于节点,而连接相当于边 MouseJoint:鼠标连接 MouseJointDef:鼠标连接定义 PrismaticJoint:棱柱连接 PrismaticJointDef:棱柱连接定义 PulleyJoint:滑轮连接 PulleyJointDef:滑轮连接定义 RevoluteJoint:旋转连接 RevoluteJointDef:旋转连接定义 org.jbox2d.testbed:主要是一些用来测试的程序 添加JBox2d到Ophone项目中   要在工程中使用JBox2d库,需要将JBox2d添加到工程中,添加方法如下: 右键单击工程,选择"Properties",进入项目Properties界面。 选择"Java Build Path",选择"Libraries"选项卡。 在点击"Add Jars..."按钮,添加Jar。 选择当前工程中我们之前放入lib文件夹中的jbox2d-2.0.1-full.jar文件,如图12-5所示,单击"确定"按钮即可。   图12-5 添加jbox2d-2.0.1-full.jar   OphoneBox2d框架   现在工程的结构展开应该如图12-6所示。   图12-6 OphoneBox2d项目结构   其中实现该工程的文件如下: Box2dTest:工程Activity,入口 GameGLSurfaceView:游戏GLSurfaceView GLRenderer:Opengl es渲染器 DrawObject:使用Opengl ES来绘制常用图形(矩形,圆形) PhysicsWorld:物理世界场景   OphoneBox2d实现   开始分析代码之前,我们先确定一下需要准备的资源图片,从图12-2所示,我们可以看出,多少需要一个矩形和一个圆形的图片(当然也可直接指定颜色绘制矩形和圆形),这里我们将使用图片来进行纹理映射,该工程所需要的纹理图片如图12-7所示。    图12-7 资源图片   Box2dTest实现   该类继承自Activity,将作为本程序的入口,授予我们是通过Opengl ES来渲染的,所以构建需要构建一个GLSurfaceView对象作为Opengl ES的窗口,然后通过setContentView函数来设置显示该窗口视图。然后分别在onPause和onResume函数中调用GLSurfaceView类的GLSurfaceView。当然这也是所有Opengl ES程序的渲染基础框架,所有的Opengl ES程序窗口都由GLSurfaceView来实现。具体实现入代码清单12-1所示。
OphoneBox2d.rar
内容介绍
package com.yarin.ophone.OponeBox2d; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import org.jbox2d.collision.CircleShape; import org.jbox2d.collision.PolygonShape; import org.jbox2d.common.Vec2; import org.jbox2d.dynamics.Body; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.opengl.GLU; import android.view.MotionEvent; import android.opengl.GLSurfaceView.Renderer; public class GLRenderer implements Renderer { // GLSurfaceView.Renderer //窗口的宽度和高度 private int width; private int height; private PhysicsWorld mWorld; //物理世界 private DrawObject mBox; //box对象 private DrawObject mLongBox; //矩形条对象, 就用来画一个小长条模型 private DrawObject mCircle; //圆形对象 private DrawObject mTriangle; //三角形对象 ,佳佳写的 private DrawObject mFiveXing; //正五边形对象 ,佳佳写的 private int activeModel = 0; //当前选择的模型 private boolean editMode = false; //是否处于编辑状态 private Context mContext; //Context,用于装载资源 private float startX, endX, startY, endY; //保存鼠标的坐标 // private DrawObject img; //佳佳的图片 ???? /*函数中我们首先定义了矩形盒子、矩形条、圆形的模型对象,稍后再绘制这些对象是都将通过他们来绘制, * 然后通过调用PhysicsWorld的createWorld函数构建一个物理世界mWorld, * 并且向物理世界中添加了三个矩形静态物体和一个圆形静态物体. */ public GLRenderer(Context newContext) { mContext = newContext; //????????? //构造(顶点数组,纹理数组,索引数组,顶点数) //public DrawObject(float[] coords, float[] tcoords, short[] icoords, int vertexes) //定一个box ,是一个正方形 mBox = new DrawObject( new float[]{ -1,-1,0, 1,-1,0, 1, 1,0, -1, 1 ,0 }, new float[]{ 0f,1f, 1f,1f, 1f,0f, 0f,0f }, //原来的 // new float[]{ 0f,0f, 1f,0f, 1f,1f, 0f,1f }, //顺方向的 // new float[]{ 0f,0f, 1f,0f, 0f,1f, 1f,1f }, //折方向的 new short[]{ 0,1,2,3,0 }, 5 ); //定义一个长条 mLongBox = new DrawObject(new float[]{ -.2f,-2f,0, .2f,-2f,0, .2f, 2f,0, -.2f, 2f,0 }, new float[]{ 0f,1f, 1f,1f, 1f,0f, 0f,0f }, new short[]{ 0, 1, 2, 3, 0 }, 5 ); //圆形 mCircle = new DrawObject( new float[]{ 0f, 0f,0f, 0f, 1f,0f, -.5f, .866f,0f, -.866f, .5f,0f, -1f, 0f,0f, -.866f, -.5f,0f, -.5f,-.866f,0f, 0f, -1f,0f, .5f,-.866f,0f, .866f, -.5f,0f, 1f, 0f,0f, .866f, .5f,0f, .5f, .866f,0f, 0f, 1f,0f }, new float[]{ 0.5f, 0.5f, 0.5f, 0.0f, .25f,.067f, .067f, .25f, 0.0f, 0.5f, .067f, .75f, .25f,.933f, 0.5f, 1.0f, .75f,.933f, .933f, .75f, 1.0f, 0.5f, .933f, .25f, .75f,.067f, .5f, .0f }, new short[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0 }, 14 ); // 12圆上的点 + 1个中心点 = 13 ,另外一个点是多余的 //三角形 mTriangle = new DrawObject( new float[]{ -1,-1,0, 1,-1,0, 0, 1,0, -1, -1,0 }, new float[]{ 0f,1f, 1f,1f, 1f,0f, 0f,0f }, new short[]{ 0,1,2,0 }, 3 ); //正五边形 mFiveXing = new DrawObject( new float[]{Coordinate.five[0].x, Coordinate.five[0].y , 0, Coordinate.five[1].x, Coordinate.five[1].y , 0, Coordinate.five[2].x, Coordinate.five[2].y , 0, Coordinate.five[3].x, Coordinate.five[3].y , 0, Coordinate.five[4].x, Coordinate.five[4].y , 0, }, new float[]{ 0f,1f, 1f,1f, 1f,0f, 0f,0f , 0f,0f }, new short[]{ 0,1,2,3,4, 0 }, 5 ); //创建一个物理场景 mWorld = new PhysicsWorld(); mWorld.createWorld(); //向物理场景添加两个实体 (中心坐标,物体半径,旋转角度,是否静态) //addBox(float x, float y, float xr, float yr, float angle, boolean dynamic) mWorld.addBox( 0f, -25f, 50f, 10f, 0f, false); // 地面 mWorld.addBall(0f, -15f, 7f, false); // 半圆形的地面 mWorld.addBox(-12f, -25f, 0.6f, 40f, 0f, false); // 这是两边的两个大的长条 mWorld.addBox( 12f, -25f, 0.6f, 40f, 0f, false); // 这是两边的两个大的长条 //mWorld.addBox(-16f, -25f, 0.6f, 40f, 0f, false); // 佳佳的两个大的长条 //mWorld.addBox( 16f, -25f, 0.6f, 40f, 0f, false); // 佳佳的两个大的长条 /* mWorld.addBall(0f, -13f, 7f, false); // 半圆形的地面,共有12点组成的 mWorld.addBox( 0f, -21f, 12f, 1f, 0f, false); // 地面 mWorld.addBox( 0f, 0f, 1f, 1f, 1.04f, false); // 地面 mWorld.addBox( 0f, 0f, 1f, 1f, 1.04f, false); // 地面 mWorld.addBox( 0f, 8f, 1f, 1f, 0f, true ); mWorld.addBall(0f, 15f, 3f, true ); mWorld.addBall(8f, 18f, 1f, true ); //小圆模型,和模型一般大小的 */ // mWorld.addBox( 4f, 8f, 3f, 3f, 0f, false ); //创建静态的正方形 // 在物理世界创建一个三角形,使之与画图的图形相一致 //addTriangle(float x, float y, float angle, boolean dynamic) // mWorld.addTriangle( 0f, 15f, 0, false ); // 在物理世界创建一个正五边形,使之与画图的图形相一致 // addFiveXing(float x, float y, float angle, boolean dynamic) // mWorld.addFiveXing(0f, 0f, 0
评论
    相关推荐
    • cocos2d-x卡通机器人
      cocos2d-x2.2.5写的物理引擎的使用,解压后添加文件和resource到自己的工程编译运行即可
    • cocos2d-x 实例源码
      愤怒的松鼠,完整源码cocos2d-x编写
    • cocos2d-x实现全屏
      參考了一下NeHe 的教程, 在 cocos2d-x 2.0 上可以做點小手腳在 Windows 上全屏顯示! 參考了一下NeHe 的教程, 在 cocos2d-x 2.0 上可以做點小手腳在 Windows 上全屏顯示! 主要修改兩個檔案: CCEGLView.h ...
    • mkcsb:Cocos Studio csb文件生成器usign edge(或任何版本)cocos2d-x
      这是使用边缘cocos2d-x的csd到csb生成器。 描述 如果您使用边缘cocos2d-x,有时会损坏cocosstudio csb文件。 该工具使用“ editor-support / cocostudio / FlatBuffersSerialize.h”在不使用Cocos Studio的情况下...
    • Cocos2d-xGameTest
      接触cocos2d-x有几天了,确实是一个强大好用的引擎~主要原因是开源呵呵,一个简单的cocos2d-X游戏源码
    • Cocos2d手势
      为实现Cocos2d手势支持,改写的CCLayer、CCNode、CCGestureRecognizer三个源码类,可以参考我博客使用!
    • cocos2d-x_Box2d实例代码
      学习cocos2dx后自己整的物理引擎(box2d)的类似helloworld的示例代码。cocos2d-x_Box2d实例代码,完整可运行的工程例子。对初学cocos2dx的物理引擎开发的同志们非常有用!
    • cocos2d-x2.0
      cocos2d-x2.0
    • cocos2d物理引擎测试
      物理引擎的简单应用代码,给大家分享物理引擎的简单应用代码,给大家分享物理引擎的简单应用代码,给大家分享物理引擎的简单应用代码,给大家分享,
    • Cocos2D-X 一个都不能死
      cocos2d-x开发的一个都不能死游戏的简单示例,可能并没有那么正统,但运行应该不会出问题,比较适合入门吧。