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

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

Flash 影格預置 Video 抗鋸齒功能

1 2011 In: ActionScript3, Adobe, Flash

之前同事問到嵌入的 Video 放在舞台上,旋轉之後會出現鋸齒的問題
AS3 的 Video 物件有提供 smoothing 屬性
打開就會有抗鋸齒效果了
可是 Flash IDE 介面上對於預先放在時間軸的 Video 物件卻沒有提供這個選項
最簡單的解決方式就是替 Video 實體命名
然後影格上直接用 AS3 對該實體設定 smoothing = true 了

假如很多地方都要用到怎麼辦,那只好一個一個設了
於是想能不能用程式的方法,一次解決 Document 下所有的 Video?
後來發現有事件可以用
只要對 stage 註冊 added to stage 事件
就可欄截到所有加入舞台的物件…
以下程式加到影格 1 便能讓所有舞台上的 Video 都自動打開 smoothing 了
影格 1 下的 Video 除外,由於時間差的關係,來不及攔截到

import flash.events.Event;
import flash.media.Video;
 
stage.addEventListener(Event.ADDED_TO_STAGE,
 function(e:Event):void{
  if (e.target is Video) e.target.smoothing = true;
 }, true);
分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

Android设备的移动编程指南

30 2011 In: Flash/Flex Mobile Dev, Mobile Dev

使用移动设备正在快速成为浏览媒体内容的流行方式。 这一快速增长趋势使得提供相应的编码指南非常必要,以便确保内容能够在影响范围和播放性能方面发挥最大效果。 在设备上只安装一个具有多速率内容的简
单视频播放器SWF,不足以获得平滑的播放体验。 例如,必须根据具体的情形进行相应的配置,例如不同的设备能力、姿势和手势互动、屏幕方向以及网络连接速度等。

下面是Adobe提供的Android设备的移动编程指南,描述了如何为移动设备的最优播放编写实时或视频点播 (VOD) 文件所需的技巧、最佳方法和设置,是白皮书Adobe Flash Platform的视频编程手册和配置文件指南的一个附录。

目录
1:前言
2:假设
2:移动Flash的视频和音频功能
3:设备显示的差异性
4:网络连接速度
5:编码注意事项
14:编码注意事项
17:编码变量
23:详细AAC/AVC、音频视频设置
42:结论

Android设备的移动编程指南(PDF, 885 KB)

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

有人問 Flex 4, 4.5 Spark 的 Download Progress Bar 不出現的問題
Adobe 討論板上也有人問 原因大略是因為 Flex 4, 4.5 提高了出現的門檻
原本 MX 版 Progress Bar 是要超過 300ms 才會出現
Spark 版 Progress Bar 要超過 700ms 且下載進度未超過 50% 才會出現
條件相當嚴苛,導致一般的小 Flex App 都看不到下載進度條了

解決的方式不難,自己繼承 SparkDownloadProgressBar 並覆寫 showDisplayForDownloading

package {
 import flash.events.ProgressEvent;
 import mx.preloaders.SparkDownloadProgressBar;
 
 public class MySparkDownloadProgressBar extends SparkDownloadProgressBar {
 
  override protected function showDisplayForDownloading(elapsedTime:int, event:ProgressEvent):Boolean {
   /*/
   trace("showDisplayForDownloading: elapsedTime = " + elapsedTime);
   trace("showDisplayForDownloading:" + event.bytesLoaded + " " +
    event.bytesTotal + " " + (event.bytesLoaded < event.bytesTotal / 2));
   //*/
 
   return elapsedTime > 100;
   // return elapsedTime > 700 && event.bytesLoaded < event.bytesTotal / 2;
  }
 }
}

然後在 Application 替換為自訂的 Preloader 就好了:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  xmlns:s="library://ns.adobe.com/flex/spark"
  xmlns:mx="library://ns.adobe.com/flex/mx"
  preloader="MySparkDownloadProgressBar">
 
 <s:layout>
  <s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
 </s:layout>
 
 <s:Button label="Button" />
 
</s:Application>

假如想要調整 MX 版 Progress Bar 出現門檻,方法也是類似
只是要覆寫的 function 不一樣

package {
 import mx.preloaders.DownloadProgressBar;
 
 public class MyDownloadProgressBar extends DownloadProgressBar {
 
  override protected function showDisplayForInit(elapsedTime:int, count:int):Boolean {
   return elapsedTime > 300 && count == 2;
  }
 
 }
}
分享到新浪微博 分享到人人网 分享到豆瓣 分享到鲜果 分享到百度空间 分享到开心网 QQ书签 分享到YAHOO! 分享到Google Google Buzz 分享到Facebook 分享到Plurk Digg delicious Technorati Twitter

On my way

2012 年五月
« 四    
 123456
78910111213
14151617181920
21222324252627
28293031  

Client & Partner

HSBC
ING
永丰银行
桐乡·振石大酒店
MODEKUU思齐之家

Aedis.Ju Ex-Blog

MXNA
9RIA
Creative Commons License
DropBox