最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 07:43:18
文檔

jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam

jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam:注:本系列教程全部翻譯完之后可能會(huì)以 PDF 的形式發(fā)布。 如果有什么錯(cuò)誤可以留言或 EMAIL : kakashi9bi@gmail.com 給我。 jME 版本 : jME_2.0.1_Stable 開發(fā)工具: MyEclipse8.5 操作系統(tǒng): Window7/Vista 這個(gè)向?qū)е?,我們將?Flag
推薦度:
導(dǎo)讀jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam:注:本系列教程全部翻譯完之后可能會(huì)以 PDF 的形式發(fā)布。 如果有什么錯(cuò)誤可以留言或 EMAIL : kakashi9bi@gmail.com 給我。 jME 版本 : jME_2.0.1_Stable 開發(fā)工具: MyEclipse8.5 操作系統(tǒng): Window7/Vista 這個(gè)向?qū)е?,我們將?Flag

注:本系列教程全部翻譯完之后可能會(huì)以 PDF 的形式發(fā)布。 如果有什么錯(cuò)誤可以留言或 EMAIL : kakashi9bi@gmail.com 給我。 jME 版本 : jME_2.0.1_Stable 開發(fā)工具: MyEclipse8.5 操作系統(tǒng): Window7/Vista 這個(gè)向?qū)е?,我們將?Flag Rush 構(gòu)建基

注:本系列教程全部翻譯完之后可能會(huì)以PDF的形式發(fā)布。

如果有什么錯(cuò)誤可以留言或EMAIL:kakashi9bi@gmail.com給我。

jME版本:jME_2.0.1_Stable

開發(fā)工具:MyEclipse8.5

操作系統(tǒng):Window7/Vista

這個(gè)向?qū)е?,我們將為Flag Rush構(gòu)建基礎(chǔ)。我們將通過(guò)自己實(shí)現(xiàn)繼承BaseGame。我們將使用BaseGame做為父類,但之后可能改為其它的游戲類型,因?yàn)锽aseGame簡(jiǎn)單地盡可能快地進(jìn)行update和render。我們或許不必或不想使用這種類型的循環(huán)。然而,現(xiàn)在BaseGame是一個(gè)循環(huán)無(wú)關(guān)的類。在以后,改變BaseGame將不是重點(diǎn),因?yàn)橹皇莻魅雞pdate和render方法的值不同而已。

我們將開始創(chuàng)建一個(gè)繼承自BaseGame的新類。你會(huì)注意到有6個(gè)需要實(shí)現(xiàn)的方法:update、render、initSystem、initGame和reinit?,F(xiàn)在,只需要為它們創(chuàng)建一個(gè)存根方法,我們將在后面將自己的邏輯填充進(jìn)去。

import com.jme.app.BaseGame;

publicclass Lesson2 extends BaseGame{

publicstaticvoid main(String[] args) {

}

protectedvoid cleanup() {

}

protectedvoid initGame() {

}

protectedvoid initSystem() {

}

protectedvoid reinit() {

}

protectedvoid render(float arg0) {

}

protectedvoid update(float arg0) {

}

}

2.1、Main

那么,讓我們從最初開始。我們?cè)谶@里將再次創(chuàng)建main方法。它很像前一個(gè)向?qū)У膍ain方法,除了一個(gè)關(guān)鍵的地方不同。這次我們將顯示FlagRush的迷人的新logo。AbstractGame定義了一對(duì)setConfigShowMode方法,其中的一個(gè)接受一個(gè)URL類用于加載Image。因此,我們將加載FlagRush.png(迷人的logo)并把它傳給這個(gè)方法。現(xiàn)在,當(dāng)PropertiesDialog被顯示時(shí),它將顯示新的Logo。

publicstaticvoid main(String[] args) {

Lesson2 app = new Lesson2();

java.net.URL url =

app.getClass().getClassLoader()

.getResource("jmetest/data/images/FlagRush.png");

app.setConfigShowMode(ConfigShowMode.AlwaysShow,url);

app.start();

}

