AS3 Static Function Variable

30 2011 In: ActionScript3, Flash

Flash ActionScript 3.0 語法中是沒有支援靜態函式變數的
不過卻可以用 prototype 物件達到類似的功能

var fun:Function = function ():void{
 // init. function static member
 var proto:Object = arguments.callee.prototype;
 proto.name ||= "Static Function Variable";
 proto.count ||= 0;
 
 trace(proto.name, proto.count++);
}
 
fun(); // Static Function Variable 0
fun(); // Static Function Variable 1
fun(); // Static Function Variable 2

不過需要注意的是不能用於類別的函式成員,只能用於匿名函式
一旦宣告為類別的函式成員,prototype 物件將會變成 null 且無法再寫入了

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Adobe Community Help

20 2011 In: Adobe

Adobe 对国内社区建设一直非常重视,在继续给力推进中文本地化的 Adobe Developer Connection (ADC) 的同时, Adobe 社区帮助计划也开展起来。

 
本人也非常荣幸成为 Adobe Community Help 中国首批社区帮助版主,做出自己的贡献。

 

谁需要社区帮助?

如何在最短的时间查找到精准、有效的技术内容?如果您符合以下描述的情形之一,我们强烈建议您立刻尝试使用社区帮助功能。

  • 查找Adobe官方的最新资讯、技术资料、Demo、Sample code;
  • 查找国内、外技术专家博客、技术文章、Demo、Sample code;
  • 支持线下浏览、查阅社区帮助中的内容;
  • 希望给Adobe的产品提出您的宝贵建议,让Adobe 产品加速您的工作进程;
  • 希望和Adobe技术专家或国内外的技术专家交流,您可以对每篇文章发表读后感或者评论;
  • 希望分享自己的实践经验、技术心得,并通过Adobe公司的力量分享给全球广大的开发者、设计师。

 

如何使用?

  1. 首先需要花费您一分钟的时间,在Adobe公司的网站注册一个用户名。如果您已经有Adobe用户名,请直接进入第二步。
  2. 下载、安装社区帮助。详细步骤请参考这里:http://www.adobe.com/support/chc/index.html

社区帮助是由管理员和版主共同管理和维护的。注册过adobe.com并已经登陆的成员可以通过发表评论或为内容评分从而为社区作出贡献。未登录的游客可以随意浏览和搜索,但是不能和内容进行互动。

 

如何参与?

提交你的评论:只要你有热情、想法,请分享你的知识吧!因为你的评论,不论是原创的或是回应其他人的评论都能让社区从中受益。你可以回答其他用户的提问,指出文章的小缺点或建议来弥补缺陷,或发表相关的代码或技巧来改进文章。

推荐更多国内外技术资源加入社区帮助里:每天都不断有最新的技术内容出现,我们需要你的帮助来保持搜索索引的更新。当你发现质量高的页面或站点,请推荐给相关的Adobe社区产品管理员。你也可以为现有的页面以评论的形式添加新内容,从而不断提高社区帮助的价值和实用性。

发布原创技术内容:我们欢迎您使用社区发布工具(Community Publishing AIR app)来方便、快捷的发表原创技术内容到社区帮忙中。

 

如何与社区帮助一起成长?

活跃评论者:例如:发表很多实用的经验分享,发现并指出有错的技术内容。

顶尖技术博主:每月发表原创技术文章,或翻译有价值的技术文章。

社区帮助版主:成为 Adobe官方或非官方的产品专家,负责管理评论,促进交流并分享知识(设计者,作者,培训者,开发者等)。

社区帮助管理员:协助和管理版主的工作,保持和Adobe的沟通与合作。

Adobe社区专家:提名成为Adobe全球社区专家候选人,成为Adobe中国社区的技术领袖。

 

如何获取积分?

