论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Flash AS编程教程
Tag:2.0,3.0菜鸟,游戏,,cs,技巧,源码,,文本,文字,函数,音乐,随机,拖拽,asp,access,xml,mc,视频教程

三星弹性导航菜单再探详解

文章类别:Flash AS编程 | 发表日期:2008-10-6 17:35:35


作品欣赏:

  浏览了许多老外的网站,发现最精彩之一的莫过于菜单的制作,由于其交互性强,所以as在这大有用武之地,嗯,前几天忙死了,总算到了周末,把我本来要作为主页菜单的 一组菜单改了改,把它呈给大家,希望对你有帮助:)也希望各高手能多分享些宝贝给 小弟们啦,多多学习,这儿才会更加精彩嘛:)

  其他的不多说了,先把东西拿上来吧,因为是我刚才改的,并且和我原来的设计有些不同,所以难免有错误,高手指正啦!试验后发现与tupling的菜单有些差异吧,加入了链式的运动,然后鼠标吸附的效 果只在一定的范围内起作用。

  嗯,我还是喜欢跟大家说说的我思路,首先要实现链式的运动,其实很简单当一个按钮被按下拖动的时候,其他的按钮与他保持一定的距离,并呈一定的角度,要实现这个也很简单,用循环,怎么用呢,稍微要动点脑筋了,呵呵,人的思维与电脑到底式不一样的,我给按钮们命名了"a0","a1","a2"....通过名字可以联系一相应的数字0,1,2,3……分成两种可能进行讨论!!一名字在中间的可以通过+或-来实现控制其周围的按钮间的联系,由于具体有许多技巧见下面的代码:

stop();
fscommand("allowscale", false); 
/*下面定义了鼠标按下和释放时启动的事件,this.dragging 是用来说明现在该按钮是被按下的,
主要是为了防止你的鼠标控制按钮运动与计算机控制的运动相冲突。
_root.dr是用来说明现在在主场景中有按钮被按下了 */
function doDrag() { 
  this.startDrag(); 
  this.dragging = true; 
  _root.dr = true; 
  this.pres = true; 
  this.gotoAndStop(2); 
} 
function noDrag() { 
  stopDrag(); 
  this.dragging = false; 
  _root.dr = false; 
  this.pres = false; 
  this.gotoAndStop(1); 
} 
//鼠标经过时改换图标 
function showme() { 
  this.gotoAndStop(2); 
} 
//下面是主要控制运动的地方 
function makemove() { 
//分了几种情况,一种是主场景中没有按钮被按下了,这个时候通过记录一个原始的位置,
由随机函数产生随机运动,然后回复到原始的位置 
if (!_root.dr) { 
  if (random(80) == 1) {//时不时让他动一动,就算你不动他:) 
   var s = random(6); 
   random((_root["a"+s].oldx), _root["a"+s].oldy); 
   _root["a"+s]._x = six; 
   _root["a"+s]._y = siy; 
  } 
/*下面的是弹性运动的公式,我现在只简单说说k是用来分割现在位置
与目标点之间距离随着dx的减小vx继续增加,当超过目标点的时候dx变
成负数,这样vx又逐渐减小这样又返回运动,为了不使来回无休止的摆动,加入damp减速
*/ 
  var dx = this.oldx-this._x; 
  var dy = this.oldy-this._y; 
  this.vx += dx*k; 
  this.vy += dy*k; 
  this._x = this._x+this.vx; 
  this._y = this._y+this.vy; 
  this.vx = this.vx*damp; 
  this.vy = this.vy*damp; 
  //这里分出一种情况,如果主场景知道有按钮被按下,但被按的不是现在的按钮
} else if (!this.dragging && _root.dr) {
  //make sure there will not be opposit to formal design 
  mytxt = new String(this._name);
  namenumber = Number(mytxt.charAt(1)); 
  //下面是区分上面我说的数字的两种情况 0,5以外的情况 
  if (namenumber != 0 && namenumber != 5) { 
   var xdis = this._x-_root["a"+(namenumber+1)]._x; 
   var ydis = this._y-_root["a"+(namenumber+1)]._y;
   var ang = Math.atan2(ydis, xdis); 
   //设计一个目标,距离自己为90向临近的按钮靠近!!包括自己前面的和后面的!!!! 
   var tarx = _root["a"+(namenumber+1)]._x+Math.cos(ang)*90; 
   var tary = _root["a"+(namenumber+1)]._y+Math.sin(ang)*90;
   this.vx += (tarx-this._x)*k; 
   this.vy += (tary-this._y)*k; 
   this.vx = this.vx*damp; 
   this.vy = this.vy*damp;
   var xdis = this._x-_root["a"+(namenumber-1)]._x; 
   var ydis = this._y-_root["a"+(namenumber-1)]._y; 
   var ang = Math.atan2(ydis, xdis); 
   var tarx = _root["a"+(namenumber-1)]._x+Math.cos(ang)*90; 
   var tary = _root["a"+(namenumber-1)]._y+Math.sin(ang)*90; 
   this.vx += (tarx-this._x)*k; 
   this.vy += (tary-this._y)*k; 
   this.vx = this.vx*damp; 
   this.vy = this.vy*damp; 
   this._x += this.vx; 
   this._y += this.vy; 
   //making the mc which besides to me follow me! 
  } else if (namenumber == 5) {//5的情况类似了
   var xdis = this._x-_root.a4._x; 
   var ydis = this._y-_root.a4._y; 
   var ang = Math.atan2(ydis, xdis); 
   var tarx = _root.a4._x+Math.cos(ang)*90;
   var tary = _root.a4._y+Math.sin(ang)*90; 
   this.vx += (tarx-this._x)*k;
   this.vy += (tary-this._y)*k; 
   this.vx = this.vx*damp; 
   this.vy = this.vy*damp; 
   var xdis = this._x-_root.a0._x;
   var ydis = this._y-_root.a0._y; 
   var ang = Math.atan2(ydis, xdis); 
   var tarx = _root.a0._x+Math.cos(ang)*90; 
   var tary = _root.a0._y+Math.sin(ang)*90; 
   this.vx += (tarx-this._x)*k; 
   this.vy += (tary-this._y)*k;
   this.vx = this.vx*damp;
   this.vy = this.vy*damp; 
   this._x += this.vx; 
   this._y += this.vy; 
  } 
 } 
 } 
 //下面的代码简单了,我想你看的明白了,我以前的教程中有这类的用法 
 function rando(x, y) { 
  six = Math.random()*30+1+(x-15); 
  siy = Math.random()*30+1+(y-15); 
} 
k = .4;
damp = .7; 
numFeet = 5;
forbid = 0; 
for (i=0; i<=5; i++) { 
  _root.li.attachMovie("b", "a"+i, -i); 
  _root.li["a"+i]._x = _root["a"+i]._x; 
  _root.li["a"+i]._y = _root["a"+i]._y; 
  _root["a"+i].oldx = _root["a"+i]._x;
  _root["a"+i].oldy = _root["a"+i]._y; 
  _root["a"+i].pres = false; 
} 
//------------------------------------ 
for (i=0; i<=5; i++) { 
 _root["a"+i].onRollOver = showme;
 _root["a"+i].onPress = doDrag; 
 _root["a"+i].onRelease = noDrag;
 _root["a"+i].onReleaseOutside = noDrag; 
 _root["a"+i].onEnterFrame = makemove;
 _root["a"+i].follow = 0;
} 
_root.li.onEnterFrame = function() {
 _root.li.clear(); 
 _root.li.lineStyle(1, 0, 50);
 i = 0; 
 while (i<=numFeet) { 
  if (i != 5) { 
   _root.li.moveTo(_root["a"+i]._x, _root["a"+i]._y);
   _root.li.lineTo(_root["a"+(i+1)]._x, _root["a"+(i+1)]._y); 
  } else if (i == 5) {
   _root.li.moveTo(_root.a5._x, _root.a5._y);
   _root.li.lineTo(_root.a0._x, _root.a0._y); 
  } 
  i++; 
 } 
};

  呵呵,还没完,因为我吸附效果不是通过直接距离实现的,偷懒用了一个透明的mc通过hitTest来判断上面的代码你如果仔细看了一定发现 每个按钮下我都 attachMovieClip()就是这样在这上面我加了下面的代码:

onClipEvent (load) { 
  this.oldx = _parent._x; 
this.oldy = _parent._y; } onClipEvent (enterFrame) { this.dx = (_parent._x-this.oldx)*(_parent._x-this.oldx)+(_parent._y-this.oldy)*(_parent._y-this.oldy); if (_root.forbid == 0 || _root.forbidname == _parent._name) { if (_parent.hitTest(_root._xmouse, _root._ymouse, true)) { _root.forbid = 1; _root.forbidname = _parent._name; t = substring(_parent._name, 2, 1); this.ok = 1; if (this.dx>=20000 && _root["a"+t].pres == false) { _parent._x = this.oldx; _parent._y = this.oldy; _root.dr = false; _root["a"+t].dragging = false; _root.forbidname = _parent._name; _root.forbid = 0; _root["a"+t].gotoAndStop(1); } else { _root.dr = true; _root["a"+t].dragging = true; _parent._x = _root._xmouse; _parent._y = _root._ymouse; _root["a"+t]._x = _root._xmouse; _root["a"+t]._y = _root._ymouse; } } else { if (_root["a"+t].pres == false) { if (this.ok) { _parent._x = this.oldx; _parent._y = this.oldy; _root.dr = false; _root["a"+t].dragging = false; this.ok = 0; _root.forbidname = _parent._name; _root.forbid = 0; _root["a"+t].gotoAndStop(1); } } } } }

  看了这么大一堆代码别晕哦,其实我就是想让当鼠标靠近按钮的时候,被吸引了以后就像按下按钮被拖动的时候效果一样跟着鼠标走了,由于与前面联系的变量很多,要解决的逻辑问题也很多,你完全可以按照你的思路去,同样一个效果实现的手段绝对不止一种 。

  忘了说了,就是偷懒没有多写一段代码_creatEmptyMovieClip()我直接在主场景中建立了一个空的名叫li的mc存放画的线条源文件待会再传给大家吧,明白了思路我想不用原文件一样能重新弄出来 。

  首先补充说说弹性的原理吧:)

  看看下面的代码吧:

  你看首先不是弹性运动,但是我想让场景中的mc变速运动

onClipEvent (load) { 
  ax=0.5 
  vx=2 
} 
onClipEvent (enterFrame) { 
  vx += ax; 
  _x += vx; 
} 

  上面的代码很简单,mc会不断加速运动,每次加速的数值由ax的量决定。上面的理解了吧?看过物理上的单摆运动吗?从最位移处到中点处加速度是不断的减小的,与此同时速度不断增大,不会忘记吧 ,呵呵,还应该记得,单摆运动的时候如果有阻力振幅会不断的减小,就象我们的弹性运动!!!!

  对了,现在要做的就是改变上面代码的加速度,就象单摆运动的时候,过平衡位置加速度变成反方向的,加速度也不断减小,怎么把上面的变量联系转化成代码呢??

  很简单,将加速度与距离平衡位置的距离联系,距离越大,加速度越大,于是我们得到:ax=(tx-_x)*k
这样就完全实现了单摆的模拟加速度,呵呵,要是这不明白我可没办法了哦:)
tx是目标位置,也就是平衡位置!!单摆最终会停在平衡位置是因为阻力,我们这里添加一个damp和起来就是下面的东东啦:

onClipEvent (enterFrame) { 
  ax = (tx-_x)*k; 
  vx += ax; 
  _x += vx; 
  vx*=damp 
} 


好了,差不多收工了吧,我的代码
首先tarx-this._x计算与目标点的距离乘k转化与加速度关联
这里由于我偷懒就没出现ax了,直接乘了

this.vx += (tarx-this._x)*k;     
this.vy += (tary-this._y)*k; 
// (tary-this._y)*k=ax相当于this.vy+=ay 
this.vx = this.vx*damp; 
this.vy = this.vy*damp; 
this._x+= this.vy 

  嗯,呵呵,三星的那个菜单说实话,我有几个月没看到过了,大概记得个效果由于没有追求商业网站的那种完美性,所以我没有进一步修改细节第一个问题要将“拖动的时候其余的点都一起动得太厉害”修改可以改几个地方。

  1.改变一个参数

var tarx = _root["a"+(namenumber+1)]._x+Math.cos(ang)*90; 
var tary = _root["a"+(namenumber+1)]._y+Math.sin(ang)*90 

  中的90使它更接近两个按钮间的距离


  还要修改的一个地方就是在

else if (!this.dragging && _root.dr)

条件下添加一个判断,思路是:当整个场景中有按钮被按下的时候,并且现在代码要控制的不是被按下的按钮运动,如果这个按钮没有偏离超过

_root["a"+i].oldx = _root["a"+i]._x; 
_root["a"+i].oldy = _root["a"+i]._y; 

中的oldx,oldy一定距离的时候,执行链式的牵连运动,让他处于最大距离处,方向上保持原来的ang

  2、呵呵,可能你没仔细看我的代码,在有鼠标事件的时候,不执行自主运动!如果你不喜欢的话可以自己改变逻辑了,呵呵,这我不管了


  3、要让震动不回到原来的位置(只在原来的位置左右)这很好办,只要把我上面的弹性教程中的tarx,tary不让他直接等于初始的按钮点的位置而是先将初始点按钮的位置执行我自定义的函数

function rando(x, y) { 
  six = Math.random()*30+1+(x-15); 
  siy = Math.random()*30+1+(y-15); 
} 
random((_root["a"+i].oldx), _root["a"+i].oldy); 
tarx=six
tary=siy 

  这样就可以保证点每次返回不在一个点上,而是在一个范围内要注意的一点是,一次事件只促发一次重新定义oldx,oldy这一点很重要,要不然它会不停的动了:)

var tarx = _root["a"+(namenumber+1)]._x+Math.cos(ang)*90; 
var tary = _root["a"+(namenumber+1)]._y+Math.sin(ang)*90; 
//。。。。。。。。。
var tarx = _root["a"+(namenumber-1)]._x+Math.cos(ang)*90;
var tary = _root["a"+(namenumber-1)]._y+Math.sin(ang)*90 

  这些是控制按钮与自己周围的按钮靠近的代码ang你知道是怎么来的了吧?90是空来控制两临近的按钮距离的由于要影响的是它周围两个按钮,所以要分别计算两次,你可以设想计算完第一个 tarx 以后,运动到一个虚拟的点,然后在计算第二个虚拟点移动到最终按钮要去的位置。

(完)

视频教程列表
文章教程搜索
 
Flash AS推荐教程
Flash AS热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058