現(xiàn)在,當(dāng)PropertiesDialog出現(xiàn)時(shí),它將像下面這個(gè)一樣(你應(yīng)該在項(xiàng)目中新建一個(gè)package——jmetest.data.images,然后里面有一張叫FlagRush.png的圖片):

2.2、InitSystem

現(xiàn)在,你能運(yùn)行你的應(yīng)用程序,但它僅僅是顯示PropertiesDialog,除此之外不會(huì)做更多的工作。我們下一步將實(shí)現(xiàn)initSystem方法。這個(gè)方法在進(jìn)入主循環(huán)之前由BaseGame調(diào)用。這正是我們?cè)O(shè)置window和display的地方。我們將保存width,height,depth,frequency和fullscreen標(biāo)志。我們將在后面使用這些值,假如用戶想改變分辨率的時(shí)候。所以,首先,讓我們創(chuàng)建變量去保存這些值:

publicclass Lesson2 extends BaseGame{

privateintwidth,height;

privateintfreq,depth;

privatebooleanfullscreen;

……………………….

我們也需要在我們的程序中保存Camera,所以我們也應(yīng)該為那創(chuàng)建一個(gè)變量。

//我們的camera對(duì)象,用于觀看scene

private Camera cam;

最后將初始化的一項(xiàng)是Timer,Timer將允許我們獲取我們的幀率。所以,同樣的,這將是一個(gè)實(shí)例變量。

protected Timer timer;

現(xiàn)在我們已經(jīng)準(zhǔn)備好我們的實(shí)例變量,并且我們將在initSystem中初始化它們。

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

}

//設(shè)置背景為黑色

display.getRenderer().setBackgroundColor(ColorRGBA.black);

//初始化攝像機(jī)

cam.setFrustumPerspective(

45.0f,

(float)width/(float)height,

1f,

1000f

);

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,0.0f,-1.0f);

//將攝像機(jī)移到正確位置和方向

cam.setFrame(loc, left, up, dir);

//我們改變自己的攝像機(jī)位置和視錐的標(biāo)志

cam.update();

//獲取一個(gè)高分辨率用于FPS更新

timer = Timer.getTimer();

display.getRenderer().setCamera(cam);

KeyBindingManager.getKeyBindingManager().set(

"exit",

KeyInput.KEY_ESCAPE

);

}

這是一個(gè)長(zhǎng)的方法,所以,我們將一點(diǎn)一點(diǎn)討論它。

//保存屬性信息

width = settings.getWidth();

height = settings.getHeight();

depth = settings.getDepth();

freq = settings.getFrequency();

fullscreen = settings.isFullscreen();

首先,我們保存從properties對(duì)象(properties是由AbstractGame創(chuàng)建的)獲取的值。通過(guò)保存這些值,當(dāng)用戶以后從系統(tǒng)菜單改變屏幕設(shè)置的時(shí)候,我們可以很容易地修改它們中的一個(gè)或全部值。

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

}

下一步,我們獲取新的DisplaySystem,并通過(guò)先前獲得的屏幕參數(shù)創(chuàng)建一個(gè)本地窗口。我們接著使用DisplaySystem去創(chuàng)建一個(gè)Camera對(duì)象。你將注意到那用一個(gè)try/catch塊包圍。如果我們嘗試創(chuàng)建一個(gè)系統(tǒng)沒(méi)能力繪制的窗口,異常將在這里出現(xiàn)。目前,它只會(huì)退出,但之后,我們將讓這個(gè)顯示得更友好,并通知用戶。

//設(shè)置背景為黑色

display.getRenderer().setBackgroundColor(ColorRGBA.black);

