頁:
[1]
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]