10.6 、 Lesson10.java import java.io.IOException; import java.net.URL; import java.util.HashMap; import javax.swing.ImageIcon; import com.jme.app.BaseGame; import com.jme.bounding.BoundingBox; import com.jme.image.Texture; import com.jme.i 10.6、Lesson10.java import java.io.IOException;import java.net.URL;import java.util.HashMap; import javax.swing.ImageIcon; import com.jme.app.BaseGame;import com.jme.bounding.BoundingBox;import com.jme.image.Texture;import com.jme.input.ChaseCamera;import com.jme.input.InputHandler;import com.jme.input.KeyBindingManager;import com.jme.input.KeyInput;import com.jme.input.thirdperson.ThirdPersonMouseLook;import com.jme.light.DirectionalLight;import com.jme.math.FastMath;import com.jme.math.Vector3f;import com.jme.renderer.Camera;import com.jme.renderer.ColorRGBA;import com.jme.renderer.Renderer;import com.jme.scene.Node;import com.jme.scene.Skybox;import com.jme.scene.state.CullState;import com.jme.scene.state.LightState;import com.jme.scene.state.TextureState;import com.jme.scene.state.ZBufferState;import com.jme.system.DisplaySystem;import com.jme.system.JmeException;import com.jme.util.TextureManager;import com.jme.util.Timer;import com.jme.util.export.binary.BinaryImporter;import com.jmex.terrain.TerrainBlock;import com.jmex.terrain.util.MidPointHeightMap;import com.jmex.terrain.util.ProceduralTextureGenerator; publicclass Lesson10 extends BaseGame{ privateintwidth,height; privateintfreq,depth; privatebooleanfullscreen; //我们的camera对象,用于观看scene private Camera cam; protected Timer timer; private Node scene; private TextureState ts; private TerrainBlock tb; private ForceFieldFence fence; private Skybox skybox; private Vehicle player; private ChaseCamera chaser; private InputHandler input; //保存terrain的任何一个给出点的法向 private Vector3f normal = new Vector3f(); privatefloatagl; private Flag flag; private CollisionDetection bounce; private Node walls; //获取距离 privatefloatgrabDistanceSquared = 64f; publicstaticvoid main(String[] args) { Lesson10 app = new Lesson10(); java.net.URL url = app.getClass().getClassLoader().getResource("res/logo.png"); app.setConfigShowMode(ConfigShowMode.AlwaysShow,url); app.start(); } /* * 清除texture */ protectedvoid cleanup() { ts.deleteAll(); } protectedvoid initGame() { display.setTitle("Flag Rush"); scene = new Node("Scene Graph Node"); ZBufferState buf = display.getRenderer().createZBufferState(); buf.setEnabled(true); buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo); scene.setRenderState(buf); buildTerrain(); buildFlag(); buildLighting(); buildEnvironment(); createSkybox(); buildPlayer(); buildChaseCamera(); buildInput(); bounce = new CollisionDetection( player, walls, CollisionDetection.MOVE_BOUNCE_OFF ); CullState cs = display.getRenderer().createCullState(); cs.setCullFace(CullState.Face.Back); scene.setRenderState(cs); //更新scene用于渲染 scene.updateGeometricState(0.0f, true); scene.updateRenderState(); } privatevoid buildFlag() { flag = new Flag(tb); scene.attachChild(flag); flag.placeFlag(); } privatevoid buildInput() { input = new FlagRushInputHandler( player, settings.getRenderer() ); } privatevoid buildChaseCamera() { HashMap props = new HashMap(); props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6"); props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3"); props.put( ThirdPersonMouseLook.PROP_MAXASCENT, ""+45*FastMath.DEG_TO_RAD ); props.put( ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5,0,30*FastMath.DEG_TO_RAD) ); chaser = new ChaseCamera(cam, player, props); chaser.setMaxDistance(8); chaser.setMinDistance(2); } privatevoid buildPlayer() { Node model = null; URL maxFile = Lesson10.class.getClassLoader() .getResource("res/bike.jme"); try { model = (Node)BinaryImporter.getInstance().load( maxFile.openStream() ); model.setModelBound(new BoundingBox()); model.updateModelBound(); model.setLocalScale(0.0025f); } catch (IOException e1) { e1.printStackTrace(); } //设置Vehicle的属性(这些数字能被认为是单元/秒 Unit/S) player = new Vehicle("Player Node",model); player.setAcceleration(15); player.setBraking(25); player.setTurnSpeed(2.5f); player.setWeight(25); player.setMaxSpeed(25); player.setMinSpeed(15); player.setLocalTranslation(new Vector3f(100,0, 100)); player.updateWorldBound(); player.setRenderQueueMode(Renderer.QUEUE_OPAQUE); scene.attachChild(player); scene.updateGeometricState(0, true); agl = ((BoundingBox)(player.getWorldBound())).yExtent; } privatevoid createSkybox() { skybox = new Skybox("skybox",10,10,10); Texture north = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/north.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); Texture south = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/south.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); Texture east = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/east.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); Texture west = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/west.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); Texture up = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/top.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); Texture down = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/texture/bottom.jpg"), Texture.MinificationFilter.BilinearNearestMipMap, Texture.MagnificationFilter.Bilinear ); skybox.setTexture(Skybox.Face.North, north); skybox.setTexture(Skybox.Face.West, west); skybox.setTexture(Skybox.Face.South, south); skybox.setTexture(Skybox.Face.East, east); skybox.setTexture(Skybox.Face.Up, up); skybox.setTexture(Skybox.Face.Down, down); skybox.preloadTextures(); scene.attachChild(skybox); } privatevoid buildEnvironment() { //这将是所有walls的主要结点 walls = new Node("bouncing walls"); scene.attachChild(walls); fence = new ForceFieldFence("forceFieldFence"); //我们将手工做一些调整去让它更好适应terrain //首先我们将实体“模型”放大 fence.setLocalScale(5); //现在,让我们移动fence到terrain的高度并有一点陷入它里面 fence.setLocalTranslation( new Vector3f(25,tb.getHeight(25,25)+10,25) ); //这里我们将它(fence)attach到walls Node walls.attachChild(fence); } privatevoid buildLighting() { /* 设置一个基础、默认灯光 */ DirectionalLight light = new DirectionalLight(); light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); light.setDirection(new Vector3f(1, -1, 0)); light.setEnabled(true); LightState lightState = display.getRenderer().createLightState(); lightState.setEnabled(true); lightState.attach(light); scene.setRenderState(lightState); } /** * 创建heightmap和terrainBlock */ privatevoid buildTerrain() { //生成随机地形数据 MidPointHeightMap heightMap = new MidPointHeightMap(64,1f); //缩放数据 Vector3f terrainScale = new Vector3f(4, .0575f, 4); //创建一个terrain block tb = new TerrainBlock( "terrain", heightMap.getSize(), terrainScale, heightMap.getHeightMap(), new Vector3f(0, 0, 0) ); tb.setModelBound(new BoundingBox()); tb.updateModelBound(); //通过三个纹理生成地形纹理 ProceduralTextureGenerator pt = new ProceduralTextureGenerator(heightMap); pt.addTexture( new ImageIcon( getClass().getClassLoader() .getResource("res/grassb.png") ), -128, 0, 128 ); pt.addTexture( new ImageIcon( getClass().getClassLoader() .getResource("res/dirt.jpg") ), 0, 128, 256 ); pt.addTexture( new ImageIcon( getClass().getClassLoader() .getResource("res/highest.jpg") ), 128, 256, 384 ); pt.createTexture(32); //将纹理赋予地形 ts = display.getRenderer().createTextureState(); Texture t1 = TextureManager.loadTexture( pt.getImageIcon().getImage(), Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true ); ts.setTexture(t1, 0); //加载细节纹理并为2个terrain的texture设置组合模型 Texture t2 = TextureManager.loadTexture( Lesson10.class.getClassLoader() .getResource("res/Detail.jpg"), Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear ); ts.setTexture(t2, 1); t2.setWrap(Texture.WrapMode.Repeat); t1.setApply(Texture.ApplyMode.Combine); t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate); t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor); t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); t2.setApply(Texture.ApplyMode.Combine); t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned); t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); t2.setCombineSrc1RGB(Texture.CombinerSource.Previous); t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); tb.setRenderState(ts); tb.setDetailTexture(1, 16); tb.setRenderQueueMode(Renderer.QUEUE_OPAQUE); scene.attachChild(tb); } protectedvoid initSystem() { //保存属性信息 width = settings.getWidth(); height = settings.getHeight(); depth = settings.getDepth(); freq = settings.getFrequency(); fullscreen = settings.isFullscreen(); try{ display = DisplaySystem.getDisplaySystem( settings.getRenderer() ); display.createWindow( width, height, depth, freq, fullscreen ); cam = display.getRenderer().createCamera(width, height); }catch(JmeException e){ e.printStackTrace(); System.exit(-1); } //设置背景为黑色 display.getRenderer().setBackgroundColor(ColorRGBA.black); //初始化摄像机 cam.setFrustumPerspective( 45.0f, (float)width/(float)height, 1f, 5000f ); Vector3f loc = new Vector3f(200f,1000f,200f); cam.setLocation(loc);// Vector3f left = new Vector3f(-0.5f,0.0f,0.5f);// Vector3f up = new Vector3f(0.0f,1.0f,0.0f);// Vector3f dir = new Vector3f(-0.5f,0.0f,-0.5f);// //将摄像机移到正确位置和方向// cam.setFrame(loc, left, up, dir); //我们改变自己的摄像机位置和视锥的标志 cam.update(); //获取一个高分辨率用于FPS更新 timer = Timer.getTimer(); display.getRenderer().setCamera(cam); KeyBindingManager.getKeyBindingManager().set( "exit", KeyInput.KEY_ESCAPE ); } /* * 如果分辨率改变将被调用 */ protectedvoid reinit() { display.recreateWindow(width, height, depth, freq, fullscreen); } /* * 绘制场景图 */ protectedvoid render(float interpolation) { //清除屏幕 display.getRenderer().clearBuffers(); display.getRenderer().draw(scene); } /* * 在update期间,我们只需寻找Escape按钮 * 并更新timer去获取帧率 */ protectedvoid update(float interpolation) { //更新timer去获取帧率 timer.update(); interpolation = timer.getTimePerFrame(); input.update(interpolation); chaser.update(interpolation);// flag.update(interpolation); fence.update(interpolation); bounce.processCollisions(); //我们想让skybox一直在我们的视野内,所以让它和camera一起移动 skybox.setLocalTranslation(cam.getLocation()); //我们不想chase camera走到世界下面,因此让它一直在水平面上2个单元。 if(cam.getLocation().y tb.getHeight(cam.getLocation())+2)) { cam.getLocation().y = tb.getHeight(cam.getLocation()) + 2; cam.update(); } //确保当玩家离开平面时我们不会坠落。 //当我们增加冲突时,fence将做它自己的工作并保持玩家在里面。 float characterMinHeight = tb.getHeight(player.getLocalTranslation()) + agl; if( !Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight) ) player.getLocalTranslation().y = characterMinHeight; //获取terrain在我们当前位置的normal。 //我们然后将它应用到player上面。 tb.getSurfaceNormal( player.getLocalTranslation(), normal ); if(normal != null) { player.rotateUpTo(normal); } //首先获取Flag和player的距离 float distanceSquared = player.getLocalTranslation().distanceSquared( flag.getLocalTranslation() ); //检查能否获取flag if(distanceSquared grabDistanceSquared){ //重设flag,如果reset不能使用 //请到Flag.java里面将reset方法改为public flag.reset(); player.setFlagsGrabbed(player.getFlagsGrabbed()+1); } //当Escape被按下时,我们退出游戏 if(KeyBindingManager.getKeyBindingManager() .isValidCommand("exit") ){ finished = true; } //由于我们改变了场景(移动skybox),我们需要更新scene graph scene.updateGeometricState(interpolation, true); }} 09-13 14:16