查看: 1821|回复: 3
打印 上一主题 下一主题

flash教程:伪3D菜单的实现

[复制链接]
.    

3797

主题

11

听众

5万

积分

首席设计师

Rank: 8Rank: 8

纳金币
32328
精华
41

活跃会员 优秀版主 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2012-10-10 14:37:02 |只看该作者 |倒序浏览
今天我们来讲这个互动的3D菜单。不过我们这里所讲述的方法是完全没有经过Z轴计算的,也就是说是一个伪3D的效果。


在解释结构之前,对整个作品的运动把握是很重要的。首先我们看例子,在这里有5个立方体柱子以画面最右方的某点为消失点向外沿伸。这个立方体的前侧会根据其与鼠标的距离而变换大小和左右移动。另外,立方体对鼠标的纵方向(Y)移动也有反应,可以随其上下移动。
如我们刚才说的,这个作品是没有Z轴运算的,场景中的实例会根据X和Y的坐标来模拟Z轴的空间感觉。在基本的立方体产生的过程中将运用AS的填充和画线命令。
首先先做一个正方形的按钮,你可以自己为它定制大小,例子中的是一个75*75大小的正方形,将它的填充作成透明(alpha=0)。接着制作五个MC,我们把它们命名为MM-a1_typo~MM-a5_typo,将刚才作的透明按钮放进去,注意按钮对于中心点都要有一个递增的偏移植。比如MM-a5_typo在x=-150的位置,而MM-a4_typo则在x=-250,依次类推,到MM-a1_typo,x=550。这样一来当把所有这五个MC实例的中心点对齐后,它们便会均匀地分布在X轴上了,对它们进行放大或者缩小都会以相同“消失点”为中心,这样便会产生出***效果。
在场景中给这五个MC的实例起实例名为“typo”,因为他们处在不同的父级中,所以起相同的名字就可以了,然后在这五个实例上加入AS——
onClipEvent (enterFrame) {

ppp = getBounds(this);

pointdataMin = {x:ppp.xMin, y:ppp.yMin};

pointdataMax = {x:ppp.xMax, y:ppp.yMax};

this.localToGlobal(pointDataMin);

this.localToGlobal(pointDataMax);

xMinData = pointdataMin.x;

yMinData = pointdataMin.y;

xMaxData = pointdataMax.x;

yMaxData = pointdataMax.y;

}
这里我们所用的函数getBounds会取得实例坐标的四个级值点(即X轴上的最大最小值和Y轴上的最大最小值,也就是矩形的四个顶点),分别存在xMin,yMin,xMax,yMax中。另外localToGlobal可以将MC中的空间坐标转为全局,也就是根目录中的坐标植。所以经过这一计算后,xMinData、 yMinData、xMaxData 、 yMaxData 这四个变量中会存储正方形的顶点信息并将之转为根目录下的坐标值。
现在再将这五个typo都转化为MC(在场景中按F8即可),我们给它们起名为MM-a1~MM-a5,并将随之产生的实例命名为a1~a5。给它们都分别加入AS——
onClipEvent (load) {

   objnum = _name.slice(1, 2);

   _parent.init3D(objNum);

}

onClipEvent (enterFrame) {

   tb = this.getBounds(this);

   valueA = Math.pow(_parent._xmouse - tb.xMin, 2);

   valueB = Math.pow(_parent._ymouse - tb.yMax, 2);

   distance = Math.sqrt(valueA + valueB) * 0.5;

   if (distance <= 200) {

       this._xscale = this._xscale + (((200 - distance) - this._xscale) * 0.1);

       this._yscale = this._yscale + (((200 - distance) - this._yscale) * 0.1);

   } else {

       this._xscale = this._xscale + ((50 - this._xscale) * 0.1);

       this._yscale = this._yscale + ((50 - this._yscale) * 0.1);

    }

   this.typo._x = _parent._ymouse * 0.1;

   this.typo._y = this.typo._y + (((_parent._ymouse - this.typo._y) * 0.1) * objNum);

   _parent.move3D(objnum);

}
这段AS一开始会把实例名的一部分切下来,也就是a1,a2,a3…的序号1,2,3……。并将之传递给父级目录下的init3D这个函数。接着,在每一帧都计算鼠标与正方形左下角顶点的距离,将对MC进行动态的放缩。
现在对这五个加入了AS的影片实例a1~a5进行排序,分别将他们放在不同的层中,靠右边的层要高一点,因为它要压在其左边层的上方。排好层后再新建一层,加入如下AS——
function init3D(objnum) {

i = 1;

while (i<=4) {

this[("newName"+objnum)+i] = ("sq"+objnum)+i;

_root.createEmptyMovieClip(this[("newName"+objnum)+i], (objnum*10)+i);

i++;

}

}

