最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag

來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-09 07:43:20
文檔

jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag

jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag:8.6 、為旗桿增加布 我想要讓 Flag 看起來像 很好,像 Flag 。為了這么做,我們需要模擬一個布的 Flag , attach 到旗桿。有什么更好的方式完成這件事,還是使用 jME 的 ClothPatch 功能。這將允許我們?nèi)?chuàng)建一個彈簧( spring )點的 matrix
推薦度:
導(dǎo)讀jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag:8.6 、為旗桿增加布 我想要讓 Flag 看起來像 很好,像 Flag 。為了這么做,我們需要模擬一個布的 Flag , attach 到旗桿。有什么更好的方式完成這件事,還是使用 jME 的 ClothPatch 功能。這將允許我們?nèi)?chuàng)建一個彈簧( spring )點的 matrix

8.6 、為旗桿增加布 我想要讓 Flag 看起來像 很好,像 Flag 。為了這么做,我們需要模擬一個布的 Flag , attach 到旗桿。有什么更好的方式完成這件事,還是使用 jME 的 ClothPatch 功能。這將允許我們?nèi)?chuàng)建一個彈簧( spring )點的 matrix ,它們由不同方

8.6、為旗桿增加布

我想要讓Flag看起來像…很好,像Flag。為了這么做,我們需要模擬一個布的Flag,attach到旗桿。有什么更好的方式完成這件事,還是使用jME的ClothPatch功能。這將允許我們?nèi)?chuàng)建一個彈簧(spring)點的matrix,它們由不同方向的外力(force)調(diào)整(引力和風(fēng)力)。我已經(jīng)為這個向?qū)?chuàng)建了我自己的風(fēng)力,而我們將在下面討論。

首先,增加對象到Flag類。

//用于制作Flag的Cloth

private ClothPatch cloth;

//風(fēng)的參數(shù)

privatefloatwindStrength = 15f;

private Vector3f windDirection = new Vector3f(0.8f, 0, 0.2f);

private SpringPointForce gravity,wind;

在Flag的構(gòu)造參數(shù)中,我們將創(chuàng)建一個ClothPatch。這個Cloth將是25*25的matrix,給它一個相當詳細的cloth。cloth上的點越多,它運行得越慢,所以你應(yīng)該在flag的視覺外觀和它對游戲的影響之間選個平衡點。25*25給我一個可接受的性能和外觀的比例。在創(chuàng)建cloth之后,我們將增加我們的force。我們增加的第一個force是我們?yōu)檫@個向?qū)?chuàng)建的自定義的force,叫做RandomFlagWindForce。我們也將增加一個默認的重力它是由ClothUtils創(chuàng)建的,這將在風(fēng)減小的時候把Flag拉下來。

//創(chuàng)建一個cloth patch 將處理我們flag

cloth = new ClothPatch("cloth", 25, 25, 1f, 10);

//將我們自定義的風(fēng)力增加到cloth

wind = new RandomFlagWindForce(windStrength, windDirection);

cloth.addForce(wind);

//增加一個簡單的重力

gravity = ClothUtils.createBasicGravity();

cloth.addForce(gravity);

由于cloth是標準的jME Spatial,我們和平常一樣應(yīng)用RenderState。我們將為Flag增加texture,使用jME monkey的logo。這個是一個讓monkey的頭在你腦海留下烙印的企圖。

//創(chuàng)建一個將flag顯示的texture,一起推進jME發(fā)展!

TextureState ts = DisplaySystem.getDisplaySystem()

.getRenderer().createTextureState();

ts.setTexture(

TextureManager.loadTexture(

Flag.class.getClassLoader()

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

Texture.MinificationFilter.Trilinear,

Texture.MagnificationFilter.Bilinear

)

);

cloth.setRenderState(ts);

當我開始增加一個flag到場景時,我對light非常不滿意,因為flag大部分時間都是陰影。因此,我決定增加一個light,它只影響flag。這個light應(yīng)該跟著Flag移動,并且根據(jù)Flag定位自己。因此,使用一個LightNode是最好的解決方案。LightNode允許你對待一個light就像scene中的其它元素一樣,通過移動light的父親node移動它。

//我們將使用一個LightNode去給Flag增加light,使用Node

//是因為它允許light隨著FLag移動

//首先創(chuàng)建light

PointLight dr = new PointLight();

dr.setEnabled(true);

dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));

dr.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));

dr.setLocation(new Vector3f(0.5f, -0.5f, 0));

//接下來是state

LightState lightState = DisplaySystem.getDisplaySystem()

.getRenderer().createLightState();

lightState.setEnabled(true);

lightState.setTwoSidedLighting(true);

lightState.attach(dr);

setRenderState(lightState);

//最后是結(jié)點

LightNode lightNode = new LightNode("light");

lightNode.setLight(dr);

lightNode.setLocalTranslation(new Vector3f(15,0,0));

attachChild(lightNode);

cloth.setRenderState(lightState);

Flag有一點和前面不同,那就是我們想看到它所有面的三角形。前面,我們設(shè)置了scene的CullState去剔除所有背后的三角形。因此,我們將增加另一個CUllState給cloth,讓它不要剔除任何三角形。它將看到所有的三角形。

//我們想看flag所有的面,所以我們將關(guān)閉Cull

CullState cs = DisplaySystem.getDisplaySystem()

.getRenderer().createCullState();

cs.setCullFace(CullState.Face.None);

cloth.setRenderState(cs);

this.attachChild(cloth);

