Abel Lee

 
   

as3commons生成DoABC关键部分代码说明

swfassist实在是难学,基本全都要靠猜的,

学习资料少的不能再少了

幸好有as3commons

再加上as3swf就能做一些生成swf的工具了

好了 闲话少扯

开始代码吧:

生成代码的过程,就像我们写代码的顺序一样,

先生成package

abcBuilder = new AbcBuilder();

packageBuilder = abcBuilder.definePackage("");

这就生成了一个根目录下的包,代码就是:package{}

var classBuilder:IClassBuilder = packageBuilder.defineClass("TestClass", "flash.display.Sprite");

这里定义了类的继承,代码:public class TestClass extends flash.display.Sprite

classBuilder.isDynamic = true;

这里定义了类为动态类

classBuilder.defineProperty("testProperty", "String", "doabc");

这里定义了一个公共变量,代码为:public var testProperty:String = "doabc";

var ctorBuilder:ICtorBuilder = classBuilder.defineConstructor();

从这里开始定义构造函数

ctorBuilder.defineArgument("int", true, imgWidth);

ctorBuilder.defineArgument("int", true, imgHeight);

构造函数有两个参数,类型均为int,第二个参数为true 意思是说这个参数是可选的,默认值为imgWidth,imgHeight。


关于Opcode部分的需要说明一些概念性的东西,纯属个人理解,哪里不对的请各位指点一下 先谢过了。

每个类里的变量会被存于一个列表中,每个function也是,而列表中的第一个变量,也就是索引为0的变量为this,其它都是我们自定义的,至此为止,我们自定义了两个变量,那此时列表中就有三个变量

ctorBuilder.addOpcode(Opcode.getlocal_0)

getlocal_0取的就是第一个变量 也就是this

.addOpcode(Opcode.pushscope)

pushscope 其实就是为function添加了一个"{}"

.addOpcode(Opcode.getlocal_0)

.addOpcode(Opcode.getlocal_1)

.addOpcode(Opcode.getlocal_2)

再次把三个变量都取出来

.addOpcode(Opcode.constructsuper, [2])

constructsuper就是super(***, ***),这里表示调用超类的function,参数有两个,分别为变量列表中的后两个,也就是imgWidth, imgHeight

.addOpcode(Opcode.returnvoid);

returnvoid就是return;

var method:IMethodBuilder = classBuilder.defineMethod("testMethod");

定义一个function 函数名为testMethod

method.returnType = "String";

定义函数返回数据类型为String

method.defineArgument("int");

定义一个function的参数为int类型,后面两个参数都使用默认值,意为第一个int型参数是不可选的

method.addOpcode(Opcode.getlocal_0)

  .addOpcode(Opcode.pushscope)

  .addOpcode(Opcode.pushint, [101])

  .addOpcode(Opcode.getlocal_2)

  .addOpcode(Opcode.multiply)

  .addOpcode(Opcode.pushstring, [""])

  .addOpcode(Opcode.add)

  .addOpcode(Opcode.setlocal_2)

  .addOpcode(Opcode.getlocal_2)

  .addOpcode(Opcode.returnvalue);

经过上面的解释 这一步的操作应该很清楚了,

先取出了this

再添加了一个访问域 可以理解为添加了"{}"括号

pushint意为添加一个我们自定义的int型的值为101

然后再取出第二个变量,

因为当前操作是在function内部的,所以是一个新的变量列表,开始我们只定义了一个函数传入的参数 再加上一个默认的this 也就是列表中只存在2个变量,而此时我们getlocal_2 不存在这个变量 就是创建它,就像是我们var _local2:* 一样

然后把上面取出来的进行multiply 也就是乘法操作

pushstring意为我们再次添加一个String类型的值为""

并跟上面取出来的变量进行add 也就是加法操作

然后把这些操作setlocal_2 赋予local_2这个变量

至此为止可以转换为可视代码就是:var _local2:* = 101 * _local2 + "";

最后再把_local2取出来

作为返回的值

也就是return _local2;

OK 就是这样

关于图片部分打包成swf部分,粗略的叙述一下。

我们知道jpg格式图片不包含alpha通道 就会比png的图片要小

而我们游戏中大部分的图片都是png的

那如果我们把png的透明信息取出来,进行压缩,再把png当jpg去存储,就可以达到瘦身的目的

而在打包生成swf的时候,使用DefineBitsJPEG3这个tag,因为它可以包含bitmap的alpha信息,这个alpha信息需要我们自己在加载进要打包的png图片后,自己扫一遍每个像素,取出ARGB中的A,然后写到tag的bitmapDataAlphaData里面去,最后生成一个swf后试着用硕思之类的工具破解出来看一下,就会看到我们的png图片,因为虚拟机已经帮我们把透明信息重新添加到了jpg图片中恢复成了我们最初的png图片。

别的各位再自己研究一下吧。。。不多废话了~


 
 
评论(1)