📄 flash3d.as
字号:
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.ColorTransform;
public class Flash3D extends Sprite
{
//给每个定点编号,以点的编号确定面
private var plane:Array = [[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14],[15,16,17,18,19],[20,21,22,23,24],[25,26,27,28,29],
[30,31,32,33,34],[35,36,37,38,39],[40,41,42,43,44],[45,46,47,48,49],[50,51,52,53,54],[55,56,57,58,59],
[1,0,5,9,11,10],[2,1,10,14,16,15],[3,2,15,19,21,20],[4,3,20,24,26,25],[0,4,25,29,6,5],
[11,9,8,37,36,12],[16,14,13,32,31,17],[21,19,18,52,51,22],[26,24,23,47,46,27],[6,29,28,42,41,7],
[8,7,41,40,38,37],[13,12,36,35,33,32],[18,17,31,30,53,52],[23,22,51,50,48,47],[28,27,46,45,43,42],
[59,55,34,30,53,54],[58,59,54,50,48,49],[57,58,49,45,43,44],[56,57,44,40,38,39],[55,56,39,35,33,34]];
//给出所有顶点的坐标
private var dx:Array = [0,-0.326477,-0.201774,0.201774,0.326477,
0,0.326477,0.201774,-0.201774,-0.326477,
-0.652955,-0.652955,-0.854729,-0.979432,-0.854729,
-0.403548,-0.730026,-0.730026,-0.403548,-0.201774,
0.403548,0.201774,0.403548,0.730026,0.730026,
0.652955,0.854729,0.979432,0.854729,0.652955,
-0.652955,-0.854729,-0.979432,-0.854729,-0.652955,
-0.730026,-0.730026,-0.403548,-0.201774,-0.403548,
0.201774,0.403548,0.730026,0.730026,0.403548,
0.854729,0.979432,0.854729,0.652955,0.652955,
0.326477,0.201774,-0.201774,-0.326477,0,
-0.326477,-0.201774,0.201774,0.326477,0];
private var dy:Array = [0.343279,0.106079,-0.277718,-0.277718,0.106079,
0.686557,0.792636,0.964275,0.964275,0.792636,
0.212158,0.555436,0.489876,0.106079,-0.0655604,
-0.555436,-0.449358,-0.661515,-0.898715,-0.833155,
-0.555436,-0.833155,-0.898715,-0.661515,-0.449358,
0.212158,-0.0655604,0.106079,0.489876,0.555436,
-0.555436,-0.489876,-0.106079,0.0655604,-0.212158,
0.449358,0.661515,0.898715,0.833155,0.555436,
0.833155,0.898715,0.661515,0.449358,0.555436,
0.0655604,-0.106079,-0.489876,-0.555436,-0.212158,
-0.792636,-0.964275,-0.964275,-0.792636,-0.686557,
-0.106079,0.277718,0.277718,-0.106079,-0.343279];
private var dz:Array = [-0.939234,-0.939234,-0.939234,-0.939234,-0.939234,
-0.727076,-0.514918,-0.171639,-0.171639,-0.514918,
-0.727076,-0.514918,-0.171639,-0.171639,-0.514918,
-0.727076,-0.514918,-0.171639,-0.171639,-0.514918,
-0.727076,-0.514918,-0.171639,-0.171639,-0.514918,
-0.727076,-0.514918,-0.171639,-0.171639,-0.514918,
0.514918,0.171639,0.171639,0.514918,0.727076,
0.514918,0.171639,0.171639,0.514918,0.727076,
0.514918,0.171639,0.171639,0.514918,0.727076,
0.514918,0.171639,0.171639,0.514918,0.727076,
0.514918,0.171639,0.171639,0.514918,0.727076,
0.939234,0.939234,0.939234,0.939234,0.939234];
/*
private var plane:Array = [[0,1,2],[0,1,3],[1,2,3],[0,2,3]];
private var dx:Array = [0.8165,-0.8165,0,0];
private var dy:Array = [-0.4714,-0.4174,0.9428,0];
private var dz:Array = [-0.3333,-0.3333,-0.3333,1];*/
//这里定义的是立方体的颜色,其实,要6个面,每个面的颜色不同,就把这个colour定义成数组就可以了。
//同样前面加个0,也是上面的理由。
private var colour:Array = [0,0,0,0,0,0,0,0,0,0,0,0,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF];
//private var colour:Array =[0,0x4499FF,0x6F13EC,0xF1F00E,0x6CE31C,0x26D9A3,0x808080];
private const trans:Number = Math.PI/180;//下面的弧度和角度的转换用
private const cube_width:int = 200;//用于设定立方体的边的长度
private const d:int = 400;// 观察者与屏幕的距离
private const num_planes:int = plane.length;// 面数
private const num_nodes:int = dx.length;// 点数
//下面这4个定义对用鼠标控制旋转的速度有关,
private var xz_angle_inc:int = 0;
private var yz_angle_inc:int = 0;
private var angle_inc_factor:Number = .1;
private var angle_dec_factor:Number = .9;
//3D物体的中心
private var o_x:int = 0;
private var o_y:int = 0;
//保存各点的坐标
private var node:Array = new Array();
private var p_node:Array = new Array();
//判断鼠标是否有按下
private var mouse_down:Boolean = false;
//保存上一帧的鼠标坐标
private var old_mx:int = 0;
private var old_my:int = 0;
public function Flash3D()
{
var i:int = 0;
//把坐标原点移到屏幕中心
o_x = this.stage.stageWidth/2;
o_y = this.stage.stageHeight/2;
//边长调整... 主要是求出8个点,在设定边长,情况下的坐标
for (i=0; i<num_nodes; i++)
{
node[i] = new Object();
node[i].x = dx[i]*(cube_width/2);
node[i].y = dy[i]*(cube_width/2);
node[i].z = dz[i]*(cube_width/2);
}
for (i=0; i<num_planes; i++)
{//建立6个空白的影片剪辑,主要用于,每天影片剪辑,画一个立方体的面。
this.addChild(new Shape());
}
this.stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
this.stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
this.stage.addEventListener(Event.ENTER_FRAME,onEnterFrame);
}
//版面的调整 下面的_root.onEnterFrame 会调用这里进行画立方体
//对这里不理解的,看附录一的代码!
private function create_planes():void
{
var depths:Array = new Array();
for (var i:int = 0; i<num_planes; i++)
{
var depth:int = 0;//设定深度初始值
var aplane:Shape = Shape(this.getChildAt(i));
aplane.graphics.clear();//清除上次画的面,不用这句语句,可以看到面的连续旋转的会是什么轨迹,程序是怎么画的。不过,很难看。
aplane.graphics.beginFill(colour[i],100);//设置立方体面的颜色,colour可以变数组colour[i],这样每个面可以画,不同的颜色。
aplane.graphics.lineStyle(3,0xFF0000,100);//设置立方体的棱的颜色
aplane.graphics.moveTo(p_node[plane[i][0]].x,p_node[plane[i][0]].y);//这里设定每个正方形面,开始画时的启始点。
for (var j:int=plane[i].length-1; j>=0; j--)
{//这里是连续读取4个点,画好一个正方形
aplane.graphics.lineTo(p_node[plane[i][j]].x,p_node[plane[i][j]].y);
depth += node[plane[i][j]].z;//求每个面上4点旋转后,4个点的深度变化,并相加
}
depth /= -plane[i].length;//注意除以负数,这样符合,FLASH的深度变化的远近情况
//有点的深度变化,来控制面的层次变化,如果没有这句,
//可以看到一个立方体在旋转是6个面的层次混乱。
depths.push(depth);
for(var index:int = depths.length-1; index>0; index--)
{
if(depths[index]<depths[index-1])
{
var temp:int = depths[index];
depths[index] = depths[index-1];
depths[index-1] = temp;
}
else
{
break;
}
}
this.setChildIndex(aplane,index);
//用深度变化,在传值,这个参数主要用于下面的语句,下面的语句,用于立方体在旋转时,
//面的亮度的调整,符合一定的光照效果。
var amount:int = depth-50;
//这句语句可以查看FLASH_AS语法参考,可以找到的。主要是对色彩的设置。
var ct:ColorTransform = new ColorTransform();
ct.blueOffset = ct.greenOffset = ct.redOffset = amount;
aplane.transform.colorTransform = ct;
}
}
private function onMouseDown(e:Event):void
{
mouse_down = true;
}
private function onMouseUp(e:Event):void
{
mouse_down = false;
}
private function onEnterFrame(e:Event):void
{
if (mouse_down)
{//判断,鼠标情况,对鼠标移动距离的相加,如果,没有“+=”而用“=”,这样鼠标每点一次,图象就跳回初始状态。可以自己实验看下效果,进行对比。
xz_angle_inc += (this.mouseX-old_mx)*angle_inc_factor;
yz_angle_inc += (this.mouseY-old_my)*angle_inc_factor;
}
for (var i:int=0; i<num_nodes; i++)
{
var sin_xz:Number = Math.sin(xz_angle_inc*trans);//对弧度与角度的转化公式。
var cos_xz:Number = Math.cos(xz_angle_inc*trans);
var sin_yz:Number = Math.sin(yz_angle_inc*trans);
var cos_yz:Number = Math.cos(yz_angle_inc*trans);
var rx1:Number = cos_xz*node[i].x-sin_xz*node[i].z;//这里就是上面的坐标转换公式里的,先按Y轴旋转,再按X轴旋转。
var ry1:Number = node[i].y;
var rz1:Number = cos_xz*node[i].z+sin_xz*node[i].x;
var rx2:Number = rx1;
var ry2:Number = cos_yz*ry1+sin_yz*rz1;
var rz2:Number = cos_yz*rz1-sin_yz*ry1;
node[i].x = rx2;//这里是把每个旋转后,得到的先的坐标保存在变量里
node[i].y = ry2;
node[i].z = rz2;
var p_ratio:Number = d/(d+node[i].z);//这个是上面d/(d+z)
p_node[i] = new Object();
p_node[i].x = o_x+node[i].x*p_ratio;//确定在屏幕上点的位置
p_node[i].y = o_y-node[i].y*p_ratio;
}
xz_angle_inc *= angle_dec_factor;//这个加速鼠标控制时的旋转速度
yz_angle_inc *= angle_dec_factor;
old_mx = this.mouseX;//得到影片开始时的鼠标坐标
old_my = this.mouseY;
create_planes();//调用上面的函数,画出立方体
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -