`
ilovezhurong
  • 浏览: 44808 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

jme学习笔记例11

阅读更多

import com.jme.app.SimpleGame;
import com.jme.app.BaseGame;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.Text;
import com.jme.scene.shape.Box;
import com.jme.scene.state.*;
import com.jme.input.*;
import com.jme.util.Timer;
import com.jme.util.TextureManager;
import com.jme.util.LoggingSystem;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.math.Vector3f;
import com.jme.image.Texture;
import com.jme.light.PointLight;
import java.util.logging.Level;
/**
* Started Date: Jul 29, 2004<br><br>
*
* Is used to demonstrate the inner workings of SimpleGame.
*
* @author Jack Lindamood
*/
public class HelloSimpleGame extends BaseGame {
public static void main(String[] args) {
HelloSimpleGame app = new HelloSimpleGame();
app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
/** The camera that we see through. */
protected Camera cam;
/** The root of our normal scene graph. */
protected Node rootNode;
/** Handles our mouse/keyboard input. */
protected InputHandler input;
/** High resolution timer for jME. */
protected Timer timer;
/** The root node of our text. */
protected Node fpsNode;
/** Displays all the lovely information at the bottom. */
protected Text fps;
/** Simply an easy way to get at timer.getTimePerFrame(). */
protected float tpf;
/** True if the renderer should display bounds. */
protected boolean showBounds = false;
65
/** A wirestate to turn on and off for the rootNode */
protected WireframeState wireState;
/** A lightstate to turn on and off for the rootNode */
protected LightState lightState;
/** Location of the font for jME's text at the bottom */
public static String fontLocation = "com/jme/app/defaultfont.tga";
/**
* This is called every frame in BaseGame.start()
* @param interpolation unused in this implementation
* @see com.jme.app.AbstractGame#update(float interpolation)
*/
protected final void update(float interpolation) {
/** Recalculate the framerate. */
timer.update();
/** Update tpf to time per frame according to the Timer. */
tpf = timer.getTimePerFrame();
/** Check for key/mouse updates. */
input.update(tpf);
/** Send the fps to our fps bar at the bottom. */
fps.print("FPS: " + (int) timer.getFrameRate() + " - " +
display.getRenderer().getStatistics());
/** Call simpleUpdate in any derived classes of SimpleGame. */
simpleUpdate();
/**
Update controllers/render states/transforms/bounds for
rootNode.
*/
rootNode.updateGeometricState(tpf, true);
/**
If toggle_wire is a valid command (via key T), change
wirestates.
*/
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_wire", false)) {
wireState.setEnabled(!wireState.isEnabled());
rootNode.updateRenderState();
}
/**
If toggle_lights is a valid command (via key L),
change lightstate.
*/
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_lights", false)) {
lightState.setEnabled(!lightState.isEnabled());
rootNode.updateRenderState();
}
66
/**
If toggle_bounds is a valid command (via key B),
cha
nge bounds.
*/
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_bounds", false)) { showBounds = !showBounds;
}
/**
If camera_out is a valid command (via key C), show camera
location.
*/
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("camera_out", false)) {
System.err.println("Camera at: " + display.getRenderer().getCamera().getLocation()); } }
/**
* This is called every frame in BaseGame.start(), after update()
* @param interpolation unused in this implementation
* @see com.jme.app.AbstractGame#render(float interpolation)
*/
protected final void render(float interpolation) {
/**
Reset display's tracking information for
number of triangles/vertexes
*/
display.getRenderer().clearStatistics();
/** Clears the previously rendered information. */
display.getRenderer().clearBuffers();
/** Draw the rootNode and all its children. */
display.getRenderer().draw(rootNode);
/**
If showing bounds, draw rootNode's bounds, and the
bounds of all its children.
*/
if (showBounds)
display.getRenderer().drawBounds(rootNode);
/** Draw the fps node to show the fancy information at the bottom. */
display.getRenderer().draw(fpsNode);
/** Call simpleRender() in any derived classes. */ simpleRender(); }
/**
* Creates display, sets up camera, and binds keys.
* Called in BaseGame.start() directly after
* the dialog box.
* @see com.jme.app.AbstractGame#initSystem() */
67
protected final void initSystem() {
try {
/**
Get a DisplaySystem acording t
o the renderer
selected in the startup box.
*/
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
/** Create a window with the startup box's information. */
display.createWindow(
properties.getWidth(),
properties.getHeight(),
properties.getDepth(),
properties.getFreq(),
properties.getFullscreen());
/**
Create a camera specific to the DisplaySystem that works
with the display's width and height
*/
cam =
display.getRenderer().createCamera(
display.getWidth(), display.getHeight());
} catch (JmeException e) {
/**
If the displaysystem can't be initialized correctly,
exit instantly.
*/
e.printStackTrace(); System.exit(1); }
/** Set a black background.*/ display.getRenderer().setBackgroundColor(ColorRGBA.black);
/** Set up how our camera sees. */
cam.setFrustumPerspective(45.0f,
(float) display.getWidth() /
(float) display.getHeight(), 1, 1000);
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
/** Move our camera to a correct place and orientation. */
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Assign the camera to this renderer.*/ display.getRenderer().setCamera(cam);
/** Create a basic input controller. */
input = new FirstPersonHandler(this, cam, properties.getRenderer());
/** Signal to all key inputs they should work 10x faster. */
input.setKeySpeed(10f); input.setMouseSpeed(1f);
68
/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer(properties.getRenderer());
/** Sets the title of our displa
y. */
display.setTitle("SimpleGame");
/**
Signal to the renderer that it should keep track of
rendering information.
*/ display.getRenderer().enableStatistics(true);
/** Assign key T to action "toggle_wire". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_wire",
KeyInput.KEY_T);
/** Assign key L to action "toggle_lights". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_lights",
KeyInput.KEY_L);
/** Assign key B to action "toggle_bounds". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_bounds",
KeyInput.KEY_B);
/** Assign key C to action "camera_out". */
KeyBindingManager.getKeyBindingManager().set(
"camera_out", KeyInput.KEY_C); }
/**
* Creates rootNode, lighting, statistic text, and other basic
* render states.
* Called in BaseGame.start() after initSystem().
* @see com.jme.app.AbstractGame#initGame()
*/
protected final void initGame() {
/** Create rootNode */ rootNode = new Node("rootNode");
/** Create a wirestate to toggle on and off. Starts disabled with
* default width of 1 pixel. */
wireState = display.getRenderer().createWireframeState();
wireState.setEnabled(false); rootNode.setRenderState(wireState); /** Create a ZBuffer to display pixels closest to the camera
above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true); buf.setFunction(ZBufferState.CF_LEQUAL); rootNode.setRenderState(buf);
// -- FPS DISPLAY // First setup alpha state
69
/** This allows correct blending of text and what is already
rendered below it*/
AlphaState as1 = display.getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_AL
PHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER); as1.setEnabled(true);
// Now setup font texture
TextureState font = display.getRenderer().createTextureState();
/** The texture is loaded from fontLocation */
font.setTexture(
TextureManager.loadTexture(
SimpleGame.class.getClassLoader().getResource(
fontLocation),
Texture.MM_LINEAR,
Texture.FM_LINEAR,
true)); font.setEnabled(true);
// Then our font Text object.
/** This is what will actually have the text at the bottom. */
fps = new Text("FPS label", "");
fps.setForceView(true); fps.setTextureCombineMode(TextureState.REPLACE);
// Finally, a stand alone node (not attached to root on purpose)
fpsNode = new Node("FPS node");
fpsNode.attachChild(fps);
fpsNode.setRenderState(font);
fpsNode.setRenderState(as1); fpsNode.setForceView(true);
// ---- LIGHTS
/** Set up a basic, default light. */
PointLight light = new PointLight();
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.setLocation(new Vector3f(100, 100, 100)); light.setEnabled(true);
/** Attach the light to a lightState and the lightState to rootNode. */
lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.attach(light); rootNode.setRenderState(lightState);
/** Let derived classes initialize. */ simpleInitGame(); /** Update geometric and rendering information for both the
rootNode and fpsNode. */ rootNode.updateGeometricState(0.0f, true);
70
rootNode.updateRenderState();
fpsNode.updateGeometricState(0.0f, true);
fpsNode.updateRenderState();
}
protected void simpleInitGame() {
rootNode.attachChild(new Box("my box",
new Vector3f(0,0,0), new Vector3f(1,1,1)));
}
/**
* Can be defined in derived classes for custom updating.
* Called every frame in update.
*/ protected void simpleUpdate() {}
/**
* Can be defined in derived classes for custom rendering.
* Called every frame in render.
*/ protected void simpleRender() {}
/**
* unused
* @see com.jme.app.AbstractGame#reinit()
*/
protected void reinit() { }
/**
* Cleans up the keyboard.
* @see com.jme.app.AbstractGame#cleanup()
*/
protected void cleanup() {
LoggingSystem.getLogger().log(Level.INFO, "Cleaning up resources.");
input.getKeyBindingManager().getKeyInput().destroy(); InputSystem.getMouseInput().destroy(); } }

这个程序介绍了wireframestate, 定时器,draw(),摄像机创建,和显示系统创建,你将学到如何创建和定制你的入口类,
这将给simplegame带来一些神秘的作用.
    这么多的代码你感到无从下手吧,我们先看开头:
public static void main(String[] args) {
HelloSimpleGame app = new HelloSimpleGame();
app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
app.start();
} 
让我们看app.start()
public final void start() {
LoggingSystem.getLogger().log(Level.INFO, "Application started.");
try {
getAttributes();
initSystem();
assertDisplayCreated();
initGame();
//main loop
while (!finished && !display.isClosing()) {
//update game state, do not use interpolation parameter
update( -1.0f);
//render, do not use interpolation parameter
render( -1.0f);
//swap buffers
72
display.getRenderer().displayBackBuffer();
}
} catch (Throwable t) {
t.printStackTrace();
}
cleanup();
LoggingSystem.getLogger().log(Level.INFO, "Application ending.");
display.reset();
quit();
} 
别被这个吓着,我们看程序调用的顺序
1) getAttributes(): 得到用户选择的 monkey dialog box属性
2) initSystem(): 调用initSystem() 创建 “system” 部分
3) assertDisplayCreated(): 检查显示系统是否被创建
4) initGame(): 初始化游戏
5) while ():  游戏在什么地方运行
6) update(-1): 调用update()改变对象值
7) render(-1): 调用render() 绘制对象值
8) displayBackBuffer() : 显示全部以前绘制的
9) 循环直到完成
10) cleanup() -- quit() : 关闭应用
这个顺序是渲染系统的基础. 让我们看 initSystem():

protected final void initSystem() {
try {
/**
Get a DisplaySystem acording to the renderer
selected in the startup box.
*/
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
/** Create a window with the startup box's information. */
display.createWindow(
properties.getWidth(),
properties.getHeight(),
properties.getDepth(),
properties.getFreq(),
properties.getFullscreen());

这里我们使用你输入的参数对游戏进行设置. 
注意DisplaySystem 是一个singleton类 我么需要初始化静态方法 getDisplaySystem.
对我们的眼睛来说什么颜色是最适合的? 下一步我们创建摄像机:
/**
Create a camera specific to the DisplaySystem that works
with
the display's width and height
*/
cam =
display.getRenderer().createCamera(
display.getWidth(),
display.getHeight());

用renderer’s给出的高和宽创建摄像机, 下面我简单地创建背景颜色,这里没有什么复杂的

/** Set a black background.*/
display.getRenderer().setBackgroundColor(ColorRGBA.black);  
现在你要为你的数学抓狂了!我们要建立一个视锥:
/** Set up how our camera sees. */
cam.setFrustumPerspective(45.0f,
(float) display.getWidth() /
(float) display.getHeight(), 1, 1000); 

jme的视锥是如何消隐对象的(比如一个三维物体的背面让其不可见)
请看下面的图片:



 连接的文章包含了一个非常好的如何消隐视锥的文章
这里我高度建议你如果对jme的内部机制感兴趣。你可以看到这个例子的视锥是一个被切割的金字塔
我定义视锥的视角是投影到屏幕的高和宽,看起来像图片中的表述,除了3d,每个事物看起来都如图片中
黄色区域,在定义我们的摄像机之后,我移动摄像机向后一个点:
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
74
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
/** Move our camera to a correct place and orientation. */
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Assign the camera to this renderer.*/

方法setFrame() 定为了摄像头的位置, 
这个方向是根据摄像头上下决定的。 
摄像头的信息被设置后,
 我必须更新摄像头 (类似更新renderstates, geometry, 和 sounds),设置摄像头被渲染. 下一步,我们创建
基础的移动按键使用一个预定义的类叫FirstPersonHandler

/** Create a basic input controller. */
input = new FirstPersonHandler(this, cam, properties.getRenderer());
/** Signal to all key inputs they should work 10x faster. */
input.setKeySpeed(10f);
input.setMouseSpeed(1f); 



 InputHandler类提供键盘和鼠标的控制,你的主程序你将制作一个扩展 InputHandler的类并定义你的输入句柄,
在这里,你的主游戏你将使用FirstPersonHandler,它定义鼠标和ADW键移动
注意我们设置key的速度是10倍快,通知FirstPersonHandler的readers10倍速度。
例如你可以让你的游戏切换走路和跑步两种状态,下面我使用一个timer更新我的FPS:
FirstPersonHa/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer(properties.getRenderer()); ndler extends InputHandler.

这个定时器使用'ticks'去获得非常精确的相隔帧的时间间隔,我们使用定时器去更新,最后,我设置一个
计数器并为显示设置一个标题:
/** Sets the title of our display. */
display.setTitle("SimpleGame");
/**
Signal to the renderer that it should keep track of
rendering information.
*/
display.getRenderer().enableStatistics(true); 


最后,我绑定T,L.B,C建和初始换系统,现在这个系统被初始化了,我设置游戏部分。
开始创建我的根节点,创建节点的渲染状态:
/** Create a wirestate to toggle on and off. Starts disabled with
* default width of 1 pixel. */
wireState = display.getRenderer().createWireframeState();
wireState.setEnabled(false);
75
rootNode.setRenderState(wireState);
/** Create a ZBuffer to display pixels closest to the camera
above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
rootNode.setRenderState(buf); 

首先是一个wirestate
The first is a wirestate. 
无论何时你按T的时候会使用,它绘制网线,不完全填充三角形。
随后我创建一个ZBufferState用来告诉rootnode如何渲染屏幕顶端的每个像素.绘制最接近你眼睛的方法,
 这是我设置buffer绘制LEQUAL开销要小,之后rootnode有它的渲染状态,为fpsnode显示屏幕顶端的文本,
第一个是beta状态:
/** This allows correct blending of text and what is already
rendered below it*/
AlphaState as1 = display.getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER);

同样我需要设置鼠标, 混合纹理的文本和背景绘制. 在alphastate之后, 我设置 text:
as1.setEnabled(true); 
// Now setup font texture
TextureState font = display.getRenderer().createTextureState();
/** The texture is loaded from fontLocation */
font.setTexture(
TextureManager.loadTexture(
SimpleGame.class.getClassLoader().getResource(
fontLocation),
Texture.MM_LINEAR,
Texture.FM_LINEAR,
true));
font.setEnabled(true); 

fpsNode把文本显示到屏幕上,下面,我创建屏幕底部的text对象  
// Then our font Text object.
/** This is what will actually have the text at the bottom. */
fps = new Text("FPS label", "");
fps.setForceView(true);
fps.setTextureCombineMode(TextureState.REPLACE); 

我使用它并允许用户更换字体。
默认情况下,只使用fpsNode的字体。

最后,我创建fpsNode。
我故意不分配到RootNode因为文本不应该被其他类型的对象一样控制。


// Finally, a stand alone node (not attached to root on purpose)
fpsNode = new Node("FPS node");
fpsNode.attachChild(fps);
fpsNode.setRenderState(font);
fpsNode.setRenderState(as1);
fpsNode.setForceView(true);
 
最后我创建灯光,灯光对象分配到LightStates---分配到Spatials,首先我创建灯光:
/** Set up a basic, default light. */
PointLight light = new PointLight();
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.setLocation(new Vector3f(100, 100, 100));
light.setEnabled(true); 

光源定位在100,100,100和基础的环境弥漫色泽,下面把灯光分配到LightState并放进rootnode使它可以照亮
该节点的全部物体。
/** Attach the light to a lightState and the lightState to rootNode. */
lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.attach(light);
rootNode.setRenderState(lightState); 

geometry和renderstates被更新:
simpleInitGame();
/** Update geometric and rendering information for both the
rootNode and fpsNode. */
rootNode.updateGeometricState(0.0f, true);
rootNode.updateRenderState();
fpsNode.updateGeometricState(0.0f, true);

fpsNode.updateRenderState(); 

0是一个时间值传递给所有控制器应该更新的对象。

updateGeometricState和updateRenderState在几何形状或绘制状态被改变时调用。
正确设置游戏后,我们
进入一个更新/渲染的无限循环。
首先,让我们来看看更新。
在更新的第一件事情就是设置帧之间的时间:


/** Recalculate the framerate. */
timer.update();
/** Update tpf to time per frame according to the Timer. */
更新我的time对象在update被调用的前后,这样我就有每帧的准确间隔时间,检查键盘的输入,更新屏幕底部的文本
/** Check for key/mouse updates. */
input.update(tpf);
/** Send the fps to our fps bar at the bottom. */
fps.print("FPS: " + (int) timer.getFrameRate() + " - " +
display.getRenderer().getStatistics());
/** Call simpleUpdate in any derived classes of SimpleGame. */

在场景图改变后 ,更新场景图根节点下的所有几何信息:
/**
Update controllers/render states/transforms/bounds for
rootNode.
*/
rootNode.updateGeometricState(tpf, true);

最后是update()检查key的按键,注意如果一个键改变一个渲染状态,方法
updateRenderState() 被调用,在更新之后,渲染发生,第一步是清空渲染信息,
/**
Reset display's tracking information for
number of triangles/vertexes
*/
display.getRenderer().clearStatistics();

jme的统计信息包括顶点和三角形的统计,如果顶点或三角形被渲染,计数器会增加,每帧信息会被重置,
下面我们清空缓冲区
/** Clears the previously rendered information. */
display.getRenderer().clearBuffers();

这样我们就清除了以前绘制的东东,如果不这样做,每帧会重复叠加,下面绘制rootnode和fpsnode
/** Draw the rootNode and all its children. */
display.getRenderer().draw(rootNode);
/**
If showing bounds, draw rootNode's bounds, and the
bounds of all its children.

*/
if (showBounds)
display.getRenderer().drawBounds(rootNode);
/** Draw the fps node to show the fancy information at the bottom. */
display.getRenderer().draw(fpsNode);
/** Call simpleRender() in any derived classes. */
simpleRender(); 


0
0
分享到:
评论

相关推荐

    JME3学习文档

    ### JME3游戏开发引擎中文学习指南 #### 引言 JME3,全称jMonkeyEngine3,是一款开源的3D游戏开发引擎,专为Java开发者设计,旨在简化3D游戏和应用程序的开发过程。本文档将详细介绍如何在Netbeans6.x环境下搭建...

    jme3 api(精华chm)

    com.jme3.animation com.jme3.app com.jme3.app.state com.jme3.asset com.jme3.asset.pack com.jme3.asset.plugins com.jme3.audio com.jme3.audio.joal ...jme3tools.preview

    JME学习文档—中文版.rar

    这份"JME学习文档—中文版"压缩包文件,显然是为了帮助初学者或有经验的Java开发者掌握JME的使用和开发技巧。 JME的核心在于它的可移植性,它允许开发者编写一次代码,就能在多个平台上运行,这得益于其“Write ...

    JME教程.rar

    Java Micro Edition(JME,前身为...通过深入学习和实践这些知识点,你将能够利用JME的强大功能,开发出富有创新性的移动和嵌入式应用。在阅读本教程时,建议同时进行实际编码练习,以便更好地理解和掌握JME的精髓。

    联想的JME2207P键盘驱动

    标题中的“联想的JME2207P键盘驱动”是指专门为联想品牌的一款键盘型号为JME2207P的设备设计的驱动程序。在计算机硬件系统中,驱动程序是连接操作系统与硬件设备的关键软件,它使得操作系统能够识别并控制特定硬件,...

    JME程序设计实例教程

    **JME程序设计实例教程详解** Java Micro Edition(JME),又称为Java 2 Micro Edition...通过学习,开发者不仅能够理解JME的编程模型,还能熟练运用其API,解决实际问题,为移动和嵌入式领域的软件开发打下坚实基础。

    JME中文教程.pdf

    该引擎不仅功能全面,其API设计简洁明了,易于学习掌握。 - **应用场景**:主要应用于3D游戏开发领域,包括但不限于桌面应用、Android及iOS平台游戏的开发。 - **核心功能**: - 场景管理:用于构建和管理复杂的...

    java学习笔记整理

    【Java学习笔记整理】 Java是一种广泛使用的编程语言,它不仅是一种语言,还是一个软件开发平台和运行环境。Java分为三个主要版本:Java标准版(JSE)、Java缩微版(JME)和Java企业版(JEE)。JSE主要用于桌面应用...

    2015jme3指南

    通过深入学习《2015jme3指南》,开发者不仅可以了解JME3的使用,还能掌握3D游戏开发的基本流程和技巧,为今后的项目开发打下坚实基础。同时,结合博主的博客文章,可以得到更全面的开发经验,解决实际遇到的问题。

    联想FN功能键 jme2207p键盘驱动. XP windows7

    标题中的“联想FN功能键 jme2207p键盘驱动. XP windows7”表明这是一个针对联想笔记本电脑的FN功能键以及JME2207P型号键盘的驱动程序,适用于Windows XP和Windows 7操作系统。FN键是许多笔记本电脑上常见的辅助功能...

    jme8002b蓝牙键盘驱动

    jme8002b蓝牙键盘驱动

    JME Molecular Editor结构式在线编辑器

    JME Molecular Editor结构式在线编辑器

    JME3中文教程(ZBP第一版)

    11. **脚本系统**:学习如何使用内置的LUA或JavaScript脚本引擎,编写游戏逻辑。 12. **插件系统**:了解如何扩展JME3的功能,使用或开发自定义插件。 通过深入学习这些内容,你将具备使用JME3开发3D游戏的能力。...

    相关技术\游戏引擎,JME

    游戏引擎是开发电子游戏的核心工具,它为游戏开发者提供了一个集成环境,用于创建、管理和优化游戏...通过学习和掌握游戏引擎的相关技术,开发者可以更高效地实现游戏创意,提高开发效率,同时保证游戏的性能和质量。

    ant-jme.jar.zip

    标题“ant-jme.jar.zip”指的是一个压缩文件,其中包含了两个关键元素:ant-jme.jar和ant.license.txt。这个文件主要与Java开发工具有关,特别是Apache Ant和Java Micro Edition (JME)。 Apache Ant是一个Java库和...

    jme3游戏demo rise-of-mutants

    《jme3游戏开发:Rise of Mutants》 ...对于希望进入Java游戏开发领域的程序员来说,这是一个很好的学习起点。通过深入研究源代码和实践,开发者可以掌握更多高级技巧,创作出更复杂、更具吸引力的游戏作品。

    JME3 JAVADOC

    本文档是JME 的javadoc 文档 JME是一个高性能的3D图形API,采用LWJGL作为底层支持。它的后续版本将支持JOGL。JME和Java 3D具有类似的场景结构,开发者必须以树状方式组织自己的场景。JME有一套很好的优化机制,这...

    JME商业游戏进阶二 (地表层的神秘面纱1)源代码

    《JME商业游戏进阶二 (地表层的神秘面纱1)...通过深入研究这个"ditu_example"的源代码,开发者不仅能学习到JME的用法,还能掌握游戏开发中的许多核心概念和技术,这对于提升游戏开发技能和理解游戏架构有着极大的帮助。

    JME的文件格式及支持的文件格式

    **JMonkeyEngine 3 (JME3) 文件格式详解** JMonkeyEngine 3(简称JME3)是一款开源的游戏开发引擎,专为构建3D游戏和应用而设计。它支持多种文件格式,使得开发者能够方便地导入和管理游戏资源。以下是对JME3支持的...

    JME试题及答案 socket 多线程 高级UI

    ### JME试题及答案知识点详解 #### 一、选择题知识点解析 ...这些知识点涵盖了JME中的多个方面,包括网络通信、图形处理、游戏开发等,旨在帮助中级水平的学习者深入理解JME的相关概念和技术细节。

Global site tag (gtag.js) - Google Analytics