参与Adobe社区帮助计划即可参加社区积分活动,有机会获取Adobe精美礼品。具体积分值如下:

  • 社区帮助评论和发表文章(5~200):如果您的评论或者原创文章被接受,根据文章或评论的技术含量的高、低,获得不同的奖励分。
  • 本社区的积分基于用户的E-Mail进行累积,因此,请广大用户使用固定的有效E-Mail账户参加我们的积分活动,以防您的积分被分散。
  • 该积分为Adobe中国技术社区成员参与Adobe社区专家评选活动的指标之一。您的积分都将保存在我们的数据库中。
  • 如果您有任何问题,请发送邮件到这里:CommunityHelp-cn@adobe.com
分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

進階版舞台縮放比例偵測器

15 2011 In: ActionScript3, Flash

承上一篇 利用文字欄位偵測舞台縮放比例
想辦法再加強精確度,分別算出垂直與水平縮放比例
這樣就能夠用於所有的 Stage 縮放模式了,包含 Show All, Exact Fit, No Border
並且單獨寫成一個類別,縮放比例變化時用事件方式通知,避免無謂的更新造成效能負擔
使用時必須要將實體放在舞台下,註冊 Change 事件,便能開始偵測縮放比例變化了

StageScaleDetectorAdv Class:

package com.ticore.utils {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.text.TextField;
 
 /**
  * Stage scale detector class, able to detect concatenated scale change in show all or exact fit mode.
  * @author Ticore Shih - http://ticore.blogspot.com/
  */
 [Event(name="change", type="flash.events.Event")]
 public class StageScaleDetectorAdv extends Sprite {
 
  public function StageScaleDetectorAdv() {
   visible = false;
 
   // txtH.textWidth 僅反映出 stageScaleX 變化
   txtH.text = "-";
   txtH.rotation = 90;
   txtH.scaleX = txtH.scaleY = precision;
   stdTextWidth = txtH.textWidth;
   addChild(txtH);
 
   // txtV.width 僅反映出 stageScaleY 對 stageScaleX 比例變化
   txtV.text = "-";
   txtV.autoSize = "left";
   txtV.scaleX = txtV.scaleY = 1 / precision;
   stdTextRatio = (txtV.width - 4 / precision) / (txtV.height - 4 / precision);
   addChild(txtV);
 
   addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  }
 
  protected function onEnterFrameHandler(e:Event = null):void {
   validateNow();
  }
 
  /**
   * force update stageScaleX, stageScaleY immediately
   */
  public function validateNow():void{
   var textRatio:Number = (txtV.width - 4 / precision) / (txtV.height - 4 / precision);
 
   _stageScaleX_ = stdTextWidth / txtH.textWidth;
   _stageScaleY_ = _stageScaleX_ * textRatio / stdTextRatio;
 
   if (Math.abs(_stageScaleX_ - _preEmitstageScaleX_) + Math.abs(_stageScaleY_ - _preEmitstageScaleY_) > threshold) {
    _preEmitstageScaleX_ = _stageScaleX_;
    _preEmitstageScaleY_ = _stageScaleY_;
    dispatchEvent(new Event(Event.CHANGE));
   }
  }
 
 
  protected var txtH:TextField = new TextField();
  protected var txtV:TextField = new TextField();
 
  // 標準文字寬度
  protected var stdTextWidth:Number;
 
  // 標準文字寬高比
  protected var stdTextRatio:Number;
 
  // 放大 20 倍情況下 precision 保險最小值為 0.005
  protected var precision:Number = 0.005;
 
  // Scale 變化超過閾值才發出 Change 事件
  protected var threshold:Number = 0.001;
 
  protected var _stageScaleX_:Number = 0;
  protected var _stageScaleY_:Number = 0;
  protected var _preEmitstageScaleX_:Number = 0;
  protected var _preEmitstageScaleY_:Number = 0;
 
 
  /**
   * concatenated scaleX to final stage output
   */
  public function get stageScaleX():Number{
   return _stageScaleX_;
  }
 
  /**
   * concatenated scaleY to final stage output
   */
  public function get stageScaleY():Number{
   return _stageScaleY_;
  }
 }
}

