|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
C#是盗用了Java的源代码,仿照开发的,原因是Java是开源的啊,盗了也白盗,还有一点,开发C#语言的团队是就是开发Java语言的团队,是微软重金挖过去的啊 1、简述
既然如今你已对3DAPI对照熟习并懂得了3D图形是怎样到场到挪动Java使用程序中的。上面将持续告知你如何利用3D外型软件以使编码和计划更加复杂。
现在,3D图形几近是任何一部游戏的关头部分,乃至一些使用程序也经由过程用3D情势来形貌信息而取得了乐成。如前文中所述,以当即形式和手工编码创建一切的3D对象的体例举行开辟速率很慢且很庞大。使用程序中多边形的一切角点必需在数组中自力编码。在JSR184中,这称为当即形式。
别的一种更初级的形式称为保存形式,它同意计划者利用诸如3DMaxStudio等3D建模软件来计划场景图,然后把它们使用在程序中。
2、3D编纂器
如今,最盛行的贸易动画制造软件应是3DStudioMax,它撑持输入模子或场景图到M3G格局(JSR184中指定的文件格局)。该文件格局是专门制定的,以合用于挪动设备的特有必要。但是,3DStudioMax十分高贵,即便它是一个很好的工具,也大概其实不合适于任何一团体。
Superscape公司有他本人的Swerve产物家属(SwerveStudio,SwerveClient,SwerveContent),以匡助软件开辟者来开辟基于3DJava的本机使用程序。遗憾的是,SwerveStudio仅适于无限数量的对Superscape十分熟习的开辟者。
另有一个自在工具能够选择利用:Blender。Blender是一个开源的3D外型工具,实在它的功效相称壮大。你能够用Blender来举行任何3D计划-从复杂的外型到完全的动画制造。只管如今还没有输入工具来输入Blender模子到M3G文件中,可是大概很快就呈现一些可用的工具(由于Blender是开源的)。
3、建模
怎样在MIDP使用程序中利用M3G文件呢?起首,你必要一个已有某种3D模子的M3G文件。你能够用Google引擎疾速查找一下,也能够利用和WirelessToolkit2.2(在Demo3D文件夹下)开辟包一同公布的现成文件。在本文中,我们将对Sun的Pogoroo例程(编者注:Sun开辟工具包自带例程)作深度修正(简化)。我们不让它动起来大概做任何奇异的事变,而仅仅在屏幕上展现各个对象。
4、加载World
起首,要从M3D文件中加载World。在pogoroo.m3g文件中,你会看到一只袋鼠在一根弹簧单高跷杆上腾跃,其身旁是一片绿茵。上面的列表1挪用了加载器类的办法load()。
列表1.加载
try{
//从M3D文件中加载World
myWorld=(World)Loader.load("/pogoroo.m3g")[0];
getObjects();
setupAspectRatio();
}
catch(Exceptione){
e.printStackTrace();
}
5、从3D天下中获得对象
3D天下已被加载,如今你必需从中获得各个对象(见列表2)。这里,3D天下中有四个对象,个中之一是有关动画(袋鼠在单脚跳)的信息。你可使用World的find()办法来获得这些对象。
列表2.从3DWorld中获得对象
try{
tRoo=(Group)myWorld.find(POGOROO);
tCams=(Group)myWorld.find(CAMERA);
acRoo=(Group)myWorld.find(TRANSFORM);
animRoo=(AnimationController)myWorld.find(ROO);
//获得动画的长度
AnimationTracktrack=acRoo.getAnimationTrack(0);
animLength=1000;//缺省长度为1秒
if(track!=null){
KeyframeSequenceks=track.getKeyframeSequence();
if(ks!=null)animLength=ks.getDuration();
}
}
catch(Exceptione){
e.printStackTrace();
}
6、设置窗口宽高比例
你必需设置窗口的宽高比例以使对象可以准确着色。列表3中的代码是未修改的-基础上同Sun的例子一样。起首,反省画布的宽度和高度,然后依据相机的范例来盘算宽高比例。
列表3.设置宽高比例
voidsetupAspectRatio(){
viewport_x=0;
viewport_y=0;
viewport_width=myCanvas.getWidth();
viewport_height=myCanvas.getHeight();
Cameracam=myWorld.getActiveCamera();
float[]params=newfloat[4];
inttype=cam.getProjection(params);
if(type!=Camera.GENERIC){
//盘算窗口的宽高比
floatwaspect=viewport_width/viewport_height;
if(waspect<params[1]){
floatheight=viewport_width/params[1];
viewport_height=(int)height;
viewport_y=(myCanvas.getHeight()-viewport_height)/2;
}
else{
floatwidth=viewport_height*params[1];
viewport_width=(int)width;
viewport_x=(myCanvas.getWidth()-viewport_width)/2;
}
}
}
7、革新视图
为了革新视图,你能够用TimerTask来挪用画布的repaint()办法。另外一种办法是间接利用线程,然后创立ExampleCanvas(画布类的名字)来完成Runnable接口。
列表4. 革新视图
privateclassRefreshTaskextendsTimerTask
{
publicvoidrun(){
if(myCanvas!=null&&myGraphics3D!=null&&myWorld!=null){
intstartTime=(int)System.currentTimeMillis();
intvalidity=myWorld.animate(startTime);
myCanvas.repaint(viewport_x,viewport_y,viewport_width,viewport_height);
}
}
}
8、完全的例程代码剖析
在列表5中,你会看到使用程序的完全代码。固然长些,可是比Sun的例子要复杂很多。你能够经由过程给使用程序增加上一些举措和逻辑来实习你的MIDP妙技。
列表5.完全的例程代码
packagecom.kontio;
importjavax.microedition.midlet.*;
importjavax.microedition.lcdui.*;
importjava.lang.IllegalArgumentException;
importjava.io.*;
importjava.util.*;
importjavax.microedition.m3g.*;
publicclassExample3DextendsMIDletimplementsCommandListener{
//我们在场景中利用的对象的UserID
staticfinalintPOGOROO=554921620;
staticfinalintCAMERA=769302310;
staticfinalintTRANSFORM=347178853;
staticfinalintROO=418071423;
privateDisplaymyDisplay=null;
privateExampleCanvasmyCanvas=null;
privateTimermyRefreshTimer=newTimer();
privateTimerTaskmyRefreshTask=null;
privateCommandexitCommand=newCommand("Exit",Command.ITEM,1);
Graphics3DmyGraphics3D=Graphics3D.getInstance();
WorldmyWorld=null;
privateAnimationControlleranimRoo=null;
privateGrouptRoo=null;
privateGrouptCams=null;
privateGroupacRoo=null;
privateintanimLength=0;
intviewport_x;
intviewport_y;
intviewport_width;
intviewport_height;
publicExample3D(){
super();
myDisplay=Display.getDisplay(this);
myCanvas=newExampleCanvas(this);
myCanvas.setCommandListener(this);
myCanvas.addCommand(exitCommand);
}
publicvoidstartApp()throwsMIDletStateChangeException{
myDisplay.setCurrent(myCanvas);
try{
//从文件中加载World
myWorld=(World)Loader.load("/pogoroo.m3g")[0];
getObjects();
setupAspectRatio();
}
catch(Exceptione){
e.printStackTrace();
}
myRefreshTask=newRefreshTask();
//调剂一个主要实行的计时器以显现出帧速度20fps.
myRefreshTimer.schedule(myRefreshTask,0,50);
}
voidsetupAspectRatio(){
viewport_x=0;
viewport_y=0;
viewport_width=myCanvas.getWidth();
viewport_height=myCanvas.getHeight();
Cameracam=myWorld.getActiveCamera();
float[]params=newfloat[4];
inttype=cam.getProjection(params);
if(type!=Camera.GENERIC){
//盘算窗口的宽高比例
floatwaspect=viewport_width/viewport_height;
if(waspect<params[1]){
floatheight=viewport_width/params[1];
viewport_height=(int)height;
viewport_y=(myCanvas.getHeight()-viewport_height)/2;
}
else{
floatwidth=viewport_height*params[1];
viewport_width=(int)width;
viewport_x=(myCanvas.getWidth()-viewport_width)/2;
}
}
}
publicvoidgetObjects(){
try{
tRoo=(Group)myWorld.find(POGOROO);
tCams=(Group)myWorld.find(CAMERA);
acRoo=(Group)myWorld.find(TRANSFORM);
animRoo=(AnimationController)myWorld.find(ROO);
//获得动画的长度
AnimationTracktrack=acRoo.getAnimationTrack(0);
animLength=1000;//缺省的长度,1秒
if(track!=null){
KeyframeSequenceks=track.getKeyframeSequence();
if(ks!=null)
animLength=ks.getDuration();
}
}
catch(Exceptione){
e.printStackTrace();
}
}
publicvoidpauseApp(){}
publicvoiddestroyApp(booleanunconditional)throwsMIDletStateChangeException{
myRefreshTimer.cancel();
myRefreshTimer=null;
myRefreshTask=null;
}
publicvoidpaint(Graphicsg){
if(g.getClipWidth()!=viewport_width||
g.getClipHeight()!=viewport_height||
g.getClipX()!=viewport_x||
g.getClipY()!=viewport_y){
g.setColor(0x00);
g.fillRect(0,0,myCanvas.getWidth(),myCanvas.getHeight());
}
if((myGraphics3D!=null)&&(myWorld!=null)){
myGraphics3D.bindTarget(g);
myGraphics3D.setViewport(viewport_x,viewport_y,
viewport_width,viewport_height);
myGraphics3D.render(myWorld);
myGraphics3D.releaseTarget();
}
}
publicvoidcommandAction(Commandcmd,Displayabledisp)
{
if(cmd==exitCommand){
try{
destroyApp(false);
notifyDestroyed();
}
catch(Exceptione){
e.printStackTrace();
}
}
}
privateclassRefreshTaskextendsTimerTask{
publicvoidrun(){
if(myCanvas!=null&&myGraphics3D!=null&&myWorld!=null{
intstartTime=(int)System.currentTimeMillis();
intvalidity=myWorld.animate(startTime);
myCanvas.repaint(viewport_x,viewport_y,viewport_width,viewport_height);
}
}
}
classExampleCanvasextendsCanvas{
Example3DmyRooMIDlet;
inti=0;
ExampleCanvas(Example3DTestlet){myRooMIDlet=Testlet;}
voidinit(){}
voiddestroy(){}
protectedvoidpaint(Graphicsg){myRooMIDlet.paint(g);}
protectedvoidkeyPressed(inti){}
protectedvoidkeyReleased(inti){}
protectedvoidkeyRepeated(inti){}
protectedvoidpointerDragged(intx,inty){}
protectedvoidpointerPressed(intx,inty){}
protectedvoidpointerReleased(intx,inty){}
}
}
9、运转在摹拟器中的例程
展现了例程在WTK摹拟器中运转的了局。图中的袋鼠和地步看上往棒极了。假如计划者选择对个中任何对象改动一下的话,能够用the3D工具来完成,而在例程MIDlet中不必要作任何变更。
例程在摹拟器中运转的了局
10、结论
如今,你又看到一种利用JSR184(也称挪动3DAPI)的更初级的体例来创立3D使用程序。在保存形式下,计划者可使用现有的3D建模工具来创立3D天下和个中的对象,然后把这些模子输入到M3G文件中。以后,使用程序只需装进该模子并在屏幕上绘制3D天下的视图便可。
没有那个大公司会傻了吧唧用.net开发大型项目,开发了,那等于自己一半的生命线被微软握着呢。而.net不行,限制在window系统,又是捆绑,鄙视微软之! |
|