AIR game (九)3D界面的搭建

前面的2D工程我们已经完成的差不多了。下面我们就应该开始我们的3D画面的程序编写了。在笔者编写这个DEMO的时候我们所使用的flare3D引擎刚刚更新到2.0版本,FLEX版本更新到4.6,为了配合做好的效果,和最优的效果。我们对程序进行了一些小小的调整,为了适应新版本的软件。现在我们就来看看如何编写第一个3D画面。

先来看一下3D画面1的预想图。

点击查看原图

为了实现这样一个3D画面,我们需要美工来配合,因为我们希望缩减工作量,同时又能得到完美的图像。那么美工需要制作两个3D文件,一个是星空背景。这里我们把背景做成一个很大的球体,然后在球体内部进行星空贴图,贴图后我们将3D画面中的摄像机放置其中,并且设置视觉角度,这样就感觉是在一个无限空间中了。但实际上我们是在一个空间大小有限的球体内制作所有视觉元素。那么第二个元素就是画面中这几个星球了,我们例举太阳系中比较突出的5个星球,分别为太阳,木星,火星,土星和地球。

在flare3D中我们要创建一个3D元素需要先建立一个3D场景,然后所有的画面均出现在这个3D场景中。下面我们来看一下这一步的代码:

this.scene = new Scene3D(this);
this.scene.antialias = 2;
//
this.scene.addEventListener(Scene3D.COMPLETE_EVENT,load_complete);
this.scene.addEventListener(Scene3D.PROGRESS_EVENT,loading);


下面我们进行两个F3D文件的加载操作:

this.fArr.push( this.scene.addChildFromFile(“res/threed/gkbg.f3d”) );
this.fArr.push( this.scene.addChildFromFile(“res/threed/gk.f3d”) );

fArr是一个数组,这里我们当做对象池来使用,方便资源管理。当我们完成资源加载后就可以对所有对象的位置进行调整。下面是加载完成后的代码:

private function load_complete(evt:Event):void
{
YcameraXYZ.x = this.scene.camera.x;
YcameraXYZ.y = this.scene.camera.y;
YcameraXYZ.z = this.scene.camera.z;
var evtObj:EventDispatcher = Tetris.getEvtObj();
var shijian:Event = new Event(Event.COMPLETE);
evtObj.dispatchEvent(shijian);
sceneStart();

}

private function sceneStart():void
{

this.scene.camera.lookAt( cameraXYZ.x,cameraXYZ.y,cameraXYZ.z );

this.fArr[0].getChildByName(“bg”).scaleX = 5;
this.fArr[0].getChildByName(“bg”).scaleY = 5;
this.fArr[0].getChildByName(“bg”).scaleZ = 5;

var i:uint = 1;
while(i<6)
{
(this.fArr[1].getChildByName(“GK” + i) as Mesh3D).addEventListener(MouseEvent3D.CLICK,gkclick);
(this.fArr[1].getChildByName(“GK” + i) as Mesh3D).addEventListener(MouseEvent3D.MOUSE_OVER, mouseOverEvent );
(this.fArr[1].getChildByName(“GK” + i) as Mesh3D).addEventListener( MouseEvent3D.MOUSE_OUT, mouseOutEvent );

i++;
}

this.scene.addEventListener(Scene3D.UPDATE_EVENT,updata);
}

最后我们要进行是对星球进行鼠标点击事件的处理,当我们鼠标点击星球的时候,场景的镜头会已被点击的星球为目标进行镜头拉伸,这样我们就之做了一个简单的3D MENU。代码如下,这里,我们使用的是引擎来制作缓动效果。

if(this.gkClickEnabled)
{
this.gkClickEnabled = false;
evt.target.setScale( 1, 1, 1 );
TweenMax.to(cameraXYZ,2,{y:evt.target.y,z:evt.target.z,x:evt.target.x, onUpdate:updatas,onComplete:effectOver});
TweenMax.to(this.scene.camera, 2, {y:evt.target.y,z:evt.target.z,x:(evt.target.x + 40)});
}

private function updatas():void
{

this.scene.camera.lookAt( cameraXYZ.x,cameraXYZ.y,cameraXYZ.z );
}
当我们的缓动完成之后我们需要制作一个状态改变,这个改变就是我们后面要做的游戏内容了,关于游戏内容部分我们将在下篇文章中讲解。