function move3D(objnum) {

Xorigin = _x;

Yorigin = _y;

with (_root[("sq"+objnum)+"3"]) {

clear();

beginFill("0x"+colorData[2], 100);

MoveTo(Xorigin, Yorigin);

LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMindata);

LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMaxdata);

endFill();

}

with (_root[("sq"+objnum)+"4"]) {

clear();

colors = [15133171, 13421772];

alphas = [100, 100];

ratios = [0, 255];

matrix = {matrixType:"box", x:_root._xmouse, y:_root._xmouse, w:550, h:400, rradian/180)*Math.PI};

beginGradientFill("linear", colors, alphas, ratios, matrix);

MoveTo(this["a"+objnum].typo.xMindata, this["a"+objnum].typo.yMindata);

LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMindata);

LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMaxdata);

LineTo(this["a"+objnum].typo.xMindata, this["a"+objnum].typo.yMaxdata);

endFill();

}

if (_root._ymouse<_y) {

_root[("sq"+objnum)+"2"].clear();

with (_root[("sq"+objnum)+"1"]) {

  clear();

  beginFill("0x"+colorData[0], 100);

  MoveTo(Xorigin, Yorigin);

  LineTo(this["a"+objnum].typo.xMindata, this["a"+objnum].typo.yMaxdata);

  LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMaxdata);

  endFill();

}

} else if (_root._ymouse>=_y) {

_root[("sq"+objnum)+"1"].clear();

with (_root[("sq"+objnum)+"2"]) {

  clear();

  beginFill("0x"+colorData[1], 100);

  MoveTo(Xorigin, Yorigin);

  LineTo(this["a"+objnum].typo.xMaxdata, this["a"+objnum].typo.yMindata);

  LineTo(this["a"+objnum].typo.xMindata, this["a"+objnum].typo.yMindata);

  endFill();

}

}

}

colorData = ["333333", "999999", "666666"];
这段AS首先会建立四个空的MC,它们是用来装立方体的各个面的。在后面的move3D部分就开始进行绘图指令了。("sq"+objnum)+"3"这一部分用来绘制右侧的面,("sq"+objnum)+"4"画正面的正方形,后面的("sq"+objnum)+"2"和("sq"+objnum)+"1"分别是上下两个面,它里面加了一个判断,当鼠标在消失点上方的时候那么就显示下边的面,在下方的时候就显示上方的面。
到这里为止,这种伪3D的作法就基本讲完了,我们可以把上面做的几层都拷贝到一个新的MC当中,放在场景中就可以很方便地产生3D效果,而且也可以利用缩放来调整最终效果。
最后,初学者会问我那些当鼠标悬浮在立方体正面时出现的导航文字是怎么讲的。我告诉你很简单,你可以先建好几个说明文字,都作成MC,然后拖到场景中。给它们起好名字,比如guide1。在它上面加入AS——
onClipEvent (load) {

this.swapDepths(300);

_visible = false;

}

onClipEvent (enterFrame) {

this._x = _root._xmouse;

this._y = _root._ymouse;

}
  在一开始将它切到一个更高的层上(300),这样可以保证它是在3D视图的上方。然后设置它的属性是不可见的。接着每一帧都让它跟着鼠标走。最后就是要设置一下那几个被加入MM-a1_typo中的不可见按钮了,在上面加入AS——
on (rollOver) {

_root.guide1._visible = ***e;

}

on (rollOut) {

_root.guide1._visible = false;

}

on (release) {

getURL("http://dreamstudio.nease.net/";;, _blank);

}
  这样当鼠标悬浮在它上面的时候它就发信告诉说根目录下的guide1要可见啦,当鼠标走出范围后又要不可见,最后加上一个链接,这样导航文字便完成了。
如果你要做几个不同的说明文字的话,注意要将他们换到不同的层上,比如guide1换到300,guide2换到400,反正不要让它们起冲突就行了。
文章来源:pconline 作者:horidream
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

无效楼层,该帖已经被删除

0

主题

1

听众

2458

积分

中级设计师

Rank: 5Rank: 5

纳金币
0
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2014-2-22 15:59:16 |只看该作者
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-9-20 21:23 , Processed in 0.422011 second(s), 33 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部