欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

jMonkeyEngine譯文 FlagRush2——從你的應(yīng)用程

系統(tǒng) 1877 0

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

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

jME 版本 jME_2.0.1_Stable

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

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

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

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

import com.jme.app.BaseGame;

public class Lesson2 extends BaseGame{

public static void main(String[] args) {

}

protected void cleanup() {

}

protected void initGame() {

}

protected void initSystem() {

}

protected void reinit() {

}

protected void render( float arg0) {

}

protected void update( float arg0) {

}

}

2.1 Main

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

public static void 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 的圖片):

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

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)建變量去保存這些值:

public class Lesson2 extends BaseGame{

private int width , height ;

private int freq , depth ;

private boolean fullscreen ;

……………………….

我們也需要在我們的程序中保存 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 中初始化它們。

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

}

// 設(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 獲取(例如 LWJGLTimer )。

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ū)У? Sphere

protected void 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ū)В? Sphere 接著被 attach scene 。這個(gè)看起來(lái)將和我們上一個(gè)向?qū)龅暮芟嗨啤H欢F(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è)黾恿? TextureState

我們現(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 去獲取幀率

*/

protected void 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)景圖

*/

protected void render( float interpolation) {

// 清除屏幕

display .getRenderer().clearBuffers();

display .getRenderer().draw( scene );

}

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

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

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

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

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

*/

protected void reinit() {

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

}

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

/*

* 清除 texture

*/

protected void cleanup() {

ts .deleteAll();

}

這簡(jiǎn)單確保了 texture 被刪除。這不是特別必須的,因?yàn)? OpenGL 在它退出時(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;

public class Lesson2 extends BaseGame{

private int width , height ;

private int freq , depth ;

private boolean fullscreen ;

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

private Camera cam ;

protected Timer timer ;

private Node scene ;

private TextureState ts ;

public static void 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

*/

protected void cleanup() {

ts .deleteAll();

}

protected void 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();

}

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

}

// 設(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)用

*/

protected void reinit() {

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

}

/*

* 繪制場(chǎng)景圖

*/

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

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

if (KeyBindingManager. getKeyBindingManager ()

.isValidCommand( "exit" )

){

finished = true ;

}

}

}

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


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久久久久久久国产 | 99爱在线视频这里只有精品 | 一区二区三区视频在线 | 99综合网 | 亚洲色图国产精品 | 久久久久久免费一区二区三区 | www伊人网 | 日本一道一区二区免费看 | 日本字幕在线观看 | 亚洲精品乱码久久久久久9色 | 天天夜天干天天爽 | 一区二区三区无码高清视频 | 美女在线视频网站 | 久久国产精品久久久久久久久久 | 久久久久久国产精品mv | 黄色影视免费看 | 羞羞视频在线免费 | 成人国产精品视频 | 毛片a片 | 国产东北普通话对白 | 日韩艹| 国产精品久久九九 | 国产亚洲一区二区三区 | 国产精品久久久久久久7电影 | 欧美日韩在线视频播放 | 亚洲尻逼视频 | 色婷婷天天综合在线 | 久久久成| 国产精品k | 日本高清无卡码一区二区久久 | 国产精品亚洲第一 | 午夜不卡一区二区 | 精品国产一区二区三区免费 | 色狠狠狠色噜噜噜综合网 | 国产精品手机在线观看 | 国产片欧美片亚洲片久久综合 | 久久精品视频在线播放 | 国内精品玖玖玖玖电影院 | 国产精品亚洲视频 | 成人福利在线视频免费观看 | 亚洲精品乱码久久久久久9色 |