?
簡(jiǎn)述
現(xiàn)在,移動(dòng)游戲和 移動(dòng)應(yīng)用 開發(fā)極為熱門!游戲中需要有時(shí)髦漂亮的圖形,其設(shè)計(jì)標(biāo)準(zhǔn)比以前任何時(shí)候都要高。本文將告訴你怎樣用酷斃的移動(dòng)3D圖形API為J2ME設(shè)備開發(fā)3D圖形游戲。
如果你在用MIDP1.0進(jìn)行用戶接口編程,那么有兩條路你可以選擇:使用高級(jí)的UI類或者一切由你自己從頭開始。作為游戲開發(fā)者,第一種選擇往往是不可能的;這是為什么游戲開發(fā)者不得不為他們的高級(jí)游戲開發(fā)自己的3D引擎的原因。無(wú)疑,這需要付出大量的時(shí)間和努力,而缺乏浮點(diǎn)數(shù)支持的CLDC 1.0(MIDP 1.0正是建于其上)對(duì)問(wèn)題的解決沒(méi)有多大幫助。
在MIDP 2.0中,有一個(gè)可選的叫移動(dòng)3D圖形API的軟件包,或者叫JSR 184。該API是第一個(gè)基于Java標(biāo)準(zhǔn)開發(fā)的移動(dòng)設(shè)備上的 三維圖 形軟件包。該API既有高級(jí)又有低級(jí)圖形特征;其中,高級(jí)特征稱為保留模式,低級(jí)特征稱為立即模式。保留模式使得開發(fā)者有可能使用場(chǎng)景圖形并使場(chǎng)景中的物體根據(jù)虛擬相機(jī)和燈光的位置進(jìn)行自身的著色。立即模式能夠允許應(yīng)用程序直接進(jìn)行物體繪制。如果需要,可以在同一個(gè)應(yīng)用程序中使用這兩種模式。
本文著重介紹立即模式(在第二篇文章中我們將分析保留模式)。
3D API
讓我們以列舉和解釋該3D API中的類作為開始。除了這些API外,JSR 184還包含了一個(gè)場(chǎng)景圖形結(jié)構(gòu)和一個(gè)相應(yīng)的文件格式以有效地管理和配置3D內(nèi)容。該文件格式定義了一種m3g文件,這種文件典型地從3D建模文件應(yīng)用程序中轉(zhuǎn)換而來(lái)。
表1.3D API類
舉例
我們將開發(fā)一個(gè)簡(jiǎn)單的旋轉(zhuǎn)一個(gè)多邊形的3D應(yīng)用程序?yàn)槔T摱噙呅问且粋€(gè)立方體,它的紋理是一張舊汽車相片。列表1展示了例程midlet的主要類-應(yīng)用程序的中心類。該類負(fù)責(zé)創(chuàng)建應(yīng)用程序并建立起運(yùn)行MyCanvas的計(jì)時(shí)器。
列表1. MIDletMain類
列表2顯示了MyCanvas類,該類包含了應(yīng)用程序的所有圖形邏輯。init()方法負(fù)責(zé)結(jié)點(diǎn)的創(chuàng)建,紋理文件的裝載并設(shè)置紋理,外觀和背景也被一起設(shè)置。paint()方法負(fù)責(zé)著色并旋轉(zhuǎn)立方體。圖1展示了正在一個(gè)模擬器中運(yùn)行的實(shí)際程序。
列表2. MyCanvas類
小結(jié)
JSR 184對(duì)于可以運(yùn)行MIDP 2.0的設(shè)備來(lái)說(shuō),是一個(gè)節(jié)省時(shí)間和空間的可選的軟件開發(fā)包。它允許開發(fā)者使用兩種圖形方式-保留模式和立即模式-來(lái)產(chǎn)生3D圖形。本文集中講述了立即模式,并給出一個(gè)例子程序來(lái)說(shuō)明怎樣使用3D API。
現(xiàn)在,移動(dòng)游戲和 移動(dòng)應(yīng)用 開發(fā)極為熱門!游戲中需要有時(shí)髦漂亮的圖形,其設(shè)計(jì)標(biāo)準(zhǔn)比以前任何時(shí)候都要高。本文將告訴你怎樣用酷斃的移動(dòng)3D圖形API為J2ME設(shè)備開發(fā)3D圖形游戲。
如果你在用MIDP1.0進(jìn)行用戶接口編程,那么有兩條路你可以選擇:使用高級(jí)的UI類或者一切由你自己從頭開始。作為游戲開發(fā)者,第一種選擇往往是不可能的;這是為什么游戲開發(fā)者不得不為他們的高級(jí)游戲開發(fā)自己的3D引擎的原因。無(wú)疑,這需要付出大量的時(shí)間和努力,而缺乏浮點(diǎn)數(shù)支持的CLDC 1.0(MIDP 1.0正是建于其上)對(duì)問(wèn)題的解決沒(méi)有多大幫助。
在MIDP 2.0中,有一個(gè)可選的叫移動(dòng)3D圖形API的軟件包,或者叫JSR 184。該API是第一個(gè)基于Java標(biāo)準(zhǔn)開發(fā)的移動(dòng)設(shè)備上的 三維圖 形軟件包。該API既有高級(jí)又有低級(jí)圖形特征;其中,高級(jí)特征稱為保留模式,低級(jí)特征稱為立即模式。保留模式使得開發(fā)者有可能使用場(chǎng)景圖形并使場(chǎng)景中的物體根據(jù)虛擬相機(jī)和燈光的位置進(jìn)行自身的著色。立即模式能夠允許應(yīng)用程序直接進(jìn)行物體繪制。如果需要,可以在同一個(gè)應(yīng)用程序中使用這兩種模式。
本文著重介紹立即模式(在第二篇文章中我們將分析保留模式)。
3D API
讓我們以列舉和解釋該3D API中的類作為開始。除了這些API外,JSR 184還包含了一個(gè)場(chǎng)景圖形結(jié)構(gòu)和一個(gè)相應(yīng)的文件格式以有效地管理和配置3D內(nèi)容。該文件格式定義了一種m3g文件,這種文件典型地從3D建模文件應(yīng)用程序中轉(zhuǎn)換而來(lái)。
表1.3D API類
類 | 描述 |
AnimationController | 控制動(dòng)畫順序。 |
AnimationTrack | 把一個(gè)KeyframeSequence同一個(gè)AnimationController相關(guān)聯(lián)。 |
Appearance | 定義一個(gè) 網(wǎng)眼 (Mesh)或一個(gè)Spring3D的著色屬性的一組對(duì)象。 |
Background | 定義視圖是怎樣被清除的。 |
Camera | 一個(gè)場(chǎng)景圖頂點(diǎn),它定義了場(chǎng)景中觀察者的位置以及從3D到2D的投影。 |
CompositingMode | 一個(gè)Appearance類,它封裝了每一個(gè)像素的合成屬性。 |
Fog | 一個(gè)Appearance類,它包含了霧化的有關(guān)屬性。 |
Graphics3D | 一個(gè)單獨(dú)的3D圖形上下文。所有的著色操作都是在該類中的render()方法中實(shí)現(xiàn)的。 |
Group | 一個(gè)場(chǎng)景圖形結(jié)點(diǎn),它存儲(chǔ)了一個(gè)無(wú)序的結(jié)點(diǎn)集作為它的子結(jié)點(diǎn)。 |
Image2D | 一個(gè)二維圖像,可用于紋理,背景,或者精靈圖像。 |
IndexBuffer | 該類定義了如何把頂點(diǎn)連接起來(lái)以形成一個(gè) 幾何 體。 |
KeyframeSequence | 封裝了一系列的具有時(shí)間戳和矢量值的關(guān)鍵幀的動(dòng)畫數(shù)據(jù)。 |
Light | 描述了不同類型的光源。 |
Loader | 下載和反串行化圖形結(jié)點(diǎn)及結(jié)點(diǎn)成分,以及整個(gè)場(chǎng)景圖形。 |
Material | 封裝了進(jìn)行光學(xué)計(jì)算的材質(zhì)屬性。 |
Mesh | 描述了一個(gè)3D對(duì)象,它是用多邊形面定義的。 |
MorphingMesh | 描述了一個(gè)頂點(diǎn)-變形的多邊形網(wǎng)眼。 |
Node | 所有場(chǎng)景圖形結(jié)點(diǎn)的 抽象 基類。其五個(gè)具體子類是:Camera,Mesh,Sprite3D,Light和Group。 |
Object3D | 所有可以成為3D世界中組成部分的對(duì)象的抽象基類。 |
PolygonMode | 封裝了多邊形級(jí)別屬性。 |
RayIntersection | 存儲(chǔ)了對(duì)于分割的Mesh或Sprite3D的引用,以及有關(guān)分割點(diǎn)的信息。 |
SkinnedMesh | 描述了一個(gè)框架動(dòng)畫的多邊形網(wǎng)眼。 |
Sprite3D | 用3D位置來(lái)描述一個(gè)2D圖像。 |
Texture2D | 封裝了一個(gè)2D紋理圖像和一個(gè)屬性集合,這些屬性指出該圖像是如何應(yīng)用到子網(wǎng)眼上的。 |
Transform | 一個(gè)通用的4x4的浮點(diǎn)數(shù)矩陣,用來(lái)描述一個(gè)變換。 |
Transformable | Node和Texture2D類的抽象基類。 |
TriangleStripArray | 定義了一個(gè)三角形帶數(shù)組。 |
VertexArray | 一個(gè)整型矢量數(shù)組,描述了頂點(diǎn)位置,法線,顏色或者紋理坐標(biāo)。 |
VertexBuffer | 存儲(chǔ)對(duì)于VertexArrays的引用,它包含了一個(gè)頂點(diǎn)集的位置,顏色,法線,以及紋理坐標(biāo)。 |
World | 一個(gè)特別的Group結(jié)點(diǎn),它作為場(chǎng)景圖最頂層的容器。 |
我們將開發(fā)一個(gè)簡(jiǎn)單的旋轉(zhuǎn)一個(gè)多邊形的3D應(yīng)用程序?yàn)槔T摱噙呅问且粋€(gè)立方體,它的紋理是一張舊汽車相片。列表1展示了例程midlet的主要類-應(yīng)用程序的中心類。該類負(fù)責(zé)創(chuàng)建應(yīng)用程序并建立起運(yùn)行MyCanvas的計(jì)時(shí)器。
列表1. MIDletMain類
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*; import java.util.*; public class MIDletMain extends MIDlet { static MIDletMain midlet; MyCanvas d = new MyCanvas(); Timer iTimer = new Timer(); public MIDletMain() { this.midlet = this; } public void startApp() { Display.getDisplay(this).setCurrent(d); iTimer.schedule( new MyTimerTask(), 0, 40 ); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public static void quitApp() { midlet.destroyApp(true); midlet.notifyDestroyed(); midlet = null; } class MyTimerTask extends TimerTask { public void run() { if( d != null ) { d.repaint(); } } } } |
列表2顯示了MyCanvas類,該類包含了應(yīng)用程序的所有圖形邏輯。init()方法負(fù)責(zé)結(jié)點(diǎn)的創(chuàng)建,紋理文件的裝載并設(shè)置紋理,外觀和背景也被一起設(shè)置。paint()方法負(fù)責(zé)著色并旋轉(zhuǎn)立方體。圖1展示了正在一個(gè)模擬器中運(yùn)行的實(shí)際程序。
列表2. MyCanvas類
import javax.microedition.lcdui.*;
import javax.microedition.m3g.*; public class MyCanvas extends Canvas { private Graphics3D graphics3d; private Camera camera; private Light light; private float angle = 0.0f; private Transform transform = new Transform(); private Background background = new Background(); private VertexBuffer vbuffer; private IndexBuffer indexbuffer; private Appearance appearance; private Material material = new Material(); private Image image; public MyCanvas() { // 創(chuàng)建Displayable對(duì)象以探聽命令事件 setCommandListener(new CommandListener() { public void commandAction(Command c, Displayable d) { if (c.getCommandType() == Command.EXIT) { MIDletMain.quitApp();}} }); try { init();} catch(Exception e) { e.printStackTrace();} } /** * 組件的初始化 */ private void init() throws Exception { addCommand(new Command("Exit", Command.EXIT, 1)); graphics3d = Graphics3D.getInstance(); camera = new Camera(); camera.setPerspective( 60.0f,(float)getWidth()/ (float)getHeight(), 1.0f, 1000.0f ); light = new Light(); light.setColor(0xffffff); light.setIntensity(1.25f); short[] vert = { 5, 5, 5, -5, 5, 5, 5,-5, 5, -5,-5, 5, -5, 5,-5, 5, 5,-5, -5,-5,-5, 5,-5,-5, -5, 5, 5, -5, 5,-5, -5,-5, 5, -5,-5,-5, 5, 5,-5, 5, 5, 5, 5,-5,-5, 5,-5, 5, 5, 5,-5, -5, 5,-5, 5, 5, 5, -5, 5, 5, 5,-5, 5, -5,-5, 5, 5,-5,-5, -5,-5,-5 }; VertexArray vertArray = new VertexArray(vert.length / 3, 3, 2); vertArray.set(0, vert.length/3, vert); //立方體的各個(gè)結(jié)點(diǎn)法線 byte[] norm = { 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0,-127, 0, 0,-127, 0, 0,-127, 0, 0,-127, -127, 0, 0, -127, 0, 0, -127, 0, 0, -127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0, 127, 0, 0,-127, 0, 0,-127, 0, 0,-127, 0, 0,-127, 0 }; VertexArray normArray = new VertexArray(norm.length / 3, 3, 1); normArray.set(0, norm.length/3, norm); //各個(gè)結(jié)點(diǎn)的紋理坐標(biāo) short[] tex = { 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1 }; VertexArray texArray = new VertexArray(tex.length / 2, 2, 2); texArray.set(0, tex.length/2, tex); int[] stripLen = { 4, 4, 4, 4, 4, 4 }; // 對(duì)象的VertexBuffer VertexBuffer vb = vbuffer = new VertexBuffer(); vb.setPositions(vertArray, 1.0f, null); vb.setNormals(normArray); vb.setTexCoords(0, texArray, 1.0f, null); indexbuffer = new TriangleStripArray( 0, stripLen ); //紋理圖像 image = Image.createImage( "/pic1.png" ); Image2D image2D = new Image2D( Image2D.RGB, image ); Texture2D texture = new Texture2D( image2D ); texture.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST); texture.setWrapping(Texture2D.WRAP_CLAMP,Texture2D.WRAP_CLAMP); texture.setBlending(Texture2D.FUNC_MODULATE); // 創(chuàng)建外觀(Appearance)對(duì)象 appearance = new Appearance(); appearance.setTexture(0, texture); appearance.setMaterial(material); material.setColor(Material.DIFFUSE, 0xFFFFFFFF); material.setColor(Material.SPECULAR, 0xFFFFFFFF); material.setShininess(100.0f); background.setColor(0xffffcc); } protected void paint(Graphics g) { graphics3d.bindTarget(g, true, Graphics3D.DITHER | Graphics3D.TRUE_COLOR); graphics3d.clear(background); //設(shè)置照相機(jī) Transform transform = new Transform(); transform.postTranslate(0.0f, 0.0f, 30.0f); graphics3d.setCamera(camera, transform); //設(shè)置燈光 graphics3d.resetLights(); graphics3d.addLight(light, transform); //設(shè)置旋轉(zhuǎn) angle += 1.0f; transform.setIdentity(); transform.postRotate(angle, 1.0f, 1.0f, 1.0f); graphics3d.render(vbuffer, indexbuffer, appearance, transform); graphics3d.releaseTarget(); } } |
小結(jié)
JSR 184對(duì)于可以運(yùn)行MIDP 2.0的設(shè)備來(lái)說(shuō),是一個(gè)節(jié)省時(shí)間和空間的可選的軟件開發(fā)包。它允許開發(fā)者使用兩種圖形方式-保留模式和立即模式-來(lái)產(chǎn)生3D圖形。本文集中講述了立即模式,并給出一個(gè)例子程序來(lái)說(shuō)明怎樣使用3D API。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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