skip to main |skip to sidebar

2008-04-06

[AS3]mxmlc 编译器的 BUG

PS:因为最近很忙,好久没有更新 Blog 了。

最近发现了一个 mxmlc 编译器的 BUG,当含有 -(true ? 1 : 0) 的代码编译会出错。

比如以下代码:

package {
import flash.display.Sprite;
public class TestBUG extends Sprite {

public function TestBUG() {
trace('Test');
var foo:Number = -(true ? 1 : 0);
}
}
}

使用 mxmlc 编译时会弹出错误:

Error: null
java.lang.NullPointerException
  at macromedia.asc.semantics.ConstantEvaluator.evaluate(ConstantEvaluator.java:1168)
  at macromedia.asc.parser.UnaryExpressionNode.evaluate(UnaryExpressionNode.java:33)
  at macromedia.asc.semantics.ConstantEvaluator.evaluate(ConstantEvaluator.java:1805)
......

但把 -(true ? 1 : 0)- 号去掉后编译却可以正常进行,真奇怪!

影响的版本:

  • 2.0
  • 2.0.1
  • 3.0.0

2008-03-20

[Flash Player]2008年4月的 Flash Player 的安全策略的变化

在 Adobe 上公布了将在4月份改变 FLash Player 9 的安全策略。(Preparing for the Flash Player 9 April 2008 Security Update

这次的改变纯粹是为了安全,没有增加任何的新特性。但是默认的策略发生了一些改变,有可能会导致现有的一些程序无法正确地工作。

javascript 协议的改变

在以前,loadMovie() 里可以使用 javascript:... 的形式,但新的版本里只在 getURL()navigateToURL()ExternalInterface 里支持 JavaScript。

allowScriptAcces的变化

allowScriptAccess 是指定从 swf 访问 HTML 里的 Script 的方式的属性。以前的 Flash player 对于版本7以下的 swf 的 allowScriptAccess 属性的默认值为 always,版本8以上的默认值为 sameDomain

但新的版本对所有的版本的 swf 的默认值都将变为 sameDomain。版本7以下的 swf 必须明确地指定 allowScriptAccess = always

传送 HTTP Header 时的变化

使用 XML.addRequestHeader()LoadVars.addRequestHeader()URLRequest.requestHeaders 可以添加 HTTP 请求的 Header。在新的版本里向非同域名的服务器发送请求并添加 Header 时先必须要取得服务器的的许可。

具体的是需要在服务器上的 crossdomain.xml 添加添加以下项目:

<allow-http-request-headers-from domain="www.example.com" headers="HeaderName"/>

Socket 连接服务器时必须使用安全策略文件

XMLSocket 与 Socket 连接服务器的安全策略将会更严。新的版本在连接同域名时也需要使用安全策略文件,并且请求安全策略文件的端口固定为843。

2008-03-16

[AS3] ActionScript 3 的代码规范

Adobe 推出了AS3 的代码的书写规范。详情参见:Coding Conventions

它推出的代码规范并不意味着开发者必须严格地遵行,仅仅是建议罢了(开发 Flex SDK 的除外)

以下为我推荐的一些内容:

数组的声明格式

var a:Array /* of String */ = [];
var a:Array /* of int */ = [ 1, 2, 3 ];
function f(a:Array /* of Number */):Array /* of Object */  {
  //...
}

不要写成

var a:Array = [];
var a:Array = new Array();
var a:Array = new Array(1, 2, 3);
function f(a:Array):Array {
  //...
|

Object 的声明格式

var o:Object = {};
var o:Object = { a: 1, b: 2, c: 3 };

不要写成

var o:Object = new Object();
var o:Object = new Object();
o.a = 1;
o.b = 2;
o.c = 3

比较

if (n == 3) // "如果 n 是 3"

不要写成

if (3 == n) // "如果 3 是 n"

2008-02-17

永远的 SoundComplete 事件

这已经不是什么新闻了,只是关注度好像不是很高,但我认为很有必要说几句。

自从 Flash Player 升级为 9.0.115.0 后 Sound.soundComplete 事件就消失了!没有任何征兆,一夜之间就从这个世界消失得无影无踪。

不要小看这个事件,没有它音频控制几乎不可能。比如以前一直使用 Sound.soundComplete 事件来实现音频的连续回放等各种特效,现在一切变为了南柯一梦。特别是 popforge 项目,一个 使用 AS3 来创作与修改音频的先端开发的新兴项目成为了最大的受害者之一,它有可能因此而从此玉损了!

大家署名来抗议吧The silent death of onSoundComplete event - a petition

2008-02-07

祝大家新春快乐

今天是初一,祝大家鼠年快快乐乐。也祝我的网站日月兴隆。

[AS3]让构造函数不执行 super()

在构造函数里一般 super() 必须执行。如果不写,在编译时会在构造函数的最上面添加 super()。但有时又需要不执行。比如以下代码:

class AbstractClass {
  public function AbstractClass() {
    throw new Error("Abstract class");
  }
}
class SubClass extends AbstractClass {
  public function SubClass() {
    trace("sub class");
  }
}

SubClass 对象会因为超类弹出错误而创建失败。但如果让 super() 不执行就可以了。

class SubClass extends AbstractClass {
  public function SubClass() {
    if(0) { //这里必须为返回 false 的表达式。但不能为 "false"(false 会被编译器忽视)。
      super();
    }
    trace("sub class");
  }
}

测试代码:

package {
  import flash.display.*;
  public class Test extends Sprite {
    public function Test() {
      new AbstractClass(); // -> Super CLass
      new SubClass1(); // -> Super CLass / Sub CLass1 start / Sub CLass1 end
      new SubClass2(); // -> Sub CLass2 start / Sub CLass2 end
    }
  }
}
class AbstractClass {
  public function AbstractClass() {
    trace("Super CLass");
  }
}
class SubClass1 {
  public function AbstractClass() {
    trace("Sub CLass1 start");
    super();
    trace("Sub CLass1 end");
  }
}
class SubClass2 {
  public function AbstractClass() {
    trace("Sub CLass2 start");
    if(0) {
      super();
    }
    trace("Sub CLass2 end");
  }
}

2008-02-03

[Flex]把 Sprite 添加到 Canvas 里的方

Flex FrameworkCanvas 是无法添加 Sprite 等非 UI 组件的 DisplayObject的。但有变通的办法。

1.使用 Adaptor 模式

Sprite 添加到 UIComponent,再把 UIComponent 添加到 Canvas

代码:

var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xFFCC00);
mySprite.graphics.drawCircle( 40, 40, 40 );
var UIRef:UIComponent = new UIComponent();
myUI.addChild(UIRef);
UIRef.addChild(mySprite);

2.使用 rawChildren

使用 Canvas.rawChildren

代码:

var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xFFCC00);
mySprite.graphics.drawCircle( 40, 40, 40 );
myUI.rawChildren.addChild(mySprite);