简单碰撞检测的3D游戏

来源:互联网 发布:js event.target 编辑:程序博客网 时间:2024/04/26 10:53
先还是大体说一下这个程序的原理吧(正方体与球体之间)。


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

(1)Activity类
    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 Administrator13. * 14. */15.public class Basic_collision extends Activity {16. private GLSurfaceView glView;17. private MyRenderer mr = new MyRenderer();18. // onCreate19. 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 Administrator22. * 23. */24.public class MyRenderer implements Renderer {25. // FrameBuffer对象26.private FrameBuffer fb;27. // World对象28.private World world;29. // RGBColor30. 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. // SimpleVector37. // 通过设置组件的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. // FPS43. 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.  // 最远的合适的平面,默认为100052.  Config.farPlane = 1500;53.  // Modifies the multiplicator for the transparency calculations in54.  // jPCT-AE. The actual formula is trans=offset+objTrans*mul, default for55.  // offset is 0.1f.56.  Config.glTransparencyMul = 0.1f;57.  // Modifies the offset for the transparency calculations in jPCT-AE. The58.  // actual formula is trans=offset+objTrans*mul, default for offset is59.  // 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加198.    fps++;99.    // 打印输出fps100.    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