简单碰撞检测的3D游戏

先还是大体说一下这个程序的原理吧(正方体与球体之间)。


(1)建立相关对象:正方体,3个球体以及为它们铺上纹理
(2)分别为每个对象设定碰撞模式,方法为setCollisionMode(int mode),3个球体为COLLISION_CHECK_OTHERS,cube为COLLISION_CHECK_SELF
(3)将其添加到world对象中,及处理必要的Camera参数
(4)在onDrawFrame函数中进行碰撞处理工作,因为是球体与正方体之间的碰撞,所以采用了相近的椭圆碰撞检测checkForCollisionEllipsoid(如果要用球体检测checkForCollisionSpherical,也能很好工作,这在代码处有相应注释)

(1)Activity类
  1. 1.
    
    2.package sim.feel;
    
    3.import android.app.Activity;
    
    4.import android.content.res.Resources;
    
    5.import android.graphics.Bitmap;
    
    6.import android.graphics.BitmapFactory;
    
    7.import android.opengl.GLSurfaceView;
    
    8.import android.os.Bundle;
    
    9./**
    
    10. * Activity类
    
    11.* 
    
    12. * @author Administrator
    
    13. * 
    
    14. */
    
    15.public class Basic_collision extends Activity {
    
    16. private GLSurfaceView glView;
    
    17. private MyRenderer mr = new MyRenderer();
    
    18. // onCreate
    
    19. public void onCreate(Bundle savedInstanceState) {
    
    20.  super.onCreate(savedInstanceState);
    
    21.  // 传入Resources方法
    
    22.  LoadBitmap.loadb(getResources());
    
    23.  glView = new GLSurfaceView(this);
    
    24.  glView.setRenderer(mr);
    
    25.  setContentView(glView);
    
    26. }
    
    27.}
    
    28.// 载入位图文件
    
    29.class LoadBitmap {
    
    30. public static Bitmap bitmap;
    
    31. // 载入位图方法
    
    32.public static void loadb(Resources res) {
    
    33.  bitmap = BitmapFactory.decodeResource(res, R.drawable.icon);
    
    34. }
    
    35.}
    
    

(2)MyRenderer类
1.

2.package sim.feel;

3.import javax.microedition.khronos.egl.EGLConfig;

4.import javax.microedition.khronos.opengles.GL10;

5.import android.opengl.GLSurfaceView.Renderer;

6.import com.threed.jpct.Camera;

7.import com.threed.jpct.Config;

8.import com.threed.jpct.FrameBuffer;

9.import com.threed.jpct.Logger;

10.import com.threed.jpct.Object3D;

11.import com.threed.jpct.Primitives;

12.import com.threed.jpct.RGBColor;

13.import com.threed.jpct.SimpleVector;

14.import com.threed.jpct.Texture;

15.import com.threed.jpct.TextureManager;

16.import com.threed.jpct.World;

17.import com.threed.jpct.util.MemoryHelper;

18./**

19. * MyRenderer类

20.* 

21. * @author Administrator

22. * 

23. */