測試程式:

package {
 import com.ticore.utils.StageScaleDetector;
 import com.ticore.utils.StageScaleDetectorAdv;
 
 import flash.display.Graphics;
 import flash.display.Sprite;
 import flash.display.StageScaleMode;
 import flash.events.Event;
 
 [SWF(frameRate="24")]
 public class Main extends Sprite {
 
  public var detector:StageScaleDetectorAdv = new StageScaleDetectorAdv();
  public var sp:Sprite = new Sprite();
 
  public function Main() {
   // stage.scaleMode = StageScaleMode.SHOW_ALL;
   stage.scaleMode = StageScaleMode.EXACT_FIT;
 
   addChild(detector);
 
   initBackground();
   initSprite();
 
   detector.addEventListener(Event.CHANGE, onScaleChangeHandler);
  }
 
  public function initBackground():void {
   var g:Graphics = this.graphics;
   g.lineStyle(10, 0x808080);
   g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
  }
 
  public function initSprite():void {
   var g:Graphics = sp.graphics;
   g.lineStyle(3, 0);
   g.beginFill(0, 0.5);
   g.drawRect(0, 0, 100, 100);
   g.endFill();
   addChild(sp);
  }
 
  public function onScaleChangeHandler(e:Event):void{
   var detector:StageScaleDetectorAdv = e.target as StageScaleDetectorAdv;
   sp.scaleX = 1 / detector.stageScaleX;
   sp.scaleY = 1 / detector.stageScaleY;
   sp.x = (stage.stageWidth - sp.width) / 2;
   sp.y = (stage.stageHeight - sp.height) / 2;
  }
 }
}
分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

利用文字欄位偵測舞台縮放比例

13 2011 In: ActionScript3, Flash

噗浪上有朋友說 TextField 設定 autoSize 之後放在 MovieClip 內
隨著 MoiveClip scaleX, scaleY 改變
居然會影響到 TextField 的 width 與 textWidth
測試程式如下:

package {
 import flash.display.Sprite;
 import flash.text.TextField;
 
 public class TextFieldSize extends Sprite {
  public function TextFieldSize() {
   var txt:TextField = new TextField();
   txt.text = "0";
   txt.autoSize = "left";
 
   var sp:Sprite = new Sprite();
   sp.addChild(txt);
 
   trace(txt.width, txt.textWidth); // 64 60
 
   sp.scaleX = 2;
   trace(txt.width, txt.textWidth); // 34 30
 
   sp.scaleX = 3;
   trace(txt.width, txt.textWidth); // 24 20
  }
 }
}

其實這問題很容易解決,只要嵌入字體或者是設定一個 Matrix3D 到 TextField 上就好了

我在測試時發現它的數值變化很有趣,是跟外層容器 Scale 大致成反比的
另外,有開發過滿版 Flash 應該都知道,必須要將 stage.scaleMode 設為 noScale 才能偵測到實際舞台尺寸
於是就想是否能利用 TextField 這個特性,來偵測縮放模式為 ShowAll 的舞臺尺寸呢?

反覆測試幾次之後,發現是可行的
只是作法略有變化,另外算出來的數值略有誤差,不過是可以忍受的
以下便是利用 TextField 縮放特性,算出舞台縮放比,讓一個正方形 Sprite 不被縮放並且置中