我們接著設(shè)置了窗口的背景顏色。當(dāng)沒(méi)有其它數(shù)據(jù)被渲染的時(shí)候,這是顯示的默認(rèn)顏色。我選擇黑色,這是因?yàn)樗臀覀兒竺鎸⑹褂玫娜魏挝谋拘纬甚r明的對(duì)比。不管怎樣,這都不是重點(diǎn),因?yàn)楫?dāng)一切正常工作時(shí),屏幕上通常覆蓋其它的數(shù)據(jù)。

//初始化攝像機(jī)

cam.setFrustumPerspective(

45.0f,

(float)width/(float)height,

1f,

1000f

);

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,0.0f,-1.0f);

//將攝像機(jī)移到正確位置和方向

cam.setFrame(loc, left, up, dir);

//我們改變自己的攝像機(jī)位置和視錐的標(biāo)志

cam.update();

display.getRenderer().setCamera(cam);

下一步,我設(shè)置了camera。我想要一個(gè)標(biāo)準(zhǔn)的camera,正常情況下是右手坐標(biāo)系統(tǒng)(向上是正Y,向右是正X和向屏幕里面是-Z)。我同時(shí)設(shè)置了透視圖為45度視角。這個(gè)是大多數(shù)游戲里面的公認(rèn)標(biāo)準(zhǔn),而它將應(yīng)用于Flag Rush。在camera數(shù)據(jù)設(shè)置之后,我們調(diào)用update,這將設(shè)置所有的OpenGL組件,例如視點(diǎn)(下文以ViewPort代替)和Frustum。

//獲取一個(gè)高分辨率用于FPS更新

timer = Timer.getTimer();

這里只是初始化Timer,從本地Timer獲?。ɡ鏛WJGLTimer)。

KeyBindingManager.getKeyBindingManager().set(

"exit",

KeyInput.KEY_ESCAPE

);

最后,我們創(chuàng)建一個(gè)新的InputSystem,將它綁定到我們的KeyBindingManager并設(shè)置一個(gè)輸入行為(Input action)。在這個(gè)框架中我們只關(guān)心一個(gè)按鍵——Escape。在這個(gè)例子中,我們?cè)O(shè)置action“exit”給Escape鍵。KeyBindingManager是一個(gè)單例類,它使用單一的get調(diào)用,關(guān)注了所有InputSystem組件的初始化。

現(xiàn)在,如果你運(yùn)行系統(tǒng)你將真正獲得一個(gè)屏幕顯示。它將充滿黑色(我們?cè)O(shè)置的背景顏色),沒(méi)有任何東西。

2.3、InitGame

現(xiàn)在,我們擁有一個(gè)窗口和OpenGL上下文環(huán)境,我們將加載我們的游戲數(shù)據(jù)(如上面前個(gè)向?qū)У腟phere)

protectedvoid initGame() {

scene = new Node("Scene Graph Node");

//創(chuàng)建我們的球體

Sphere s = new Sphere("sphere", 30, 30, 25);

s.setLocalTranslation(new Vector3f(0, 0, -40));

s.setModelBound(new BoundingBox());

s.updateModelBound();

ts = display.getRenderer().createTextureState();

ts.setEnabled(true);

ts.setTexture(

TextureManager.loadTexture(

Lesson2.class.getClassLoader()

.getResource("res/logo.png"),

Texture.MinificationFilter.Trilinear,

Texture.MagnificationFilter.Bilinear

)

);

s.setRenderState(ts);

scene.attachChild(s);

//更新scene用于渲染

scene.updateGeometricState(0.0f, true);

scene.updateRenderState();

}

我們現(xiàn)在保存我們自己的Scene Graph結(jié)點(diǎn),我已經(jīng)選擇把它命名為scene,但實(shí)際上怎樣命名都是沒(méi)關(guān)系。因?yàn)檫@是scene的根節(jié)點(diǎn),它也是一個(gè)實(shí)例變量而它和其他實(shí)例變量一樣被聲明:

private Node scene;

這個(gè)Node接著被實(shí)例化。接著我們創(chuàng)建了一個(gè)Sphere和TextureState(就像上一個(gè)的向?qū)Вphere接著被attach到scene。這個(gè)看起來(lái)將和我們上一個(gè)向?qū)龅暮芟嗨?。然而,現(xiàn)在,我們還調(diào)用updateGeometricState和updateRenderState。這些方法為SceneGraph updates調(diào)用。updateGeometricState是必須的,不管場(chǎng)景圖(Scene Graph)結(jié)構(gòu)在何時(shí)改變(設(shè)置一個(gè)新的,改變另一個(gè)的參數(shù),等等),在我們的例子中,我增加了一個(gè)sphere到到scene。不管RenderState在什么時(shí)候以何種方式發(fā)生改變,updateRenderState都應(yīng)該被調(diào)用(比如創(chuàng)建一個(gè)新的RenderState、改變它的參數(shù)等等),在我們的例子中,我們?cè)黾恿薚extureState。

我們現(xiàn)在擁有游戲中的數(shù)據(jù),但它仍然沒(méi)被渲染到屏幕。

2.4、Render和update

既然我們已經(jīng)初始化了窗口并加載了數(shù)據(jù),如果能看到它將更好。那就是render方法的到來(lái)。BaseGame調(diào)用update并根據(jù)它的能力盡可能快地render。render的調(diào)用需要處理所有繪畫調(diào)用,而update應(yīng)該處理任何的游戲邏輯。在我們的例子中,我們想要update做一點(diǎn)游戲邏輯,退出游戲。為了簡(jiǎn)單退出游戲,我們將設(shè)置finished布爾值為true。

/*

* 在update期間,我們只需尋找Escape按鈕

* 并更新timer去獲取幀率

*/

protectedvoid update(float interpolation) {

//更新timer去獲取幀率

timer.update();

interpolation = timer.getTimePerFrame();

//當(dāng)Escape被按下時(shí),我們退出游戲

if(KeyBindingManager.getKeyBindingManager()

.isValidCommand("exit")

){

finished = true;

}

}

你也將注意到update獲取最新的timer讀數(shù)并為此設(shè)置插值(interpolation)。BaseGame通常在調(diào)用update時(shí)發(fā)送-1,所以我們將繼續(xù)并重用這個(gè)值去保存每幀真正的時(shí)間。

接下來(lái),我們將渲染。

/*

* 繪制場(chǎng)景圖

*/

protectedvoid render(float interpolation) {

//清除屏幕

display.getRenderer().clearBuffers();

display.getRenderer().draw(scene);

}

這個(gè)直截了當(dāng)。我們使用clearBuffers清除屏幕。我們接著畫了scene,這是包含我們Sphere的樹。

你現(xiàn)在能運(yùn)行程序并看到:

正是和前一課的顯示一樣,只不過(guò)沒(méi)了燈光。

2.5、reinit和cleanup

最后我們將覆蓋的2個(gè)方法是reinit和cleanup。當(dāng)窗口需要重建時(shí),Reinit應(yīng)該被調(diào)用,就像參數(shù)發(fā)生了變化。而在關(guān)閉的時(shí)候調(diào)用cleanup。

/*

* 如果分辨率改變將被調(diào)用

*/

protectedvoid reinit() {

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

}

我們?cè)谶@里所做的就只是傳遞新的值給DisplaySystem處理。僅此而已。

/*

* 清除texture

*/

protectedvoid cleanup() {

ts.deleteAll();

}

這簡(jiǎn)單確保了texture被刪除。這不是特別必須的,因?yàn)镺penGL在它退出時(shí)將處理這個(gè)。但“寧可事先謹(jǐn)慎有余,切莫事后追悔莫及”。

2.6、總結(jié)

很好,就是那樣。我們現(xiàn)在有一個(gè)很基本、可工作的框架。通過(guò)創(chuàng)建我們自己的應(yīng)用程序類型,我們能完全保持對(duì)我們場(chǎng)景中一切的控制。隨著向?qū)У睦^續(xù),我們將很明確地增強(qiáng)并構(gòu)建基于這個(gè)類的程序。

