查看完整版本: as3代碼制作地球自轉的問題
頁: [1]

yunsc 發表於 2013-9-21 12:40 PM

as3代碼制作地球自轉的問題

本帖最後由 yunsc 於 2013-9-21 01:22 PM 編輯

http://53798.43la.com.cn/earth.swf
  對于地球自轉的問題,在as3沒有出現前,人們通過圖片在遮罩下循環不間斷移動的方法制作,上面的“地球1”就是以這種方法制作的。

  然而,在as3出現後,用代碼語句的方法了。上面的“地球2”是用代碼方法制作的,跟“地球1”放在一起對比,很明顯,“地球2”的立體性強許多,有縱深感,鼠標放在上面移動時,會跟著立體轉動,“地球1”的平推性暴露出來了。通過對比,用as3代碼制作的“地球2”豐富精彩許多了。

  下面把“地球2”的制作方法在這裏跟大家分享。
  一、打開含as3的flash中“ActionScript3.0類”,在“類名稱” 裏填入“EarthTurn”,輸入代碼如下:

package {

import flash.display.*;

import flash.geom.*;

public class EarthTurn extends Sprite {

private var bdPic:BitmapData;

private var vertsVec:Array;

private var picWidth:Number;

private var picHeight:Number;

private var spSphere:Sprite;

private var spSphereImage:Sprite;

private var rad:Number;

private var nMesh:Number;

private var tilesNum:Number;

public function EarthTurn(b:BitmapData) {

bdPic = b;

picWidth = bdPic.width;

picHeight = picWidth / 2;

rad = Math.floor(picWidth / (Math.PI * 2));

spSphere = new Sprite();

spSphere.rotationX = 0;

spSphere.rotationY = 0;

spSphere.rotationZ = 0;

spSphereImage = new Sprite();

this.addChild(spSphereImage);

nMesh = 30;

tilesNum = nMesh*nMesh;

vertsVec = [];

setVertsVec();

rotateSphere(0,0,0);

}


private function setVertsVec():void {

var i:int;

var j:int;

var istep:Number;

var jstep:Number;

istep = 2 * Math.PI / nMesh;

jstep = Math.PI / nMesh;

for( i = 0;i <= nMesh;i++){

vertsVec = [];

for( j = 0;j <= nMesh;j++){


vertsVec = new Vector3D(rad * Math.sin(istep * i) * Math.sin(jstep * j),-rad * Math.cos(jstep * j),-rad * Math.cos ( istep * i) * Math.sin(jstep * j));

                     }

         }

}


public function rotateSphere(rotx:Number,roty:Number,rotz:Number):void {

var paramMat:Matrix3D;

spSphere.transform.matrix3D.appendRotation(rotx,Vector3D.X_AXIS);

spSphere.transform.matrix3D.appendRotation(roty,Vector3D.Y_AXIS);

spSphere.transform.matrix3D.appendRotation(rotz,Vector3D.Z_AXIS);

paramMat=spSphere.transform.matrix3D.clone();

transformSphere(paramMat);



}


public function autoSpin(roty:Number):void {

var paramMat:Matrix3D;

spSphere.transform.matrix3D.prependRotation(roty,Vector3D.Y_AXIS);

paramMat = spSphere.transform.matrix3D.clone();

transformSphere(paramMat);

}


private function transformSphere(mat:Matrix3D):void {

var i:int;

var j:int;

var n:int;

var distArray = [];

var dispPoints = [];

var newVertsVec = [];

var zAverage:Number;

var dist:Number;

var curVertsNum:int = 0;

var vertices:Vector.<Number> = new Vector.<Number>();

var indices:Vector.<int> = new Vector.<int>();

var uvtData:Vector.<Number> = new Vector.<Number>();


var  curv0  = new Point();

var  curv1  = new Point();

var  curv2  = new Point();

var  curv3  = new Point();

var curObjMat:Matrix3D = mat.clone();

vertices = new Vector.<Number>();

indices = new Vector.<int>();

uvtData = new Vector.<Number>();

spSphereImage.graphics.clear();

for(i = 0;i<= nMesh;i++){

newVertsVec = [];

for(j = 0;j<= nMesh;j++){

newVertsVec = curObjMat.deltaTransformVector(vertsVec);

      }

}


for(i = 0;i<nMesh;i++){

for(j = 0;j<nMesh;j++){

zAverage = (newVertsVec.z + newVertsVec.z + newVertsVec.z + newVertsVec.z) / 4;

dist = zAverage;

distArray.push();

}

}

distArray.sort(byDist);

for(i = 0;i <= nMesh;i++){

dispPoints = [];

for(j = 0;j <= nMesh;j++){

dispPoints = new Point(newVertsVec.x,newVertsVec.y);

     }
}

for(n = 0;n<tilesNum;n++){

i = distArray;

j = distArray;

curv0 = dispPoints.clone();

curv1 = dispPoints.clone();

curv2=dispPoints.clone();

curv3 = dispPoints.clone();

vertices.push(curv0.x,curv0.y,curv1.x,curv1.y,curv2.x,curv2.y,curv3.x,curv3.y);

indices.push(curVertsNum,curVertsNum + 1,curVertsNum + 3,curVertsNum + 1,curVertsNum + 2,curVertsNum + 3);

uvtData.push(i / nMesh,j / nMesh,(i + 1) / nMesh,j / nMesh,(i + 1) / nMesh,(j + 1) / nMesh,i / nMesh,(j + 1) / nMesh);

curVertsNum += 4;

}

spSphereImage.graphics.beginBitmapFill(bdPic);

spSphereImage.graphics.drawTriangles(vertices,indices,uvtData);

spSphereImage.graphics.endFill();

}


private function byDist(v:Array,w:Array):Number {

if (v > w){

return -1;

} else if (v < w){

return 1;

} else {

return 0;
      }

}



public function destroy():void {

spSphereImage.graphics.clear();

spSphereImage = null;

spSphere = null;

            }

      }

}

