好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

jMonkeyEngine译文FlagRush9(2)墙壁检测系统(DetectionSy

9.5 、 Lesson9.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.inp

9.5 、 Lesson9.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;

public class Lesson9 extends BaseGame{

private int width , height ;

private int freq , depth ;

private boolean fullscreen ;

// 我们的 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();

private float agl ;

private Flag flag ;

private CollisionDetection bounce ;

private Node walls ;

public static void main(String[] args) {

Lesson9 app = new Lesson9();

java.net.URL url = app.getClass().getClassLoader().getResource( "res/logo.png" );

app.setConfigShowMode(ConfigShowMode. AlwaysShow ,url);

app.start();

}

/*

* 清除 texture

*/

protected void cleanup() {

ts .deleteAll();

}

protected void 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();

}

private void buildFlag() {

flag = new Flag( tb );

scene .attachChild( flag );

flag .placeFlag();

}

private void buildInput() {

input = new FlagRushInputHandler(

player ,

settings .getRenderer()

);

}

private void 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);

}

private void buildPlayer() {

Node model = null ;

URL maxFile = Lesson9. 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 ;

}

private void createSkybox() {

skybox = new Skybox( "skybox" ,10,10,10);

Texture north = TextureManager. loadTexture (

Lesson9. class .getClassLoader()

.getResource( "res/texture/north.jpg" ),

Texture.MinificationFilter. BilinearNearestMipMap ,

Texture.MagnificationFilter. Bilinear

);

Texture south = TextureManager. loadTexture (

Lesson9. class .getClassLoader()

.getResource( "res/texture/south.jpg" ),

Texture.MinificationFilter. BilinearNearestMipMap ,

Texture.MagnificationFilter. Bilinear

);

Texture east = TextureManager. loadTexture (

Lesson9. class .getClassLoader()

.getResource( "res/texture/east.jpg" ),

Texture.MinificationFilter. BilinearNearestMipMap ,

Texture.MagnificationFilter. Bilinear

);

Texture west = TextureManager. loadTexture (

Lesson9. class .getClassLoader()

.getResource( "res/texture/west.jpg" ),

Texture.MinificationFilter. BilinearNearestMipMap ,

Texture.MagnificationFilter. Bilinear

);

Texture up = TextureManager. loadTexture (

Lesson9. class .getClassLoader()

.getResource( "res/texture/top.jpg" ),

Texture.MinificationFilter. BilinearNearestMipMap ,

Texture.MagnificationFilter. Bilinear

);

Texture down = TextureManager. loadTexture (

Lesson9. 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 );

}

private void 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 );

}

private void 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

*/

private void 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 (

Lesson9. 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 );

}

protected void 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

);

}

/*

* 如果分辨率改变将被调用

*/

protected void reinit() {

display .recreateWindow( width , height , depth , freq , fullscreen );

}

/*

* 绘制场景图

*/

protected void render( float interpolation) {

// 清除屏幕

display .getRenderer().clearBuffers();

display .getRenderer().draw( scene );

}

/*

* 在 update 期间,我们只需寻找 Escape 按钮

* 并更新 timer 去获取帧率

*/

protected void 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 );

}

// 当 Escape 被按下时,我们退出游戏

if (KeyBindingManager. getKeyBindingManager ()

.isValidCommand( "exit" )

){

finished = true ;

}

// 由于我们改变了场景(移动 skybox ),我们需要更新 scene graph

scene .updateGeometricState(interpolation, true );

}

}

9.6 、 CollisionDetection.java

import com.jme.bounding.BoundingBox;

import com.jme.image.Texture;

import com.jme.math.FastMath;

import com.jme.math.Vector3f;

import com.jme.renderer.ColorRGBA;

import com.jme.scene.Controller;

import com.jme.scene.Node;

import com.jme.scene.Spatial;

import com.jme.scene.state.BlendState;

import com.jme.scene.state.RenderState;

import com.jme.scene.state.TextureState;

import com.jme.system.DisplaySystem;

import com.jme.util.TextureManager;

import com.jmex.effects.particles.ParticleFactory;

import com.jmex.effects.particles.ParticleSystem;

import com.jmex.effects.particles.SimpleParticleInfluenceFactory;

public class CollisionDetection {

private Vehicle player ;

private Node target ;

private int nextMove ;

private float zExtent ;

public static final int MOVE_BOUNCE_OFF = 0;

public static final int MOVE_STOP = 1;

private ParticleSystem particleGeom ;

public CollisionDetection(

Vehicle player, Node target, int nextMove){

this . player = player;

this . target = target;

this . nextMove = nextMove;

this . zExtent = ((BoundingBox)(player.getWorldBound())). zExtent ;

createParticles();

}

public CollisionDetection(

Vehicle play

查看更多关于jMonkeyEngine译文FlagRush9(2)墙壁检测系统(DetectionSy的详细内容...

  阅读:46次