Adobe Air & Adobe Flex & ActionScript & Mobile Dev & HTML5 & RIA & User Experience
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 且無法再寫入了
Adobe 对国内社区建设一直非常重视,在继续给力推进中文本地化的 Adobe Developer Connection (ADC) 的同时, Adobe 社区帮助计划也开展起来。
本人也非常荣幸成为 Adobe Community Help 中国首批社区帮助版主,做出自己的贡献。
如何在最短的时间查找到精准、有效的技术内容?如果您符合以下描述的情形之一,我们强烈建议您立刻尝试使用社区帮助功能。
社区帮助是由管理员和版主共同管理和维护的。注册过adobe.com并已经登陆的成员可以通过发表评论或为内容评分从而为社区作出贡献。未登录的游客可以随意浏览和搜索,但是不能和内容进行互动。
提交你的评论:只要你有热情、想法,请分享你的知识吧!因为你的评论,不论是原创的或是回应其他人的评论都能让社区从中受益。你可以回答其他用户的提问,指出文章的小缺点或建议来弥补缺陷,或发表相关的代码或技巧来改进文章。
推荐更多国内外技术资源加入社区帮助里:每天都不断有最新的技术内容出现,我们需要你的帮助来保持搜索索引的更新。当你发现质量高的页面或站点,请推荐给相关的Adobe社区产品管理员。你也可以为现有的页面以评论的形式添加新内容,从而不断提高社区帮助的价值和实用性。
发布原创技术内容:我们欢迎您使用社区发布工具(Community Publishing AIR app)来方便、快捷的发表原创技术内容到社区帮忙中。
活跃评论者:例如:发表很多实用的经验分享,发现并指出有错的技术内容。
顶尖技术博主:每月发表原创技术文章,或翻译有价值的技术文章。
社区帮助版主:成为 Adobe官方或非官方的产品专家,负责管理评论,促进交流并分享知识(设计者,作者,培训者,开发者等)。
社区帮助管理员:协助和管理版主的工作,保持和Adobe的沟通与合作。
Adobe社区专家:提名成为Adobe全球社区专家候选人,成为Adobe中国社区的技术领袖。
参与Adobe社区帮助计划即可参加社区积分活动,有机会获取Adobe精美礼品。具体积分值如下:
承上一篇 利用文字欄位偵測舞台縮放比例
想辦法再加強精確度,分別算出垂直與水平縮放比例
這樣就能夠用於所有的 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; } } }
噗浪上有朋友說 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; } } }
畫面截圖
最近開始需要用到物理引擎
網路上有好幾套 Flash 物理引擎
比較多人用、資料比較豐富的似乎是從 C 移植過來的 Box2D
同樣是移植過來的版本居然還有分兩種
Box2D Flash AS3 與 Box2D Alchemy WCK
Box2D Flash AS3 整個是純 AS3 寫成的
Box2D Alchemy WCK 是直接拿 Box2D C 程式,透過 Alchemy 編譯為 Flash SWC
然後加上其它 AS3 Wrapper Class 來的
兩種版本大略使用過之後發現 Box2D Alchemy WCK 有許多優點
唯一的缺點只有檔案較大,沒有提供單一打包好的 SWC,導致編譯速度太慢問題
用了之後一定會占掉 300kb 左右大小,這或許也不算很大
不過編譯速度太慢真的很傷腦筋
所以本篇文章的目的就是要把整個 Project 打包為單一 SWC
如此一來,編譯速度就會大幅提升,也能很容易的拿到 Flash Builder 內使用
當我實際開始著手這樣工作之後,才發現遇到很多問題
也懶得一一解釋原因了
主要的步驟如下:
e.g. /src/wck/WavesEffect.as -> /src/extra/WavesEffect.as
e.g. /src/Box2DAS/Cls.as
以上就能產生出可以同時給 Flash/Flex 用的 SWC 類別庫了
假如想要把 Demo.fla 套用新的 SWC 類別庫
修改步驟如下:
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 那版改的