[AS]フォント埋め込みの際のフォント名を取得する方法

以前書いた、
[AS]FlashPlayer10ではTestFieldにアルファ処理可能、あとFlashPlayer9でのフォントの埋め込み方法の詳細
の記事の補足

上の記事では、フォントを指定する際に、TextFormat.fontに指定するフォント名を手動で調べないといけないと書いたけど、ライブラリに登録されたフォントから、さくっと取得することができるようだ。

//フレームアクション
//ライブラリ内のフォントのリンケージ名
var class_name=”font1″;
var loadedFont:Font = new Font();
var LoadFontClass:Class=ApplicationDomain.currentDomain.getDefinition(class_name) as Class;
Font.registerFont(LoadFontClass);
loadedFont = new LoadFontClass();
//これがTextFormat.fontに指定するフォント名となる。
var font_name=loadedFont.fontName;

//おまけ
//テキストフォーマット
var fmt:TextFormat=new TextFormat();
//フォント名を指定
fmt.font=font_name;
fmt.size = 40;
fmt.bold = false;
//テキストフィールド作成
var tf:TextField=new TextField();
tf.embedFonts=true;
tf.defaultTextFormat=fmt;
tf.text=”Test”;
//表示
addChild(tf);

教えてくれたサイト:frasio report:[AS3]埋め込みフォントの盲点

[AS]入れ子状態のDisplayObjectの幅/高さをあくまで内容物の大きさによる

あたりまえといっちゃあたりまえのことに躓いた。

var sp:Sprite = new Sprite();
sp.graphics.beginFill(0);
sp.graphics.drawRect(0,0, 10, 100);
var container:Sprite = new Sprite();
container.addChild(sp);
sp.y = 300;
this.addChild(container)
container.addChild(sp)
trace(container.height);//出力は400ではなく、100
//(containerはDisplayObjectContainerの機能しか果たしていないので)

ステージに手動でMCとか作ってるときには直感的に理解していたことだけど、ASで動的に作ってるときにはなぜか上記のようなときは400になるもんだと思ってた。

そんで高さを400にするためには以下のようにすればOK。

var sp:Sprite = new Sprite();
sp.graphics.beginFill(0);
sp.graphics.drawRect(0,0, 10, 100);
var container:Sprite = new Sprite();

container.graphics.drawRect(0,0,0,0);//大きさの無いものをdrawしておくだけでいいらしい

container.addChild(sp);
sp.y = 300;
this.addChild(container)
container.addChild(sp)
trace(container.height);//出力:400

相対的な位置情報も含めて大きさを保持したい場合は単にアルファ0でのものを置こうかと思ったけど、大きさを指定しない状態でdrawするだけでいいようだ。
これは試してみてよかった。

[AS]文字が半角か全角のチェックする方法

厳密にいうとちょっと違うみたいだけどこんな感じ。

//文字列の全角/半角チェック関数。
//(文字列内の文字が全て半角の場合にtrueを返す)
function isAll1ByteChar(str:String):Boolean {
var countCharCode:Number = 0;
var isAll1Byte:Boolean = false;

for (var i:int = 0; i < str.length; i++) {
// 条件分岐
// 2010/01/27修正:半角カナ対応(のつもり)
if (str.charCodeAt(i)<=255 || str.charCodeAt(i)>=0xFF61 &amp;amp;&amp;amp; str.charCodeAt(i)<=0xFF9F) {
countCharCode+=1;
} else {
countCharCode+=2;
}
}
if(str.length == countCharCode) {
isAll1Byte = true;
}
return isAll1Byte;
}
var str1:String = “aaアaaa”
var str2:String = “あああああ”;
var str3:String = “aaaaあbcs”;
trace(isAll1ByteChar(str1));//出力:true
trace(isAll1ByteChar(str2));//出力:false
trace(isAll1ByteChar(str3));//出力:false

2010/1/27:コード修正:半角カナ対応(のつもり)

[AS]progression4 LoadCommand系のイベント(開始、終了、ローディング、エラー、中断)のまとめ

progressionのコマンドを使ったときのイベント処理追加(開始、終了、ローディング、エラー、中断)のやり方
何種類か方法があるようなのでまとめ。

1.addEventLinstenerを使った一般的な書き方

public function Test2() {
//コマンドの定義
var loadSound:LoadSound = new LoadSound(new URLRequest(“./sound.mp3″));
//イベント処理の追加
loadSound.addEventListener(ExecuteEvent.EXECUTE_START, startHandler);
loadSound.addEventListener(ExecuteEvent.EXECUTE_COMPLETE, completeHandler);
loadSound.addEventListener(ExecuteErrorEvent.EXECUTE_ERROR, errorHandler);
loadSound.addEventListener(ProgressEvent.PROGRESS, progressHandler);
//コマンドの実行
loadSound.execute();
}
private function progressHandler(e:ProgressEvent):void {
trace(“e : ” + e);
}
private function errorHandler(e:ExecuteErrorEvent):void {
trace(“e : ” + e);
}
private function completeHandler(e:ExecuteEvent):void {
trace(“e : ” + e);
}
private function startHandler(e:ExecuteEvent):void {
trace(“e : ” + e);
}