package {
 import flash.display.Graphics;
 import flash.display.Sprite;
 import flash.display.StageScaleMode;
 import flash.events.Event;
 import flash.text.TextField;
 
 /**
  * Detect scale of stage with show all mode by TextField.textWidth
  * @author Ticore Shih - http://ticore.blogspot.com/
  */
 public class StageScaleDetector extends Sprite {
 
  public var txt:TextField = new TextField();
  public var stdTextWidth:Number;
 
  public var sp:Sprite = new Sprite();
 
  public function StageScaleDetector() {
   stage.scaleMode = StageScaleMode.SHOW_ALL;
 
   initDetector();
   initBackground();
   initSprite();
 
   addEventListener(Event.ENTER_FRAME, onStageResize);
  }
 
  public function initDetector():void {
   txt.text = "-";
   txt.rotation = 90;
   addChild(txt);
   stdTextWidth = txt.textWidth;
  }
 
  public function initBackground():void {
   var g:Graphics = this.graphics;
   g.lineStyle(10, 0x808080);
   g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
  }
 
  public function initSprite():void {
   var g:Graphics = sp.graphics;
   g.lineStyle(3, 0);
   g.beginFill(0, 0.5);
   g.drawRect(0, 0, 100, 100);
   g.endFill();
   addChild(sp);
  }
 
  public function onStageResize(e:Event):void {
   var stageScale:Number = stdTextWidth / txt.textWidth;
   sp.scaleX = sp.scaleY = 1 / stageScale;
   sp.x = (stage.stageWidth - sp.width) / 2;
   sp.y = (stage.stageHeight - sp.height) / 2;
  }
 }
}

畫面截圖

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

最近開始需要用到物理引擎
網路上有好幾套 Flash 物理引擎
比較多人用、資料比較豐富的似乎是從 C 移植過來的 Box2D
同樣是移植過來的版本居然還有分兩種
Box2D Flash AS3Box2D Alchemy WCK
Box2D Flash AS3 整個是純 AS3 寫成的
Box2D Alchemy WCK 是直接拿 Box2D C 程式,透過 Alchemy 編譯為 Flash SWC
然後加上其它 AS3 Wrapper Class 來的
兩種版本大略使用過之後發現 Box2D Alchemy WCK 有許多優點

  • 執行效能較佳
  • 與 Box2D 原版 API 接近,假如原版更新了,也可以自己架設 Alchemy 更新到 Flash 版
  • 提供了很多輔助類別可以使用,譬如能夠作到各種形狀重力場等
  • 與 Flash IDE 完美整合在一起,甚至只要用拖拉的方式就可以建立好需要的物理場景

唯一的缺點只有檔案較大,沒有提供單一打包好的 SWC,導致編譯速度太慢問題
用了之後一定會占掉 300kb 左右大小,這或許也不算很大
不過編譯速度太慢真的很傷腦筋
所以本篇文章的目的就是要把整個 Project 打包為單一 SWC
如此一來,編譯速度就會大幅提升,也能很容易的拿到 Flash Builder 內使用

當我實際開始著手這樣工作之後,才發現遇到很多問題
也懶得一一解釋原因了
主要的步驟如下:

  1. 開一個空白的 Flex Library Project – Box2DAlchemyLib
  2. 將 Box2D.swc 加入到 lib path
  3. 將所有的 AS3 Class 放置到 Flex Lib src 下,修正未宣告型別、存取修飾子等語法問題
  4. e.g. /src/wck/WavesEffect.as -> /src/extra/WavesEffect.as

  5. 於空的 Package 下放置空白 Dummy Class
  6. e.g. /src/Box2DAS/Cls.as

以上就能產生出可以同時給 Flash/Flex 用的 SWC 類別庫了
假如想要把 Demo.fla 套用新的 SWC 類別庫
修改步驟如下:

  1. 修改 fla AS3 Setting,path 加入 Box2DAlchemyLib.swc,並取消發布 SWC
  2. 修改 MovieClip 設定
  3. GravityCapsule Symbol
    Class: GravityCapsule
    Base Class: gravity.GravityCapsule

    GravityLinear Symbol
    Class: GravityLinear
    Base Class: gravity.GravityLinear

    GravityRadial Symbol
    Class: GravityRadial
    Base Class: gravity.GravityRadial

    GravitySine Symbol
    Class: GravitySine
    Base Class: gravity.GravitySine

修改完之後,編譯時間從原本 30 秒大幅縮短到 9 秒呢
這是我修改完之後的 Box2D WCK Library Project,從 2011-06-15 那版改的

分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter