这是我认为每个人都希望知道如何在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值——相对于剪辑图形内容的左上角。而且,就像我所说的,代码工作时忽略注册点现在在哪里。下页是这个函数(未做处理,保留作者原汁原味):
注释很好的解释了大部分是怎么回事,这是一个更充分的解释:
getBounds()函数用来获取剪辑的边界框。剪辑的x和y属性给出了当前注册点的位置。暂时让我们只考虑x方向:bounds.left值是图形内容的最左边的位置,剪辑的x属性给出了注册点的x位置。这两个值都来自父视图(坐标空间),这两个数之间的差异给出了注册点相对图形内容最左边的当前位置,然后从我们要使用的新x值中扣除该(差)值,存储在变量xOffset中。剩下的部分是将所有的子对象向左移动这个数值,最后再讲剪辑自身向右移动这个数值。在y方向上保持同样的处理。
在示例文件中,舞台上有一个称为 book 的影片剪辑实例。初始时特意使 book 影片剪辑的注册点不在左上角,也不在中心。然后 setRegPoint() 函数将注册点设定到中心,这仅需要一次简单的函数调用。当 book 被点击时,其 scaleX 属性被乘以 -1 ,这是众所周知的进行水平翻转技术。因为函数调用已经设置注册点到中心,缩放使用了新的注册点来进行。 book 影片剪辑内部还有一对 shape ,用来演示所有的内容进行了移动。下页是完成任务的辅助代码(联合上面的函数代码):