2.addEventLisnerを使わない書き方
※エラー発生時のイベントについては、onErrorとcatchErrorのどちらでも取れるけど、エラーの内容を参照するには、catchErrorを使っておいた方がいいみたい。
(引数:errorでエラー内容が取れる)

public function Test2() {
//コマンドの定義
var loadSound:LoadSound = new LoadSound(new URLRequest(“./sound.mp3″));
//イベント処理の追加
loadSound.onStart = function(){
trace(“onStart this : ” + this);
};
loadSound.onComplete = function(){
trace(“onComplete this : ” + this);
};
loadSound.onError = function(){
trace(“onError this : ” + this);
};
loadSound.catchError = function(target:Object, error:Error){
trace(“onError this : ” + target ,error);
target.interrupt();
};
loadSound.onProgress = function(){
trace(“onProgress this : ” + this);
};
//コマンドの実行
loadSound.execute();
}

3.addCommand内とかでコマンドのインスタンスを作れないときのやり方
※エラー発生時のイベントについては、onErrorとcatchErrorのどちらでも取れるけど、エラーの内容を参照するには、catchErrorを使っておいた方がいいみたい。
(引数:errorでエラー内容が取れる)

public function Test2() {
//コマンドの定義
var slist:SerialList = new SerialList();
slist.addCommand(
new LoadSound(new URLRequest(“./sound.mp3″), null,
{
//読み込み開始時
onStart:function():void{trace(“start : ” + this)}
//読み込み完了時
,onComplete:function():void{trace(“onComplete : ” + this)}
//読み込み中
,onProgress:function():void{ trace(“onProgress : “+this); }
//読み込みエラー
,onError:function():void{trace(“error : “+ this)}
,catchError:function(target:Object, error:Error):void{trace(“error : “+ target,error)}
//読み込み中断時
,onInterrupt:function():void{trace(“interrupt : “+ this)}
}
)
);

//コマンドの実行
slist.execute();
}

[AS]progression4 LoadCommand系でのエラー処理とかローディング処理とか中断処理とか

メモ
initObjectでイベントを管理可能

slist.addCommand(
new LoadSound(new URLRequest(“./sound.mp3″), null,
{
//読み込み開始時
onStart:function():void{trace(“start”)}
//読み込み完了時
,onComplete:function():void{trace(“onComplete”)}
//読み込み中
,onProgress:function():void{trace(“progress” + this.bytesLoaded);}
//読み込みエラー
,onError:function():void{trace(“error”)}
//読み込み中断時
,onInterrupt:function():void{trace(“interrupt”)}
}
)
);
slist.execute();

参考:_level0.KAYAC:Progression4の新コマンドあれこれ

[AS]progression4 Load系コマンド(LoadURLとかLoadSoundとか)で読み込んだデータをインスタンス変数に参照させて取り扱うときの注意

題名のまんまをprogression forumに質問したらすぐに回答を頂けたのでその補足メモ。

まずLoad系のコマンドで読み込んだデータを扱う際の定石は

//※要点を抜粋したコード
var _sound:Sound;
addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = this.latestData;
trace(_sound)//出力:[Object Sound]
}
)

と思ってましたが、progression4からは、getResourceByIdというものを使った方が便利とのこと。
↑のコードを書き換えると

//※要点を抜粋したコード
var _sound:Sound;
addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = getResourceById( “./sound.mp3″ ).data;
trace(_sound)//出力:[Object Sound]
}
)

getResourceById()の便利なところは、一度読み込めば、読み込んだデータがどこからでも参照できるというところみたい。
getResourceById( “./sound.mp3″ )と書くことでstaticは変数みたいな扱いができるということかな。

↓ざっくり書くとこんな感じ。

//※要点を抜粋したコード
var _sound:Sound;
addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = getResourceById( “./sound.mp3″ ).data;
trace(_sound)//出力:[Object Sound];
new Test();
}
)
//
class Test {
function Test(){
trace(getResourceById( “./sound.mp3″ ).data)//出力:[object Sound]
}
}

あとgetResourceByGroupというものもあって同様な扱いができるそうです。
上記の検証で参考になった記事
参考:_level0.KAYAC:Progression4の新機能Resourceを試してみる

でタイトルの本題については、forumに書いたけど↓ではSerialList内のtraceはnullになり

addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = getResourceById( “./sound.mp3″ ).data;
trace(_sound)//出力:[Object Sound];
new Test();
}
,new SerialList(null
,new Trace(_sound)//出力:null
)
)

SerialListをfinctionでくくると参照がとれました。

addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = getResourceById( “./sound.mp3″ ).data;
trace(_sound)//出力:[Object Sound];
new Test();
}
,function(){
new SerialList(null
,new Trace(_sound)//出力:[Object:Sound]
).execute()
}
)

最後にこれらの集大成的なコード(ドキュメントクラス)
(functionで括らないSerialList内でのTraceでnullになるのは、イマイチ理解できてないけど)

package {
import flash.display.Sprite;
import flash.media.Sound;
import flash.net.URLRequest;
import jp.progression.commands.media.DoSound;
import jp.progression.commands.display.*;
import jp.progression.commands.lists.*;
import jp.progression.commands.net.*;
import jp.progression.commands.tweens.*;
import jp.progression.commands.*;
import jp.progression.data.getResourceById;
/**
* @author 393
*/
public class Test extends Sprite{
private var _sound:Sound;
private var number:int = 0;

public function Test() {
var slist:SerialList = new SerialList();
slist.addCommand(
new LoadSound(new URLRequest(“./sound.mp3″))
,function(){
_sound = getResourceById( “./sound.mp3″ ).data;
trace(“_sound : ” + _sound);
new DoSound(_sound).execute();
number = 100;
}
,new SerialList(null
,new Trace(“SerialList number : ” + number)//出力:0
,new Trace(“SerialList sound : ” +_sound)//出力:null
)
,new Func(next)
);
slist.execute();
}
private function next():void{
trace(“number : ” + number);//出力:100
trace(“nextの_sound : ” + _sound);//出力: [object Sound]
new Test2()
}
}
}
import jp.progression.data.getResourceById;

class Test2{
public function Test2() {
trace(“Test2のgetResourceById( \”./sound.mp3\” ).data : ” + getResourceById( “./sound.mp3″ ).data);
}
}

[AS]progression4 managerインスタンスの参照でちょっとはまった

progression4からは、Progressionクラスを参照できるプロパティがmanagerになりました。
(3はprogressionだった)
SceneObjectとかCastSpriteとかが持ってるプロパティなので簡単に参照できます。

んが、ちょっとはまったのでmemo。

SceneObject(を継承したカスタムクラス)の場合、そのSceneObjectがaddSceneされてない状態では、managerはnullとなる。
つまりSceneObjectのコンストラクタに
trace(manager)
としてもnullが返ってくるだけ。
addSceneされたあとなら、Progressionインスタンスを返してくれる。

CastSprite(を継承したカスタムクラス)の場合は、自身の親が普通のspriteとかMovieClipの状態では参照できない。
親はCastSpriteとかCastMovieClipとかprogression独自のDisplayObjectContainerでないとだめ。

[2011.10.19追記]
とうぜんstageに追加した場合もmanagerはnullとなる

//nullの例
var sp:Sprite = new Sprite();
container.addChild(sp) //containerはprogressionの持ってるプロパティ。(progression的なstage)
var csp:CastSprite = new CastSprite();
sp.addChild(csp);
trace(csp.manager);//出力:null
//nullじゃない例
var sp:CastSprite = new CastSprite();
container.addChild(sp) //containerはprogressionの持ってるプロパティ。(progression的なstage)
var csp:CastSprite = new CastSprite();
sp.addChild(csp);
trace(csp.manager);//出力:[Progression id="index"]

というようなことが上手くまとめられてる記事もありました。
ありがたいことです。

参考:Fountain:Flash初心者がProgression 4 publicBeta1.1を始めたメモ

[AS]TextFieldで幅固定、高さ可変とする設定

手順としては、
1.TextField.autoSizeをnone以外
2.TextField.wordWrapをtrue
3.TextField.widthを設定
(設定の順番は変えてもいいみたい)
autoSizeをnone以外にして、wordWrapをtrueにするのがポイントらしい。

参考:trick7:TextField が思いのほか細長くなったら

[AS]progression4 preloaderの表示オブジェクトコンテナー foreground/background

preloader.fla(プリローダー)に表示オブジェクトを追加する際は、foregroundもしくはbackgroundにaddChild()する。
CastPreloader.foreground
CastPreloader.background

foregroundは、メインコンテンツ(index.swf)よりも上の階層。
backgroundは、メインコンテンツ(index.swf)よりも下の階層

つまりコンテンツの背景として表示したいものはbackgroundに、
常に表示させたいものは、foregroundに、addChild()

[AS]デザインパターンについていろいろ

あとで読む。

【デザパタ入門】GoFによる23パターンの概要・分類・使用頻度:独学ActionScript

参考意見
doke/Twitter
doke/Twitter
clockmaker_core/Twitter
coppieee/Twitter