[AS]FlashBuilderでのパブリッシュでエラーを修正しても再パブリッシュでエラーが消えない

FlashBuilder4の体験版で操作感を試してたときのハマッたこと。
(もともとFlexBuilderを使ってる人からしたらあたり前のことなんだろうけど)

ボクみたくFlashIDEとFlashDevelopしか使ってなかった人で、エディターとしてFlashBuilder使おうと思ってる人がひっかりそうなのでメモ。

状況:
ActionScriptプロジェクトを作成。
ドキュメントクラスでBetweenAS3の動作テストしようと思ったら、nullエラー発生。
ASを修正して再度デバッグモードでパブリッシュ(F11)するも同じエラーが表示される。
該当箇所全部消しても、同じエラー。ムキーなんじゃこりゃー。となる。

解決:
Flashデバッグのパースペクティブのデバッグタブに状況が表示されるのだけど
エラーのときにここが赤字で中断になるときがあってこのまま放置すると同じエラーが吐かれ続けるみたい。
※メインスレッド(中断:~ ってところ

デバッグタブ右の赤い■ボタンを押して終了するか、一式をデリートで消してから(ここではTest[WEBアプリケーション]を選択してDELETEキー)、改めてコード修正して再パブリッシュすればOKのようす。
再パブリッシュするときは、エラーを中断状態のまま放置しないで終了状態にしとけってことなのね。

そういやeclipse使ってのJavaのWEBアプリケーションの実行も処理を一度終了させてから実行しないとダメだったな。。。
せっかくの知識があんまり役立ってねぇ。。

[AS]swcでくるんだクラスをgetDefinitionByName()で読み込むときの注意

SWC書き出しでアセット作るというワークフローを試してみたところ、若干はまったのでメモ。

SWCの書き出しと読み込みはkayacさんの記事を参照ください。
参考:SWC書き出しを有効に使って作業効率アップ:_level0.kayac

で、たとえば、MyMc0ってクラス名でリンケージしたMcを含んだswcファイルを用意したとして、
そのMyMc0を取り出すときの処理で、普通に書くと↓な感じでOK

var myMc0:MyMc0 = new MyMc0();
addChild(myMc0);

ただここで、クラス名を動的に生成したい場合は、getDefinitionByName()使わないとなので、こんな感じ。
これも問題なくOK。

var index:int = 0;
var className:String = "MyMc" + index;
var myClass:Class = getDefinitionByName(className) as Class;
//myMc0はMyMc0として定義
var myMc0:MyMc0 = new myClass();
addChild(myMc0);

で、お次はハマったダメな場合の書き方
↓これはエラーになります。

var index:int = 0;
var className:String = "MyMc" + index;
var myClass:Class = getDefinitionByName(className) as Class;
//myMc0はMovieClipとして定義
var myMc0:MovieClip = new myClass();
addChild(myMc0);

違いは、変数myMc0の型をMyMc0とするか、MovieClipにするか、ということ。
MyMc0なら、エラーにはならないけど、MovieClipにするとエラーになります。

MyMc0の親クラスはMovieClipなんだから、間違いないんじゃね?
と思ってましたが、問題はそこではなく、エラーのコードでは、MyMc0が一度も出てきてない、という事実が問題。
もっと具体的にいうと、「MyMc0に参照が通ってないからMyMc0は使えない」、ということになるんだそうだ。

詳細は以下、

コンパイルする段階で、使われてないクラスは含まないようにして最適化されるからですよん。なので import しただけだと、使ってないとみなされて、コンパイル段階で省かれてしまうんです。
必要なのはクラス名ではなくて、クラスへの参照です。なので、ロジック中にクラス書くと、エラー回避出来るんです。

soundkitchen:Tweet1
soundkitchen:Tweet2

なので、エラーコードを修正例としては、

//MyMc0を明示的に表記することで参照を通して、MyMcを使うよってことをアピール。
MyMc0;
//上の書き方がよくわからなくて気持ち悪いときは、空の変数定義でもOK
var hoge:MyMc0;
var index:int = 0;
var className:String = "MyMc" + index;
var myClass:Class = getDefinitionByName(className) as Class;
//myMc0はMovieClipとして定義
var myMc0:MovieClip = new myClass();
addChild(myMc0);

個人的な感覚としては、 getDefinitionByName()でクラス作って、そのクラスでnewしてるんだから、問題ないんじゃない?と思ってたけど、プログラム的には明示的に参照を通さないとだめらしい。

Twitterのおかげで知識が広がる、嬉しい限り。

ちなみにswcを使いたかったのはFlexBuilderとかFlashDevelop+flexSDKで製作するようにしたかったから。
ムービープレビューが速い速い。

[AS]DisplayObjectContainerが内包しているDisplayObjectをすべてremoveChildする

人のソースからのメモ
DisplayObjectContainerが内包しているDisplayObjectをすべてremoveする処理を1行で。
whileは無限ループになるのが怖いから苦手意識あるなー

while(numChildren) removeChildAt(0);

[AS]TLF用にCFF形式のフォントを埋め込んだSWFがどうやっても作れない
→解決!!!

※2010/03/09/14:49 解決(一番下に追記):クリック

TLF(TextLayoutFramework)を使ったときにフォントを埋め込むにはCFFでトランスコードしたフォントを埋め込んだSWFを作って、そのSWFからフォントを読み込むという手順らしい。
が、しかし、そもそもこの形式でSWFが書き出せない。

具体的には、
Unable to transcode
とトランスコードできないというエラーになる。

まずは↓を見て同じようにやってみただけど、上記エラー
TextlayoutFrameworkやFlash.text.engineで埋め込みOpenTypeフォントを使う方法:高橋文樹.com

つぎに↓を見つけ、同様の古いSDKで試してみるも、やっぱり上記エラー。。。
新テキストエンジンFlash.text.engineでOpenTypeのフォントを埋め込みで使う:SIHOのActionScript勉強メモ

SDKもいろいろ試してみた。
flex_sdk_4.0.0.4021
flex_sdk_4.0.0.4904
flex_sdk_4.0.0.7219(Beta1)
flex_sdk_4.0.0.10485(Beta2)
・・・全滅

上記、SHIHOさんはMACでやられてるようなので、MACでも試してみた。
でもだめ。。。
意味がわからん、どうしようもないわ。

原因がわかりそうな方、ぜひアドバイスをお願いします。。。

※試してみた環境
◆コンパイラ
flex_sdk_4.0.0.4021
flex_sdk_4.0.0.4904
flex_sdk_4.0.0.7219(Beta1)
flex_sdk_4.0.0.10485(Beta2)

◆実行ツール
FlashDevelop(3.0.6) + Flex4SDK (AS3プロジェクト)
FlexBuilder + Flex4SDK (ASプロジェクト)

◆OS
Win XP SP3
Mac OS10.6(FlexBuilder + flex_sdk_4.0.0.4021でのみ実行 )

◆メインAS

//swfの書き出し先にfontフォルダをつくりその中にA-OTF-ShinGoPro-Regular.otfという名前のフォントファイルを配置。
package {
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
[Embed(source = "font/A-OTF-ShinGoPro-Regular.otf", fontName = "Shingo", cff = "true")]
//最新のSDKを使うときは、cffをembedAsCFFに変更して試した
//[Embed(source = "font/A-OTF-ShinGoPro-Regular.otf", fontName = "Shingo", embedAsCFF = "true")]
public static var font:Class;
public function Main():void {
trace("Main.Main");
}
}
}



