一般我们判断两个实例对象是否同样的类型,可以用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中。最后做比较。

详细代码:

              /**
* 判断是否来自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,在舞台上放置两份。

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

算法有效!

情况2:

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

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

算法有效!

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

  1. [c++][语言语法]函数模板和模板函数 及参数类型的运行时判断

    参考:http://blog.csdn.net/beyondhaven/article/details/4204345 参考:http://blog.csdn.net/joeblackzqq/arti ...

  2. 使用Method swizzling (也就是运行时交换两个方法的imp ,实现重写方法)

    贴上资源.很简单 https://gist.github.com/rudyjahchan/2191796 http://itony.me/592.html http://stackoverflow.c ...

  3. iOS 运行时使用(交换两个方法)

    举例 在创建了如下代码 NSString *str=nil; NSURL *url =[NSURL URLWithString:str]; NSLog(@"%@",url); 但是 ...

  4. Objective-C Runtime 运行时之一:类与对象

    Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...

  5. Objective-O Runtime 运行时初体验

    Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...

  6. Android 6.0的运行时权限

    原文  http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/ 主题 安卓开发   Andr ...

  7. RTTI (Run-Time Type Identification,通过运行时类型识别) 转

    参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.   RTTI提供了以下两个 ...

  8. 聊一聊 Android 6.0 的运行时权限

    权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权 ...

  9. 聊一聊Android 6.0的运行时权限

    Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发 ...

随机推荐

  1. ThreadLocal 与 Request 和 Session 之关联

    ThreadLocal<T> 类行是 .NET Framework 4.0 才开始支持的类型,MSDN 的解释只有简单的一句话:提供数据的线程本地存储,其提供的实例代码也不太好,有点为了演 ...

  2. 帕累托分布(Pareto distributions)、马太效应

    什么是帕累托分布 帕累托分布是以意大利经济学家维弗雷多·帕雷托命名的. 是从大量真实世界的现象中发现的幂次定律分布.这个分布在经济学以外,也被称为布拉德福分布. 帕累托因对意大利20%的人口拥有80% ...

  3. Python 的 Flask 框架安装应用

    Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱採用 Werkzeug ,模板引擎则使用 Jinja2 ,使用 BSD 授权. Flask也被称为 " ...

  4. verilog语法实例学习(7)

    常用的时序电路介绍 组合电路:这类电路的输出信号值仅却决于输入端信号值. 时序电路:时序电路的输出值不仅取决于当前的输入值,还取决于电路的历史状态,所以时序逻辑电路中包含保存逻辑信号值的存储元件,存储 ...

  5. 如何查看Isilon的节点的CPU的信息?

    使用Isilon自带的命令 isi_hw_status 使用如下的命令 dmidecode --type processor 笔者只是想了解一下F800的CPU有多少个core.上面的命令都可以获得这 ...

  6. [PowerShell Utils] Automatically Change DNS and then Join Domain

    I would like to start a series of blog posts sharing PowerShell scripts to speed up our solution ope ...

  7. 初识C#程序结构

    一.编写第一个C#程序.注释:   1.编写程序   static void Main(string[] args)//在Mian方法下编写代码输出数据         {             C ...

  8. 第一个手写Win32窗口程序

    第一个手写Win32窗口程序 一 Windows编程基础 1 Win32应用程序的基本类型 1.1 控制台程序 不需要完善的Windows窗口,可以使用DOS窗口 的方式显示. 1.2 Win32窗口 ...

  9. Centos curl ssl 替换 NSS 为 OpenSSL

    参考:https://www.latoooo.com/xia_zhe_teng/368.htm 我的系统版本是 Centos 7 64位.为了方便,先安装常用的开发环境. yum groupinsta ...

  10. protobuf-c的学习总结

    1.前言 项目中用到protobuf-c进行数据序列化,好处在于后期程序扩展性非常好,只需要改动proto的定义就可以保持兼容,非常的灵活方便.关于protobuf-c的详细介绍可以参考google官 ...