·您当前的位置:首页 > 技术教程 > AS2与AS3技术 >

[AS3]翻译国外文章AS3中修改mc的注册点常用于相册

时间:2015-08-19 22:37酷播
这是我认为每个人都希望知道如何在ActionScript中实现的:在运行时动态改变一个影片剪辑或精灵的注册点。

这是我认为每个人都希望知道如何在ActionScript中实现的:在运行时动态改变一个影片剪辑或精灵的注册点。我 想知道这个很长时间了,也在网上看到了一些不太满意的解决方案。然而,它们为我开发自己的解决方案提供了有价值的线索,所以,我并不是在这里打击任何人。 你能找到的最主流的解决方案之一是链接库符号到一个类,然后,你获取诸如rotation2、x2、y2、scaleX2、scaleY2等属性,你知道 的。

然而,这不是我想要的……

我不想使用以2结尾的新属性,因为这看 起来不自然。相反,我需要一个函数,我可以调用它改变注册点,然后只需要使用正常的影片剪辑属性:rotation、x、y、scaleX和 scaleY。如果影片剪辑注册点可以在第一个地方永久的移动,后续的转换就可以从新的注册点开始了。我需要一些东西可以直接应用到已有的影片剪辑实例而 无需先链接该影片剪辑到一个自定义的类。

如果不是必须的,我也不想非使用Matrix类来处理。并不是说使用它不好,但是如果有更简单的解决方案,显然我会更喜欢它。

当 我在线查阅时,经常被很多人的断言所打击——影片剪辑的注册点不能移动(从技术上讲,确实如此)!然而,我也看到许多在线的示例,人们已经设法完成了它。 那么,你是如何移动一个注册点的?我必须知道!我看了许多论坛上的许多贴子,沮丧者即使死了都想知道答案。事实上,改变注册点是如此基本的东西,你可能想 ActionScript语言内建了解决方案,但没有。

这是一个技术性问题

像 我刚才说的,你确实不能移动一个注册点。对任何精灵或影片剪辑来说,注册点的位置永远是(0,0)。这是一个技术性问题,证明我们都在问一个错误的问题。 如果你不能移动一个注册点,问如何实现它就没有任何意义了。然而当你不能从技术上移动注册点的时候,你却可以参照它来移动其他所有的东西。这就是答案的关 键!你不能移动注册点,但你可以从效果上移动它!通过移动其他的一切!

这类似于你如何用Flash创作工具改变 注册点。你永远不会移动注册点自身,因为那是不可能的。相反,你相对该点移动所有的图形内容。假设你在舞台上有一个影片剪辑实例,其注册点在左上角,你想 让注册点在中间。你将编辑这个剪辑:进入剪辑内部,选择所有的图形并让他们在注册点上居中。然后回到场景1,你会发现舞台上的对象从先前的位置移动了,因 为你改变了它的内部,你会调整它的x和y位置来补偿刚才产生的变化。或许你已经这样做过。步骤就像这样:

1. 在剪辑内部,编辑模式下,向左向上移动剪辑内每一个图形内容

2. 回到场景,向右向下移动影片剪辑相同的数量

注意你并没有移动注册点本身,但你向左上方移动了影片剪辑的所有显示子对象,并且最后回到场景1,你向右下方移动了影片剪辑进行补偿。

所以如果我们想在程序中动态改变注册点,我们基本上要进行同样的处理,只使用代码。我不再让你有任何悬念。为此我花了一整天的大部分,完成后,我的函数只有11行(如果你不将注释计算在内)!但它起作用了,并且工作很棒!我很高兴与您共享!

噢, 我差点忘了。我也想要一个解决方案,它不管注册点最初设定在哪里,我也做到了!这个函数很容易使用。第一个参数是你要影响的对象,该对象必须是一个显示对 象容器(DisplayObjectContainer),所以它可以是Sprite、MovieClip,甚至Loader实例。第二个和第三个参数就 是你想要的新注册点的x和y值——相对于剪辑图形内容的左上角。而且,就像我所说的,代码工作时忽略注册点现在在哪里。下页是这个函数(未做处理,保留作 者原汁原味):

  1. function setRegPoint(obj:DisplayObjectContainer, newX:Number, newY:Number):void { 
  2.         //get the bounds of the object and the location 
  3.         //of the current registration point in relation 
  4.         //to the upper left corner of the graphical content 
  5.         //note: this is a PSEUDO currentRegX and currentRegY, as the 
  6.         //registration point of a display object is ALWAYS (0, 0): 
  7.         var bounds:Rectangle = obj.getBounds(obj.parent); 
  8.         var currentRegX:Number = obj.x - bounds.left; 
  9.         var currentRegY:Number = obj.y - bounds.top; 
  10.          
  11.         var xOffset:Number = newX - currentRegX; 
  12.         var yOffset:Number = newY - currentRegY; 
  13.         //shift the object to its new location-- 
  14.         //this will put it back in the same position 
  15.         //where it started (that is, VISUALLY anyway): 
  16.         obj.x += xOffset; 
  17.         obj.y += yOffset; 
  18.          
  19.         //shift all the children the same amount, 
  20.         //but in the opposite direction 
  21.         for(var i:int = 0; i < obj.numChildren; i++) { 
  22.                 obj.getChildAt(i).x -xOffset
  23.                 obj.getChildAt(i).y -yOffset
  24.         } 

注释很好的解释了大部分是怎么回事,这是一个更充分的解释:

getBounds() 函数用来获取剪辑的边界框。剪辑的x和y属性给出了当前注册点的位置。暂时让我们只考虑x方向:bounds.left值是图形内容的最左边的位置,剪辑 的x属性给出了注册点的x位置。这两个值都来自父视图(坐标空间),这两个数之间的差异给出了注册点相对图形内容最左边的当前位置,然后从我们要使用的新 x值中扣除该(差)值,存储在变量xOffset中。剩下的部分是将所有的子对象向左移动这个数值,最后再讲剪辑自身向右移动这个数值。在y方向上保持同 样的处理。

在示例文件中,舞台上有一个称为book的影片剪辑实例。初始时特意使book影片剪辑的注册点不在左上角,也不在中心。然后setRegPoint()函数将注册点设定到中心,这仅需要一次简单的函数调用。当book被点击时,其scaleX属性被乘以-1,这是众所周知的进行水平翻转技术。因为函数调用已经设置注册点到中心,缩放使用了新的注册点来进行。book影片剪辑内部还有一对shape,用来演示所有的内容进行了移动。下页是完成任务的辅助代码(联合上面的函数代码):

  1. book.addEventListener(MouseEvent.CLICK, bookClicked); 
  2. function bookClicked(event:MouseEvent):void { 
  3.         book.scaleX *= -1; 
  4. //set the registration point for the book object in the middle instead: 
  5. setRegPoint(book, book.width / 2, book.height / 2); 

下页是在线演示

http://theflashconnection.com/sites/default/files/Jody%20Hall/dynamic_registration_point.fla

注意:附件文件是CS4格式的。它演示了使用这面的函数是如何的容易。舞台上的影片剪辑动态修改了它的注册点。之后的所有变换都将使用新的点替代原来的那个。如果你在使用CS3,不能打开这个文件,但不用做太多,我在上面已经给出了全部的代码,只要复制、粘贴到你自己的文件,应用到你自己的影片剪辑实例。享用!

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器