※2010/03/09/12:27追記
taigaさんにアドバイスを頂き、明示的にプレイヤー10にしてなかったことに気付きました。。
FlexBuilder:追加コンパイラ引数に、-target-player=10.0.12を追加
FlashDevelop:project>property>output>TargetをFashPlayer10に変更
(setting>AS3Context>Language>DefaultFlashVersionも10)
さらにモリサワ系のフォントはダメっぽいとの助言も頂き、taigaさんの記事で実績のある小塚明朝に。
メインASもtaigaさんの記事のものを拝借し、以下に更新

package {
import flash.display.Sprite;
public class Main extends Sprite {
[Embed(
source               = "font/KozMinPro-Bold.otf",
fontName             = "testFont",
mimeType             = "application/x-font",
embedAsCFF           = "true",
advancedAntiAliasing = "true"
//unicodeRange         = "U+5927, U+96c5" 大雅
)]
public static const FONT:Class;
}
}

で、結果は変わらずで同じエラーのまま。
×が消えず。

うーんなんでだろう。
ちなみにコンパイラは最新のSDKを仕様




※2010/03/09/14:03追記
FlashBuilderで試してみては?という助言のもとトライ。
FBインストール後、プロジェクトプロパティのASコンパイラーのPlayerオプションを以下のように設定。

