Category Archive: ActionScript

[AS]progression PRMLLoaderクラスで、Error #1065: 変数 IndexScene は定義されていません。が出たときの対処法

PRMLLoaderクラスは、xml形式のデータを外部読み込みすることで、progressionのシーン構成を生成するクラスでちょっとはまったのでメモ。
PRMLLoaderクラスの使い方は、ProgressionによるFlashコンテンツ開発ガイドのp268に分かりやすく書いてあるのでその通りにならって実行したつもりが、題記エラーが表示されました。。。
だがしかし、書籍のサンプルファイルをダウンロードしてみるとちゃんとできてる。

書籍サンプルファイルと自分のプロジェクトの差異はなんなんだ?
とひと晩結果が、xmlでのクラスファイル(cls属性)の指定が間違っていました。

まずは、OK
(問題なしの書籍のサンプルは以下の画像のようなプロジェクト構成)

そして、NG
(題記エラーが表示されたプロジェクト構成)

※xmlはいずれも以下の通りとした

<?xml version="1.0" encoding="UTF-8" ?>
<prml version="2.0.0" type="text/prml">
	<scene name="index" cls="IndexScene">
	</scene>
</prml>

まずOKのNGの違いは、IndexSceneがパッケージでくるまれてるかくるまれていないか、ということ。
OKは、srcの直下にIndexScenen.asがあるのでパッケージにはくるまれていない。
NGは、srcの直下にあるcsr393pv3dというパッケージでくるまれている。

結論としては、パッケージからのパスをxmlのcls属性に設定することが必要。
srcの直下にあるcsr393pv3dにIndexSceneが含まれた場合は、、

<?xml version="1.0" encoding="UTF-8" ?>
<prml version="2.0.0" type="text/prml">
	<scene name="index" cls="csr393pv3d.IndexScene">
	</scene>
</prml>

これで正常に実行される。

つまり、srcからみたパスの構成を、xmlのcls記述に記述する必要がある。

[AS]エラーprogression「Error #1065: 変数 ContextMenuClipboardItems は定義されていません。」の原因

Progrssionの勉強中にはまったことメモ。
FlashDevelop(以下FD)のProgression用プロジェクトテンプレートを使って試してます。
(FlashIDE無しでも作れちゃうのはホント便利)

Progressionは基本preloader.swf、index.swfの二つを使うので、上記テンプレートの使い方として、FDのprojectファイルを切り替えてパブリッシュしていきます。

いろいろごちゃごちゃやってたときにpreloader.swfをパブリッシュ時に以下のエラーが発生

Error #1065: 変数 ContextMenuClipboardItems は定義されていません。

preloader,indexともにソースコードをデフォルトに戻しても直らないのでなんだこりゃ?としばらく途方にくれました。。。

で、原因はというと、preloaderの対象となるFlashPlayerのヴァージョンを9でパブリッシュして、indexではヴァージョンを10でパブリッシュしていたというオチ。
(そういや、ごちゃごちゃやってるときにプレイヤーは10じゃないとダメだということで、indexだけ変更してたんだったな、と)
ContextMenuClipboardItems はFlashPlayer10から使える機能なので、FlashPlayer9のpreloader.swfからFlashPlayer10のindex.swfを読み込んだ際に使えないよってエラーだったようだ。
エラー内容読めばそのまんまなんだけどね。

というわけで、FlashPlayerのヴァージョンを変更する場合は、preloaderとindexをそろえてやることを忘れずに。。。
(調べてないけどprogressionに限らず親が9で、10の子swfを読み込んだ場合は必ず発生するのかな?)
ちなみにFDでは各プロジェクトのプロパティからプレイヤ-のバージョンを変更可能。

[AS]as3でのスクリプトの実行の順番をmemo

swfを開いたときに実行される順番がこんがらがることが多いので調べた。

まずはドキュメントクラスのコンストラクタとメインのタイムラインのフレームアクションの比較

  • 1.ドキュメントクラスのコンストラクタ。
  • 2.メインタイムラインのフレームアクション

これは想像通り。

注意が必要なのはリンケージしたMCをnewするとき、(ドキュメントクラスの)コンストラクタでnewするか、(メインのタイムラインの)フレームアクションでnewするかというとき。
※前提として、メインのタイムラインにはMc(Mc0_tl)が配置してあり、Mc0_tlには、さらにMc(Mc1_tl)が入れ子で配置してることとする。

