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.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.shape.Box;
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.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
public class Lesson5 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 Node player;
private ChaseCamera chaser;
private InputHandler input;
public static void main(String[] args) {
Lesson5 app = new Lesson5();
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();
buildLighting();
buildEnvironment();
createSkybox();
buildPlayer();
buildChaseCamera();
buildInput();
CullState cs = display.getRenderer().createCullState();
cs.setCullFace(CullState.Face.Back);
scene.setRenderState(cs);
//更新scene用于渲染
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
}
private void buildInput() {
input = new FlagRushInputHandler(
player,
settings.getRenderer()
);
}
private void buildChaseCamera() {
Vector3f targetOffset = new Vector3f();
targetOffset.y =
((BoundingBox)player.getWorldBound()).yExtent*1.5f;
HashMap<String, Object> props = new HashMap<String, Object>();
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)
);
props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
chaser = new ChaseCamera(cam, player, props);
chaser.setMaxDistance(8);
chaser.setMinDistance(2);
}
private void buildPlayer() {
//box 代替
Box b = new Box("box", new Vector3f(), 0.35f,0.25f,0.5f);
b.setModelBound(new BoundingBox());
b.updateModelBound();
player = new Node("Player Node");
player.setLocalTranslation(new Vector3f(100,0, 100));
player.attachChild(b);
player.updateWorldBound();
scene.attachChild(player);
}
private void createSkybox() {
skybox = new Skybox("skybox",10,10,10);
Texture north = TextureManager.loadTexture(
Lesson5.class.getClassLoader()
.getResource("res/texture/north.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
);
Texture south = TextureManager.loadTexture(
Lesson5.class.getClassLoader()
.getResource("res/texture/south.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
);
Texture east = TextureManager.loadTexture(
Lesson5.class.getClassLoader()
.getResource("res/texture/east.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
);
Texture west = TextureManager.loadTexture(
Lesson5.class.getClassLoader()
.getResource("res/texture/west.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
);
Texture up = TextureManager.loadTexture(
Lesson5.class.getClassLoader()
.getResource("res/texture/top.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
);
Texture down = TextureManager.loadTexture(
Lesson5.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() {
fence = new ForceFieldFence("forceFieldFence");
//我们将手工做一些调整去让它更好适应terrain
//首先我们将实体“模型”放大
fence.setLocalScale(5);
//现在,让我们移动fence到terrain的高度并有一点陷入它里面
fence.setLocalTranslation(
new Vector3f(25,tb.getHeight(25,25)+10,25)
);
scene.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);
tb.setRenderState(ts);
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(250f,100f,250f);
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);
fence.update(interpolation);
//我们想让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()) +
((BoundingBox)player.getWorldBound()).yExtent;
if(
!Float.isInfinite(characterMinHeight) &&
!Float.isNaN(characterMinHeight)
)
player.getLocalTranslation().y = characterMinHeight;
//当Escape被按下时,我们退出游戏
if(KeyBindingManager.getKeyBindingManager()
.isValidCommand("exit")
){
finished = true;
}
//由于我们改变了场景(移动skybox),我们需要更新scene graph
scene.updateGeometricState(interpolation, true);
}
}
分享到:
相关推荐
FlagRush5——跟随的摄像机(ChaseCamera) FlagRush6——控制交通工具 FlagRush7——拥抱大地让我们驾驶的不再是Box FlagRush8——增加随机的Flag FlagRush9——墙壁检测系统(Detection System) FlagRush10——...
5.5、跟随摄像机(ChaseCamera) 61 5.6、我们自定义的输入处理 62 5.7、源码 65 6、 控制交通工具 74 6.1、介绍 74 6.2、增加一个交通工具 74 6.3、Vehicle.java 76 6.4、Actions 79 6.5、FlagRushHandler.java 81 ...
sdk, 在netbeans上,基于 jMonkeyEngine3 SDK jMonkeyEngine软件开发工具包( SDK ) 欢迎使用jMonkeyEngine软件开发工具包( SDK )的知识库。 这个SDK使用jMonkeyEngine简化了 3D 个应用程序的开发。 它包含开发完整...
NULL 博文链接:https://hjk685.iteye.com/blog/1912303
jmonkeyengine是一个面向冒险的java开发人员的三维游戏引擎。它是开源的、跨平台的、尖端的。3.2.4是jmonkeyengine 3 sdk的最新稳定版本,是一个完整的游戏开发套件。我们将发布3.2.x更新,直到主要的3.3版本到来。
jmonkeyengine, 在Java中,一个完整的3D 游戏开发 jMonkeyEngine jMonkeyEngine是一款用于冒险Java开发人员的3D 游戏引擎。 它是开放的,跨平台的,和... 3.2.0是 jMonkeyEngine 3 SDK的最新稳定版本,一个完整的游戏开
jMonkeyEngine(jME)是一个开源的Java 3D引擎,它的效果非常好,速度也不错
Jmonkeyengine 3.0 Beginners Guide
jMonkeyEngine 3.0 Beginner's Guide
NULL 博文链接:https://snake.iteye.com/blog/578982
jMonkeyEngine软件开发套件(SDK) 欢迎使用jMonkeyEngine软件开发套件(SDK)的存储库。 该SDK简化了使用jMonkeyEngine开发3D应用程序的过程。 它包含开发完整应用程序所需的一切。 我们的SDK(或jmonkeyplatform...
共12章JME中文教程,演示代码经测试无错
jmonkeyengine:纯Java编写的一个完整的3D游戏开发套件
该演示应用程序展示了最新的jME版本jME 3的功能和某些功能。jMonkeyEngine使用OpenGL作为其图形库。 该软件包含的一些功能包括:粒子效果,水渲染,照明,动画,单元碰撞,地形生成,模型和场景,纹理。 这些应用...
jme3-clj-aide JMonkeyEngine3 + Clojure-Android + AIDE 示例项目
jMonkeyEngine 3.0 项目的 gradle 样板 桌面+安卓构建 maven 满足 jme3 依赖项 android sdk 必须在local.properties提供 安卓依赖 android sdk 构建工具 21.1.1 android 支持存储库 8 安卓支持库 21.0.1 执照 新的...
口香糖游戏3d 使用 jMonkeyEngine 的太空口香糖和口香糖机实验性 3D 游戏