把該文件保存在某一文件夾裏。

  二、新建一個“.fla”,導入地球平面圖(寬高比例爲2:1),右擊“庫”面板中的圖片標簽欄,在彈出的面板中點擊“屬性”。打開後,在“爲ActionScript導出(x)前面打勾”,在“類(C)”後把名稱改爲“Earth”。

  三、新建插入影片剪輯元件1,在第一層(僅一層)第一幀的動作面板輸入:
//導入EarthTurn類
import EarthTurn;
//創建一個地球
var board:Sprite = new Sprite();
//添加到顯示列表
this.addChild(board);
//生成 datatype EarthTurn 的一個函數。
// 設定函數初始值。
var ball:EarthTurn;
//旋轉的一個布爾值的函數。
var autoOn:Boolean = true;
//兩個函數爲鼠標旋轉。
var prevX:Number;
var prevY:Number;
//地球的位置.
var ballX:Number = 250;
var ballY:Number = 250;
//貼圖


var imageData:BitmapData = new Earth(580,290);
ball = new EarthTurn(imageData);
board.addChild(ball);
ball.x = ballX;
ball.y = ballY;
//濾鏡
ball.filters = ;
this.addEventListener(Event.ENTER_FRAME,autoRotate);
board.addEventListener(MouseEvent.ROLL_OUT,boardOut);
board.addEventListener(MouseEvent.MOUSE_MOVE,boardMove);
board.addEventListener(MouseEvent.MOUSE_OVER,boardDown);
board.addEventListener(MouseEvent.MOUSE_UP,boardUp);
function autoRotate(e:Event):void {
if (autoOn) {
ball.autoSpin(-1);
}
}
//三個偵聽爲旋轉和鼠標。
function boardOut(e:MouseEvent):void {
autoOn = true;
}
function boardDown(e:MouseEvent):void {
prevX = board.mouseX;
prevY = board.mouseY;
autoOn = false;
}
function boardUp(e:MouseEvent):void {
autoOn = true;
}
function boardMove(e:MouseEvent):void {
var locX:Number = prevX;
var locY:Number = prevY;
//取反
if (! autoOn) {
prevX = board.mouseX;
prevY = board.mouseY;
ball.rotateSphere(prevY - locY, - (prevX - locX),0);
e.updateAfterEvent();
}
}
  四、回到“場景”,在第一層導入一張底圖,在第二層拖進元件1。完成後,把該fla保存在與“EarthTurn.as”文件的同一文件夾中。測試影片,根據情況調整元件1在場景中的位置。




注:需要源文件者,可留言後向我索取。





...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>
頁: [1]