まず、ドキュメントクラスのコンストラクタでnewする場合

  • 1.DocumentClass コンストラクタ開始
  • 2.DocumentClass ムービークリップを動的に生成(new MyMc0_as())
  • 3.▲MyMc0_as コンストラクタ開始
  • 4.▲MyMc0_as コンストラクタ終了
  • 5.DocumentClass ムービークリップを動的に生成終了
  • 6.DocumentClass コンストラクタ終了
  • 7.★MyMc0_as フレームアクション開始
  • 8.★MyMc0_as フレームアクション終了
  • 9.mainTimeLine フレームアクション開始
  • 10.mainTimeLine フレームアクション終了
  • 11.MainTimeLineに配置した Mc0_tl フレームアクション開始
  • 12.MainTimeLineに配置した Mc0_tl フレームアクション終了
  • 13.Mc0_tlに配置した Mc1_tl フレームアクション開始
  • 14.Mc0_tlに配置した Mc1_tl フレームアクション終了

動的にnewしたMyMc0_asのフレームアクションが開始されるのは、ドキュメントクラスのコンストラクタ終了直後。
(メインタイムラインのフレームアクションの前)

次にメインタイムラインのフレームアクションでnewする場合(1フレーム目に記載)

  • 1.mainTimeLine フレームアクション開始
  • 2.mainTimeLine ムービークリップを動的に生成(new MyMc0_as)
  • 3.▲MyMc0_as コンストラクタ開始
  • 4.▲MyMc0_as コンストラクタ終了
  • 5.mainTimeLine ムービークリップを動的に生成終了(new MyMc0_as)
  • 6.mainTimeLine フレームアクション終了
  • 7.MainTimeLineに配置した Mc0_tl フレームアクション開始
  • 8.MainTimeLineに配置した Mc0_tl フレームアクション終了
  • 9.Mc0_tlに配置した Mc1_tl フレームアクション開始
  • 10.Mc0_tlに配置した Mc1_tl フレームアクション終了
  • 11.★MyMc0_as フレームアクション開始
  • 12.★MyMc0_as フレームアクション終了

動的にnewしたMyMc0_asのフレームアクションが開始されるのは、ステージに配置してあるMc0_tlのフレームアクションが全て完了してから。

ここで気をつけるのは、MyMc0_asのフレームアクションにたとえば、

//MyMc0_asのフレームアクション開始
var myProp:Number;
myProp = Math.random();
MyMc0_asのフレームアクション終了

と書いて、
メインのタイムラインのフレームアクションで、以下のようにすると

var mc:MovieClip = new MyMc0_as();
trace(mc.myProp);//出力:NaN(Math.random()の代入は実行されていない)

期待通りの結果が得られない。

乱数が代入された結果を得るには、メインタイムラインの2フレーム目以降で、mc.myPropを参照すればOK。

一応検証したファイルをアップします。
1004231414_asflowtest.zip
読んでもさっぱり意味がわからない人はどーぞ。。。

[AS]progression4RC departedSceneIdやdestinedSceneIdをif文とかで判定できないってときはここに注意

progressionを使ううえでの便利プロパティ。
departedSceneId
destinedSceneId
以前のエントリでも書いてるように、出発シーンと、到着シーンを取得できます。
ただし↑はprogression3の書き方。
progression4では、progressionインスタンスは無くなり、managerが持ってるプロパティ。

manager.destinedSceneId;
manager.departedSceneId;

これを使って、if文の処理をしたいときちょっとはまったのでメモ。
destinedSceneIdとかdepartedSceneIdをtraceすると、
/indexとか、/index/aboutとか、sceneIdを出力してくれます。
なので、戻り値のデータ型はString?と思いきや、実は違います。

trace(manager.departedSceneId)//出力(例):/index
trace(typeof manager.departedSceneId)//出力:object(stringではない)

なので、if文で判定するときは、↓だと上手く判定されません

//manager.departedSceneId == manager.destinedSceneIdは中身がなんであろうと常にtrueとなる
if(manager.departedSceneId == manager.destinedSceneId){
    //処理
}

traceしたときに見えるSceneId名で判定させる場合は.toString()をつければOK

//
if(manager.departedSceneId.toString() == manager.destinedSceneId.toString()){
    //処理
}

※2010/04/17/16:30追記
コメントにてequals()メソッドというものを教えて頂きました。
こっちの方が簡単ですね。

if(manager.departedSceneId.equals(manager.destinedSceneId)){
	//処理  
}

※4のBetaまではtoStringなしでも判定してくれてたような気がするけど、RCからは無いとダメみたい。

[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] 一応、一式ダウンロードはこちら