24.public class MyRenderer implements Renderer {

25. // FrameBuffer对象

26.private FrameBuffer fb;

27. // World对象

28.private World world;

29. // RGBColor

30. private RGBColor back = new RGBColor(50, 50, 100);

31. // Object3D对象

32.private Object3D sphere1 = null;

33. private Object3D sphere2 = null;

34. private Object3D sphere3 = null;

35. private Object3D cube = null;

36. // SimpleVector

37. // 通过设置组件的x,y,z向量来创建一个SimpleVector对象

38.private SimpleVector move = new SimpleVector(0, 0.3, 1);

39. // 被碰撞Object3D的x,y,z(此处该对象为球体)

40.private SimpleVector ellips = new SimpleVector(7, 7, 7);

41. private SimpleVector tmp = new SimpleVector();

42. // FPS

43. private int fps = 0;

44. private long time = System.currentTimeMillis();

45. private boolean stop = false;

46. // 默认构造

47.// 对该项目的一些优化

48.public MyRenderer() {

49.  // 绘制的最多的Polygon数量,默认为4096,此处如果超过500,则不绘制

50.  Config.maxPolysVisible = 500;

51.  // 最远的合适的平面,默认为1000

52.  Config.farPlane = 1500;

53.  // Modifies the multiplicator for the transparency calculations in

54.  // jPCT-AE. The actual formula is trans=offset+objTrans*mul, default for

55.  // offset is 0.1f.

56.  Config.glTransparencyMul = 0.1f;

57.  // Modifies the offset for the transparency calculations in jPCT-AE. The

58.  // actual formula is trans=offset+objTrans*mul, default for offset is

59.  // 0.1f.

60.  Config.glTransparencyOffset = 0.1f;

61.  // 使JPCT-AE这个引擎使用顶点而不是顶点数组缓冲对象,因为它可能会使某些硬件更快

62.  // 但在Samsung Galaxy,它并不能工作的很好,可能使之崩溃,这就是它默认为false的原因

63.  Config.useVBO = true;

64.  Texture.defaultToMipmapping(true);

65.  Texture.defaultTo4bpp(true);

66. }

67. public void onDrawFrame(GL10 gl) {

68.  try {

69.   if (!stop) {

70.    // Do collision detections(碰撞检测)

71.    // 第1个参数为cube的移动(translation)

72.    // 第2个参数为碰撞的区域大小(ellips)

73.    // 此处的第3个参数为:递归深度的碰撞检测,较高的值将提高碰撞检测精度,而且降低性能。合理的值介于1和5。

74.    // trsn包含当前的坐标信息

75.    SimpleVector trsn = cube.checkForCollisionEllipsoid(move,

76.      ellips, 5);

77.    // 用下面的球体间碰撞也能很好的工作

78.    // SimpleVector trsn = cube.checkForCollisionSpherical(move, 2);

79.    // "移动这个对象通过改变其在JPCT-AE坐标系下的矩阵"

80.    cube.translate(trsn);

81.    // 如果cube当前z轴坐标大于

82.    // 100,重置当前cube的旋转值到默认值,换言之,没有了旋转

83.    if (cube.getTranslation(tmp).z > 50) {

84.     // 清除旋转

85.     cube.clearTranslation();

86.     // 重置为初始值

87.     cube.translate(10, -40, -30);

88.    }

89.    // 以定义好的RGBColor清屏

90.    fb.clear(back);

91.    // 变换和灯光所有的多边形

92.    world.renderScene(fb);

93.    // 绘制由renderScene产生的场景

94.    world.draw(fb);

95.    // 渲染显示图像

96.    fb.display();

97.    // fps加1

98.    fps++;

99.    // 打印输出fps

100.    if (System.currentTimeMillis() - time > 1000) {

101.     System.out.println(fps + "fps");

102.     fps = 0;

103.     time = System.currentTimeMillis();

104.    }

105.   } else {

106.    if (fb != null) {

107.     fb.dispose();

108.     fb = null;

109.    }

110.   }

111.  } catch (Exception e) {

112.   e.printStackTrace();

113.   // 打印异常信息

114.   Logger.log("Drawing thread terminated!", Logger.MESSAGE);

115.  }

116. }

117. public void onSurfaceChanged(GL10 gl, int width, int height) {

118.  if (fb != null) {

119.   fb = null;

120.  }

121.  // 新产生一个FrameBuffer对象

122.  fb = new FrameBuffer(gl, width, height);

123. }

124. public void onSurfaceCreated(GL10 gl, EGLConfig config) {

125.  Logger.log("onCreate");

126.  // 混合渲染

127.  gl.glEnable(GL10.GL_BLEND);

128.  gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

129.  // 新建world对象

130.  world = new World();

131.  // 纹理相关

132.  TextureManager tm = TextureManager.getInstance();

133.  Texture texture2 = new Texture(LoadBitmap.bitmap);

134.  tm.addTexture("texture2", texture2);

135.  // 初始化各3D元素

136.  // 返回一个给定数量的面,第一个20表示面的数量,第二是球体的缩放

137.  sphere1 = Primitives.getSphere(20, 20);

138.  // 以纹理对象的方式给对象包装上纹理

139.  sphere1.calcTextureWrapSpherical();

140.  // 为sphere1设置纹理图片

141.  sphere1.setTexture("texture2");

142.  // 复制当前的Object3D对象

143.  sphere2 = sphere1.cloneObject();

144.  sphere3 = sphere1.cloneObject();

145.  // 返回一个立方体,其中2为其缩放变量

146.  cube = Primitives.getCube(2);

147.  // 以Z轴20处来旋转球体(其实就是向里移动球体)

148.  sphere2.translate(0, 0, 20);

149.  // 以Z轴40处来旋转球体

150.  sphere3.translate(0, 0, 40);

151.  // 以(10, -40, -30)来旋转立方体

152.  cube.translate(10, -40, -30);

153.  cube.setAdditionalColor(RGBColor.GREEN);

154.  // 将3D元素添加到world对象中

155.  world.addObject(sphere1);

156.  world.addObject(sphere2);

157.  world.addObject(sphere3);

158.  world.addObject(cube);

159.  // 建立碰撞模式

160.  sphere1.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);

161.  world.addObject(sphere1);

162.  sphere2.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);

163.  world.addObject(sphere1);

164.  sphere3.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);

165.  world.addObject(sphere1);

166.  // 建立碰撞模式

167.  cube.setCollisionMode(Object3D.COLLISION_CHECK_SELF);

168.  // 设置环境光

169.  world.setAmbientLight(255, 255, 255);

170.  // 编译所有对象

171.  world.buildAllObjects();

172.  // Camera相关

173.  Camera cam = world.getCamera();

174.  // 向里以50的速度移动

175.  cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);

176.  // 向外以60的速度移动

177.  cam.moveCamera(Camera.CAMERA_MOVEUP, 60);

178.  // 以sphere2对象作为中心视角

179.  cam.lookAt(sphere2.getTransformedCenter());

180.  // 回收内存

181.  MemoryHelper.compact();

182. }

183.}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值