プロジェクト作って、メインのASにソースをコピペ。
bin-debugフォルダにfontフォルダを作って、小塚フォントを設置。
まずはデフォルトのSDKで試すもいつものエラー。。。。

SDKをBeta2(flex_sdk_4.0.0.10485)に変更してみるも結果は同じ。。。

フォント含んだswfの書き出しは都市伝説なんじゃないかと思えてきた。。。





※2010/03/09/14:49追記
taigaさんからのご指摘で解決しました!
結論からいうと、srcフォルダにfontファイルを置いてなかったから。
Embedは埋め込みなので、コンパイル環境であるsrcにおいてないとダメだそうな。
bin-debugに置くのは、swfから読み込む場合だったね。
あー、なんという無能っぷり。

というわけで、正しくはこんな感じになります。

※2010/03/09/17:44 さらに追記
FlashDevelopで、同じように実行してみると、

Warning: This compilation unit did not have a factoryClass specified in Frame metadata to load the configured runtime shared libraries. To compile without runtime shared libraries either set the -static-link-runtime-shared-libraries option to true or remove the -runtime-shared-libraries option.
Build halted with errors (fcsh).

のようにWarningがでた。
これの解決は↓の方が書いてくれてました。
Flex 4で画像の埋め込みでエラー & flex-config.xmlのバージョンアップ:sub Diary (仮)

素直にコンパイルの引数に”-static-link-runtime-shared-libraries=true”を書く

これをFlashDevelopに適応してみたら上記エラーはでなくなった。
愚弟的には、
Project>Property>Compiler Optionsタブ>Advanced>AdditionalCompilerOptions>String[]配列に
-static-link-runtime-shared-libraries=true
を追加。
たぶんこれで大丈夫・・・?

とおもったら、どうやらだめっぽい。
エラーはでてないけど、生成されたswfにはFontが内包されてないっぽい。
とりあえずはFB4で作った方がいいね。
FlashDevelopでの実行についてはあとで検証する。
sub Diary (仮)さんとこの解決事項でまだ試してないのもあるしね。

[AS]フォント名を指定するときの注意(日本語?英語?)

一個前の記事でも書いたのだけど、

※ここで引っかかったのはフォントの指定。
フォント名を指定するときに、flashのヒストリパネルに表示されるjsflをそのまま使ったらフォントが反映されない。
たとえば、新ゴProのLを指定したいときには、
jsflには、setElementTextAttr(‘face’,’ShinGoPro-Light’);と表示されたのでそのままコピペしたら動作しない。
フォント名を取得するサンプルで取得したフォント名を使用すると上手くいった。
setElementTextAttr(‘face’,’A-OTF 新ゴ Pro L’);ってな感じになります。
この差異の原因はFlashが日本語版か英語版かってことなのかな、まぁよくわからん。

この現象は予想通りコンパイラに依存するっぽい。
FlashDevelop + Flex4SDKBeta1の組み合わせて、フォント指定でパブリッシュしてみると、
指定した、フォント名が、
A-OTF 新ゴ Pro Lでは反映されずに、
ShinGoPro-Lightだと反映された。

Flex4SDKは日本語仕様ではないから、日本語は認識しないのだね。
この辺は無理に日本語化しないでアルファベットに統一してくれたらわかりやすいと思うんだが。。。

[JSFL]シンボル内の静止テキストのサイズ、フォントを変更するJSFL

製作経緯はこんなかんじ。
e-ラーニング系のコンテンツをタイムラインのアニメーションで製作中のこと。
静止テキストのモーショントゥイーンを大量にステージ配置。
雛形できたら大量生産するぜー、と5ファイルくらい作ってたところで、ここにきてテキスト関係の仕様の提示。
OH MY GOD(ってかちゃんと確認しないで作り始めたボクが悪い)
フォントサイズの変更、フォント色の変更、フォントの変更。。。
1個1個MCの中に入って静止テキストを変更するのめんどくさい。。。
1ファイルあたりMCが10個以上あるし。。。
!そうだ!これ、JSFLでできるんじゃね!?
とこんな感じ。