下一步,我們需要為cloth創(chuàng)建一些點去固定它。如果我們不這么做,整個cloth將在force應(yīng)用于它身上時被“吹走”。我們需要在旗桿上attach一些點去保住cloth。我們通過設(shè)置點的質(zhì)量為無窮大來這么做。因此,沒有任何force能移走它。為了模擬這個方法,一個flag被attach到一個旗桿,flag上邊緣的一些和旗桿接觸的點將被attach,下面的也是。這些點被設(shè)置在一個基礎(chǔ)的二維matrix中,所以我們將attach點(0,1,2,3,4)到旗桿,點(500,525,550,575,600)也一樣。我們也調(diào)整這些點在y的位置讓它們偏移,從而讓cloth形成一點褶皺。

//我們需要attach一些點到旗桿,這些點不應(yīng)該被移動。

//因此,我們將attach頂部和底部的5個點去讓它們足夠高而

//且沒有任何forece能移動它。我也稍微移動這些點的位置去

//形成褶皺讓它更真實。

for(int i=0; i<5; i++){

cloth.getSystem().getNode(i*25).position.y *= .8f;

cloth.getSystem().getNode(i*25)

.setMass(Float.POSITIVE_INFINITY);

}

for(int i=24; i>19; i--){

cloth.getSystem().getNode(i*25).position.y *= .8f;

cloth.getSystem().getNode(i*25)

.setMass(Float.POSITIVE_INFINITY);

}

最后,我創(chuàng)建自定義風(fēng)力。為了模仿旗桿上flag的效果,我們也隨機化風(fēng)向。風(fēng)向?qū)⒒谒暗奈恢?/p>

/**

* 在每次update cloth時調(diào)用。將輕微調(diào)整風(fēng)向和強度、

*/

publicvoid apply(float dt, SpringPoint node) {

windDirection.x += dt * (FastMath.nextRandomFloat() - .5f);

windDirection.z += dt * (FastMath.nextRandomFloat() - .5f);

windDirection.normalize();

float tStr = FastMath.nextRandomFloat() * strength;

node.acceleration.addLocal(

windDirection.x * tStr,

windDirection.y * tStr,

windDirection.z * tStr

);

}

通過那樣,我們現(xiàn)在有一個看起來真實的flag,而且我們以自己的方式去為我們游戲中添加元素。下一課,我們只需能獲取flag。

8.7、源碼

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.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.jme.util.export.binary.BinaryImporter;

import com.jmex.model.converters.MaxToJme;

import com.jmex.terrain.TerrainBlock;

import com.jmex.terrain.util.MidPointHeightMap;

import com.jmex.terrain.util.ProceduralTextureGenerator;

publicclass Lesson8 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;

publicstaticvoid main(String[] args) {

Lesson8 app = new Lesson8();

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

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 = new 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 = Lesson8.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();

}

//設(shè)置Vehicle的屬性(這些數(shù)字能被認為是單元/秒 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(

Lesson8.class.getClassLoader()

.getResource("res/texture/north.jpg"),

Texture.MinificationFilter.BilinearNearestMipMap,

Texture.MagnificationFilter.Bilinear

);

Texture south = TextureManager.loadTexture(

Lesson8.class.getClassLoader()

.getResource("res/texture/south.jpg"),

Texture.MinificationFilter.BilinearNearestMipMap,

Texture.MagnificationFilter.Bilinear

);

Texture east = TextureManager.loadTexture(

Lesson8.class.getClassLoader()

.getResource("res/texture/east.jpg"),

Texture.MinificationFilter.BilinearNearestMipMap,

Texture.MagnificationFilter.Bilinear

);

Texture west = TextureManager.loadTexture(

Lesson8.class.getClassLoader()

.getResource("res/texture/west.jpg"),

Texture.MinificationFilter.BilinearNearestMipMap,

Texture.MagnificationFilter.Bilinear

);

Texture up = TextureManager.loadTexture(

Lesson8.class.getClassLoader()

.getResource("res/texture/top.jpg"),

Texture.MinificationFilter.BilinearNearestMipMap,

Texture.MagnificationFilter.Bilinear

);

Texture down = TextureManager.loadTexture(

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

fence = new ForceFieldFence("forceFieldFence");

//我們將手工做一些調(diào)整去讓它更好適應(yīng)terrain

//首先我們將實體“模型”放大

fence.setLocalScale(5);

//現(xiàn)在,讓我們移動fence到terrain的高度并有一點陷入它里面

fence.setLocalTranslation(

new Vector3f(25,tb.getHeight(25,25)+10,25)

);

scene.attachChild(fence);

}

privatevoid buildLighting() {

/* 設(shè)置一個基礎(chǔ)、默認燈光 */

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

}

/**

* 創(chuàng)建heightmap和terrainBlock

*/

privatevoid buildTerrain() {

//生成隨機地形數(shù)據(jù)

MidPointHeightMap heightMap = new MidPointHeightMap(64,1f);

//縮放數(shù)據(jù)

Vector3f terrainScale = new Vector3f(4, .0575f, 4);

//創(chuàng)建一個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);

//加載細節(jié)紋理并為2個terrain的texture設(shè)置組合模型

Texture t2 = TextureManager.loadTexture(

Lesson8.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 var cpro_id = "u6292429";

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

文檔

jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag

jMonkeyEngine譯文FlagRush8(2)增加隨機的Flag:8.6 、為旗桿增加布 我想要讓 Flag 看起來像 很好,像 Flag 。為了這么做,我們需要模擬一個布的 Flag , attach 到旗桿。有什么更好的方式完成這件事,還是使用 jME 的 ClothPatch 功能。這將允許我們?nèi)?chuàng)建一個彈簧( spring )點的 matrix
推薦度:
標簽: 翻譯 增加 (2)
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top