2.7、源碼

import com.jme.app.BaseGame;

import com.jme.bounding.BoundingBox;

import com.jme.image.Texture;

import com.jme.input.KeyBindingManager;

import com.jme.input.KeyInput;

import com.jme.math.Vector3f;

import com.jme.renderer.Camera;

import com.jme.renderer.ColorRGBA;

import com.jme.scene.Node;

import com.jme.scene.shape.Sphere;

import com.jme.scene.state.TextureState;

import com.jme.system.DisplaySystem;

import com.jme.system.JmeException;

import com.jme.util.TextureManager;

import com.jme.util.Timer;

publicclass Lesson2 extends BaseGame{

privateintwidth,height;

privateintfreq,depth;

privatebooleanfullscreen;

//我們的camera對(duì)象,用于觀看scene

private Camera cam;

protected Timer timer;

private Node scene;

private TextureState ts;

publicstaticvoid main(String[] args) {

Lesson2 app = new Lesson2();

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() {

scene = new Node("Scene Graph Node");

//創(chuàng)建我們的球體

Sphere s = new Sphere("sphere", 30, 30, 25);

s.setLocalTranslation(new Vector3f(0, 0, -40));

s.setModelBound(new BoundingBox());

s.updateModelBound();

ts = display.getRenderer().createTextureState();

ts.setEnabled(true);

ts.setTexture(

TextureManager.loadTexture(

Lesson2.class.getClassLoader().getResource("res/logo.png"),

Texture.MinificationFilter.Trilinear,

Texture.MagnificationFilter.Bilinear

)

);

s.setRenderState(ts);

scene.attachChild(s);

//更新scene用于渲染

scene.updateGeometricState(0.0f, true);

scene.updateRenderState();

}

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

}

//設(shè)置背景為黑色

display.getRenderer().setBackgroundColor(ColorRGBA.black);

//初始化攝像機(jī)

cam.setFrustumPerspective(

45.0f,

(float)width/(float)height,

1f,

1000f

);

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,0.0f,-1.0f);

//將攝像機(jī)移到正確位置和方向

cam.setFrame(loc, left, up, dir);

//我們改變自己的攝像機(jī)位置和視錐的標(biāo)志

cam.update();

//獲取一個(gè)高分辨率用于FPS更新

timer = Timer.getTimer();

display.getRenderer().setCamera(cam);

KeyBindingManager.getKeyBindingManager().set(

"exit",

KeyInput.KEY_ESCAPE

);

}

/*

* 如果分辨率改變將被調(diào)用

*/

protectedvoid reinit() {

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

}

/*

* 繪制場(chǎng)景圖

*/

protectedvoid render(float interpolation) {

//清除屏幕

display.getRenderer().clearBuffers();

display.getRenderer().draw(scene);

}

/*

* 在update期間,我們只需尋找Escape按鈕

* 并更新timer去獲取幀率

*/

protectedvoid update(float interpolation) {

//更新timer去獲取幀率

timer.update();

interpolation = timer.getTimePerFrame();

//當(dāng)Escape被按下時(shí),我們退出游戲

if(KeyBindingManager.getKeyBindingManager()

.isValidCommand("exit")

){

finished = true;

}

}

}

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam

jMonkeyEngine譯文FlagRush2從你的應(yīng)用程序中移除SimpleGam:注:本系列教程全部翻譯完之后可能會(huì)以 PDF 的形式發(fā)布。 如果有什么錯(cuò)誤可以留言或 EMAIL : kakashi9bi@gmail.com 給我。 jME 版本 : jME_2.0.1_Stable 開發(fā)工具: MyEclipse8.5 操作系統(tǒng): Window7/Vista 這個(gè)向?qū)е?,我們將?Flag
推薦度:
標(biāo)簽: 翻譯 你的 應(yīng)用程序
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top