というわけで以前作ったソースをちょろっと変更してできたのはこんな感じ。
使い方
色を変更したいMCをライブラリで選択し(複数OK)、コマンドを実行。
それぞれ値を入力するダイアログがでるので値を入力すればOK。
※内部にテキストフィールドが1個だけあるようなシンボルの変更を想定してますのでそれ以外はどうなるかわかりません。。。

◆フォントサイズ変更

var doc = fl.getDocumentDOM();
var num = prompt(“フォントサイズを入力”, “18”);

var items = doc.library.getSelectedItems();
for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); doc.setElementTextAttr('size',num); doc.exitEditMode(); } [/sourcecode] ◆フォント変更 [sourcecode language='js'] var doc = fl.getDocumentDOM(); var fontName = prompt("フォントを指定", "A-OTF 新ゴ Pro L"); var items = doc.library.getSelectedItems(); for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); doc.setElementTextAttr('face',fontName); doc.exitEditMode(); } [/sourcecode] ※ここで引っかかったのはフォントの指定。 フォント名を指定するときに、flashのヒストリパネルに表示されるjsflをそのまま使ったらフォントが反映されない。 たとえば、新ゴProのLを指定したいときには、 jsflには、setElementTextAttr('face','ShinGoPro-Light');と表示されたのでそのままコピペしたら動作しない。 フォント名を取得するサンプルで取得したフォント名を使用すると上手くいった。
setElementTextAttr(‘face’,’A-OTF 新ゴ Pro L’);ってな感じになります。
この差異の原因はFlashが日本語版か英語版かってことなのかな、まぁよくわからん。

おまけ
色と、フォントと、サイズをいっぺんに変更できるやつ

◆いろいろいっぺんに変更

