前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SWF运行时判断两个DisplayObject是否同个类型,属于flash professional库中的同一个元件

SWF运行时判断两个DisplayObject是否同个类型,属于flash professional库中的同一个元件

作者头像
用户1258909
发布2018-07-05 10:52:53
5650
发布2018-07-05 10:52:53
举报
文章被收录于专栏:拂晓风起拂晓风起

一般我们判断两个实例对象是否同样的类型,可以用typeof得到对象类型,然后用==号比较。

typeof适用于原生类型。

而对于自定义类型,虽然typeof得到的都是Object,但还有更强的招数:getQualifiedClassName

利用这个原生函数可以获取到两个实例的真实类型。

然而,对于Flash professional制作出来的swf,运行时要知道其中两个MovieClip是否来自库里边的同一个元件,上述方法都无能为力了。

本文就是探讨这个问题。

1、首先,想到的是,如果两个实例相同类型,那么在内存中应该有类似的结构。不过flash并没有直接获取内存的接口;

2、替代直接获取内存的方法,可以找到ByteArray。利用ByteArray.writeObject可以把对象以AMF方式序列化。

3、但是,直接把两个MovieClip序列化,得到的ByteArray肯定不一样,因为毕竟有动态的变量值,例如x/y等。

4、那么如果不直接对MovieClip本身writeObject,而是对它的子元件writeObject呢?一度尝试过这种方法,但最后测试的时候发现这个并没有普遍适用性,因为子元件也可能有动态的东西,例如name。运行时会被赋予各种instanceXXX名称。

5、先抛开MovieClip,那么对最基础的Shape怎么对比相同呢?Shape无非就是画图,那么最好不过就是对比画图数据是否一致了。

     graphics.readGraphicsData()能获取到Vector,而且Vector里边的内容都是静态的。

     再结合ByteArray.writeObject就可以轻松比较到两个Shape是否一致了。

6、利用上边Shape的思维,对MovieClip也做一样的处理。每帧获取graphics数据,writeObject到ByteArray中。最后做比较。

详细代码:

代码语言:javascript
复制
              /**
               * 判断是否来自Flash Professional库里的同一个元件
               * @param a
               * @param b
               */
               private function equals(a:DisplayObject, b:DisplayObject):Boolean
              {
                      if((a is MovieClip && b is MovieClip) || (a is Shape && b is Shape))
                     {
                            var byteArrayA:ByteArray = new ByteArray();
                            var byteArrayB:ByteArray = new ByteArray();
                            if(a is MovieClip)
                           {
                                   var mcA:MovieClip = a as MovieClip;
                                   var mcB:MovieClip = b as MovieClip;
                                   var isPlayingA:Boolean = mcA.isPlaying;
                                   var isPlayingB:Boolean = mcB.isPlaying;
                                   var currentFrameA:int = mcA.currentFrame;
                                   var currentFrameB:int = mcB.currentFrame;
                                  
                                   for (var k:int = 1; k <= mcA.totalFrames; k++)
                                  {
                                         mcA.gotoAndStop(k);
                                         byteArrayA.writeObject(mcA.graphics.readGraphicsData());
                                  }
                                   for (var i :int = 1; i <= mcB.totalFrames; i++)
                                  {
                                         mcB.gotoAndStop(i);
                                         byteArrayB.writeObject(mcB.graphics.readGraphicsData());
                                  }
                                  
                                   if(isPlayingA)
                                         mcA.gotoAndPlay(currentFrameA);
                                   else
                                         mcA.gotoAndStop(currentFrameA);
                                   if(isPlayingB)
                                         mcB.gotoAndPlay(currentFrameB);
                                   else
                                         mcB.gotoAndStop(currentFrameB);
                           }
                            else if(a is Shape)
                           {
                                   var shapeA:Shape = a as Shape;
                                   var shapeB:Shape = b as Shape;
                                  byteArrayA.writeObject(shapeA.graphics.readGraphicsData());
                                  byteArrayB.writeObject(shapeB.graphics.readGraphicsData());
                           }
                           
                            if(byteArrayA.length != byteArrayB.length)
                           {
                                   return false;
                           }
                            else
                           {
                                  byteArrayA.position = byteArrayB.position = 0;
                                   while(byteArrayA.bytesAvailable)
                                  {
                                          if(byteArrayA.readByte() != byteArrayB.readByte())
                                                 return false;
                                  }
                                   return true;
                           }
                     }
                      return false;
              }

验证测试:

情况1:

一个MovieClip,在舞台上放置两份。

Image(30)
Image(30)

运行时只有1份MovieClip数据,1份Shape数据

Image(31)
Image(31)

算法有效!

情况2:

基于情况1,让副本元件稍稍不同。

运行时检测得到2份Shape数据,2份MovieClip数据。

Image(33)
Image(33)

算法有效!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-07-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档