jMonkeyEngine译文 FlagRush10(2)墙壁检测系统(Detection S
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.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);
}
}

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

This article explores optimizing MySQL memory usage in Docker. It discusses monitoring techniques (Docker stats, Performance Schema, external tools) and configuration strategies. These include Docker memory limits, swapping, and cgroups, alongside

This article addresses MySQL's "unable to open shared library" error. The issue stems from MySQL's inability to locate necessary shared libraries (.so/.dll files). Solutions involve verifying library installation via the system's package m

The article discusses using MySQL's ALTER TABLE statement to modify tables, including adding/dropping columns, renaming tables/columns, and changing column data types.

This article compares installing MySQL on Linux directly versus using Podman containers, with/without phpMyAdmin. It details installation steps for each method, emphasizing Podman's advantages in isolation, portability, and reproducibility, but also

This article provides a comprehensive overview of SQLite, a self-contained, serverless relational database. It details SQLite's advantages (simplicity, portability, ease of use) and disadvantages (concurrency limitations, scalability challenges). C

This guide demonstrates installing and managing multiple MySQL versions on macOS using Homebrew. It emphasizes using Homebrew to isolate installations, preventing conflicts. The article details installation, starting/stopping services, and best pra

Article discusses configuring SSL/TLS encryption for MySQL, including certificate generation and verification. Main issue is using self-signed certificates' security implications.[Character count: 159]

Article discusses popular MySQL GUI tools like MySQL Workbench and phpMyAdmin, comparing their features and suitability for beginners and advanced users.[159 characters]