var doc = fl.getDocumentDOM();
var num = prompt(“フォントサイズを入力”, “18”);
var fontName = prompt(“フォントを指定”, “A-OTF 新ゴ Pro L”);
var color = prompt(“テキストの文字色を入力”, “#000000”);
var items = doc.library.getSelectedItems();
for (var i = 0; i < items.length; i++) { doc.library.editItem(items[i].name); doc.selectAll(); //サイズ変更 doc.setElementTextAttr('size',num); //フォント変更 doc.setElementTextAttr('face',fontName); //色変更 doc.setFillColor(color); doc.exitEditMode(); } [/sourcecode] 一応、一式ダウンロードはこちら

[JSFL]シンボル内のオブジェクトの色を一括で変更するコマンド

製作経緯はこんなかんじ。
e-ラーニング系のコンテンツをタイムラインのアニメーションで製作中のこと。
静止テキストのモーショントゥイーンを大量にステージ配置。
あれ。。。よく確認してみたら仕様と違う。。。テキストの色間違ってるじゃん。。。
もう3ファイルくらい作ってて、静止テキストをラップしたMCが大量にあるよ。。。
1個1個MCの中に入って静止テキストの色を変更するのめんどくさい。。。
1ファイルあたりMCが10個以上あるし。。。
!そうだ!これ、JSFLでできるんじゃね!?
とこんな感じ。

そしてできたのはこんなかんじ。
使い方
色を変更したいMCをライブラリで選択し(複数OK)、コマンドを実行。
色を入力するダイアログがでるので色値を入力すればOK。
※MCだけじゃなくて、グラフィックとかボタンでもOK。
※静止テキストだけじゃなくて、シェイプの色も変わります。

var doc = fl.getDocumentDOM();
var items = doc.library.getSelectedItems();
ret = prompt("テキストの文字色を入力", "#000000");
//alert(ret);
for (var i = 0; i < items.length; i++) {
  doc.library.editItem(items[i].name);
  doc.selectAll();
  doc.setFillColor(ret);
  doc.exitEditMode();
}

当初はステージに配置してあるオブジェクトを選択して選択されたMCの中の色を変更しようとしてたのだけど、どうも上手くいかない。
でも良く考えたらこの動作ってライブラリ内のオブジェクトを変更するのと同じことだからこれでいいや、と。

欲しい人いるかはわからんけど一応zipでおいておこう。
シンボル内のオブジェクトの色変更する.jsfl

[AS]TextLayoutFrameworkの簡単なサンプル

TextLayoutFramework(TLF)のメモ

以下に簡単なサンプル

package  {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.*;

	// 使用するText Layout Framework クラスのロード
	//flex SDK 4 に含まれているtextLayout.swcを使用する。
	import flashx.textLayout.container.*;
	import flashx.textLayout.compose.*;
	import flashx.textLayout.conversion.*;
	import flashx.textLayout.edit.*;
	import flashx.undo.*;
	import flashx.textLayout.elements.*;
	import flashx.textLayout.container.ContainerController;

	/**
	 * ...
	 * @author 393
	 */
	public class TextTest2 extends Sprite{
		private var textFlow:TextFlow;
		private var container1:Sprite;
		private var container2:Sprite;
		private var count:int;
		
		public function TextTest2() {

			var text:String="本日確定申告と同時に開業届けも提出してきました。";
			text = [text, text, text, text, text, text, text, text].join("****************");
			
			//テキストフィールドみたいなもの
			textFlow=TextConverter.importToFlow(text,TextConverter.PLAIN_TEXT_FORMAT);
			//テキスト選択とか可能になる
			textFlow.interactionManager = new EditManager();

			//テキストを格納するコンテナーの定義(複数個を連結可能)
			container1 = new Sprite();
			container2 = new Sprite();
			addChild(container1);
			addChild(container2);
			container2.y=150;
			
			//テキストフローにコンテナを追加
			textFlow.flowComposer.addController(new ContainerController(container1, 200, 100));
			textFlow.flowComposer.addController(new ContainerController(container2, 200, 100));
			//テキストフローの更新(コンテナのサイズとか変更したら更新する)
			textFlow.flowComposer.updateAllControllers();
			
			//現在のコンテナの数を取得(出力:2)
			trace("textFlow.flowComposer.numControllers : " + textFlow.flowComposer.numControllers);
			
			//ステージをクリックするごとにテキストフローのコンテナサイズを変化
			stage.addEventListener(MouseEvent.CLICK , clickHandler);
			count = 300;
		}
		
		private function clickHandler (e:*):void {
			//コンテナの数だけループ
			for (var i:int = 0; i < textFlow.flowComposer.numControllers; i++) {
				//コンテナのサイズを変更
				textFlow.flowComposer.getControllerAt(i).setCompositionSize(count,100)
			}
			//テキストフローの更新
			textFlow.flowComposer.updateAllControllers();
			count += 100;
		}	
	}
}

[iP]Objective-Cの文法メモ(#define)

Objective-CというかC言語のお話なのだろうか

#defineを定数的な扱いができるものだと思ってたら、マクロというものらしい。
定数以外にも関数的にも使えるようだ。

//定数的な扱い:posXを100として使える
#define posX 100
//関数もあり:degreeToRadian(180)で180度のラジアン値を返す
//M_PIは定数で円周率らしい
#define degreeToRadian(x) (M_PI * (x) / 180.0)
//注意するのは、最後にセミコロンを書いちゃだめ
//↓これだとダメ
//#define posY 100;

[iP]Objective-Cの文法メモ(self,アクセサ/ミューテーター)

すぐわすれちゃうので気になったところは、とりあえずメモってくことにする。

★プライベートな変数にアクセスするときは、selfを頭につける。
ASでいうところのthisみたいなもんらしい。
ただし記述で省略はしないみたい。
(また、ローカル変数は頭になにもつけないので、頭にselfがあるのはインスタンス変数、なにもなかったらローカル変数という見分け方ができるからわかりやすいかも)

//二つは同じ意味
self.hoge = nil;
[self setHoge:nil]//- (void) setHoge:(id) aHoge{}を実装してあるのが前提

★いわゆるセッターを、Objective-Cではミューテーターと呼ぶ
(インスタンス変数を参照・変更するためのメソッドをアクセサと呼ぶ)