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的详细内容...