Category Archive: ActionScript

[AS][?]画像のEmbedは1回しか使えない?

よくわからんけど、他のクラスでEmbed済みの画像を別のクラスでEmbedしても表示もされなかった。
エラーも出ないから、かなりはまった。
とりあえず、あとで検証する。

[Event][AS] Airアプリ「Twittenorion」

先日、東京てらこ 9に参加してきました。
Twitterで何かつくろうってテーマだったのAirアプリを作ってみました。

「Twittenorion」

タイトルどおりTweetのテキストでテノリオンするという感じです。
SEARCH WORDを入力しSEARCHボタンを押すと、入力してワードでのTwitterで検索を行い結果の20件をランダムで順番に表示さいていきます。
DRUM KITのON/OFFの際にはドラムパターンがランダムに変更されます。
BPMにあわせて流れる文字の速度が変化します。
集中したいときの作業用BGMになるかなってつもりで作りました。
 
以下からDLできますので、気になった人は試してみてくださいませ。
DownLoad : Twittenorion
 
 

またてらこでの発表資料のスライドもアップしておきます。
東京てらこ vol.9 発表資料
(キーボードのカーソルキーでスライドの操作ができます)
 
 

・キーボードから任意の文字を入力できるようにしたものをwonderflにアップしました。

Twittenorion – wonderfl build flash online

 
 

[AS]FocusManagerインスタンスを生成した状態で、InteractiveObjectのtabEnabledをfalse > trueに切り替えると、focusRectが利かなくなる

タイトルどおりの挙動に出くわした。

以下、再現する環境
メインタイムラインには、ボタンインスタンスとテキストフィールド(Input状態)が配置してあるとする。
ボタンインスタンスのインスタンス名:_btn

import fl.managers.FocusManager;
var focusManager:FocusManager = new FocusManager(this);
_btn.tabEnabled = false;
_btn.tabEnabled = true;

これで、パブリッシュし、Tabキーを押すと、テキストフィールドのカーソルからフォーカスは移動していることがわかるが、ボタンにフォーカスがあたっている状態で、黄色の枠が表示されない。
ちなみに、
var focusManager:FocusManager = new FocusManager(this);
この一文がなければ、黄色の枠は表示される。

黄色枠を表示させたい場合は明示的にfocusRectをtrueにしてあげればOK。
なんか面倒だ。

import fl.managers.FocusManager;
var focusManager:FocusManager = new FocusManager(this);
_btn.tabEnabled = false;
_btn.tabEnabled = true;
//これで_btnがフォーカス時に黄色枠が表示される
_btn.focusRect = true;

[AS]コンテンツ内のTabキーでのフォーカス移動を無効にする。

Tabキー対応は本気でやると結構面倒なので、いっそ全部無効にしてしまった方がいいかも.
素敵サイトもTabキーでバグること多々あり・・・

//これでひとまず全部無効(多分)
stage.stageFocusRect = false;

ただし個別のオブジェクトでfocusRectをtrueしてる場合は個別対応が必要

以下、InteractiveObject.focusRectプロパティ引用

このオブジェクトがフォーカス矩形を表示するかどうかを指定します。true、false または null の 3 つの値のいずれかを指定できます。true および false の値は、予想されるとおり、フォーカス矩形を表示するかどうかが指定されます。null 値は、このオブジェクトが Stage の stageFocusRect プロパティに従うことを示します。

[AS]内部にムービークリップを持つMCをgoAndStop()でMCが存在しないフレームへ移動したあとMCが存在するフレームに戻しても内部MCはnull参照になるみたい

タイトルが何言ってるかよくわからないと思うので、以下のフレームアクションを参照ください。

前提条件
//メインタイムラインにMovieClipインスタンス(インスタンス名:_mc1)を配置
//_mcの内部は全2フレームで、1フレーム目にフレームアクションstop();を記載
//_mcは内部の1フレーム目にのみ、MovieClipインスタンス(インスタンス名:_mc2)を持つ
//_mcの2フレーム目は何もない状態。

//ステージにMovieClipインスタンス(インスタンス名:_mc1)を配置
//_mcの内部は全2フレームで、1フレーム目にフレームアクションstop();を記載
//_mcは内部の1フレーム目にのみ、MovieClipインスタンス(インスタンス名:_mc2)を持つ
//_mcの2フレーム目は何もない状態。

trace("before _mc1:"+_mc1);
//出力:before _mc:[object Timeline_1]
trace("before _mc1._mc2:"+_mc1._mc2);
//出力:before _mc._btn:[object SimpleButton]

var mc:MovieClip = _mc1._mc2;
mc.buttonMode = true;

trace("before numChildren:"+_mc1.numChildren);
//出力:before numChildren:1
trace("before getChildAt:"+_mc1.getChildAt(_mc1.numChildren-1));
//出力:before getChildAt:[object MovieClip]

//_mcの2フレーム目に移動(_btnがないフレーム)
_mc1.gotoAndStop(2);
//_mcの1フレーム目に移動(_btnがあるフレーム)
_mc1.gotoAndStop(1);

trace("after _mc1:"+_mc1);
//出力:after _mc1:[object Timeline_1]
trace("after _mc1._mc2:"+_mc1._mc2);
//出力:after _mc1._mc2:null
trace("after mc:"+mc);
//出力:after mc:[object MovieClip]

trace("after numChildren:"+_mc1.numChildren);
//出力:after numChildren:1
trace("after getChildAt:"+_mc1.getChildAt(_mc1.numChildren-1));
//出力:after getChildAt:null

//nullでないmcが_mc2と同じと思いきや、そうでもない様子
mc.buttonMode = true;//マウスカーソルにならない

ちなみにこれはFlashPlayer9での書き出しの場合。
FlashPlayer10での書き出しの場合は、上記スクリプトのnullの部分が全部Mcとなる。
・・・が、元のMcを挿しているわけでは無いようで、最後のbuttonModeは適応されない。

だいぶAS3と戯れてきたと思ったはずなのに今始めてしった挙動。。。

Flash-JPに似たような内容の記事がありました。
http://www.flash-jp.com/modules/newbb/viewtopic.php?topic_id=8525&forum=20

[AS]ステージに配置したRadioButtonコンポーネントをRadioButtonGroupに反映させる方法

ちょっとだけハマってしまったのでメモ。

FlashIDE上でRadioButtonをステージに配置して、プロパティのパラメータからgroupNameを設定。
groupNameからRadioButtonGroupインスタンスを作りたい。

◆前提条件
ステージにラジオボタンを配置
プロパティgroupNameには、hogeという名前を設定

◆失敗例

var radioButtonGroup:RadioButtonGroup = new RadioButtonGroup("hoge");
trace(radioButtonGroup.numRadioButtons) //出力:0 (1と出て欲しい)

◆成功例

var radioButtonGroup:RadioButtonGroup = RadioButtonGroup.getGroup("hoge"); 
trace(radioButtonGroup.numRadioButtons) //出力:1 (想定どおり)

ステージに配置してあるRadioButtonのグループ名を取得するにはRadioButtonGroup.getGroup(“グループ名”)メソッドを使うってこと。
new RadioButtonGroup(“hoge”);は動的に生成したRadioButtonを紐付けたいときとかに使う、多分。

[iPhone]allocしてない変数はreleaseに注意

あるクラスでインスタンス変数でNSArrayを定義して、そのクラスインスタンスからNSArrayの変数にアクセスしようとするとKILLされるということがあった。
何がだめかといったら、allocしてないのに、releaseしてしまったということ。

以下、ダメだったコード。
UIViewを継承したHogeクラス

@synthesize hogeArray;
-(id)initWithFrame:(CGRect) frame {
    if ((self = [super initWithFrame:frame])) {
    }
    NSMutableArray* array = [NSMutableArray array];//←allocしてないから保持カウント増えてない
    [array addObject:@"hoge"];
   self.hogeArray = array;
    [array release];//←これがダメ
}

Hogeクラスを呼ぶUIViewを継承したFooクラス。

@synthesize hogehoge;
-(void)awakeFromNib{
   Hoge* hoge = [[Hoge alloc] initWithFrame:CGRectMake(0,0,10,10)];
   self.hogehoge = hoge;
    [hoge release];
    NSLog(@"hoge.arary : %@",hoge.hogeArray);//ここでは参照できる
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     NSLog(@"hoge.arary : %@",hoge.hogeArray);//ここでは参照できない
}

書籍のサンプルコードを眺めていた感じは、ローカル変数を作ってから、インスタンス変数に代入という流れが多かった。
ローカル変数をallocして初期化したときは、すぐにreleaseしてあげる流れだけど、allocしないで初期化するような場合は注意が必要なのね。

[Event]オブジェクト指向で考えるAS3勉強会をやりました

都内某所でワークショップやりました。

Flash初心者向けの内容で、
「Flashでのオブジェクト指向的な考え方とはなんぞや?」
という部分に的を絞って2時間ひたすらしゃべって喋りました。
自分的にはこの部分を理解するまでにかなりの時間を費やしたので、これで理解を早めるきっかけになれればいいなという思いでスライドを作りました。

本日のスライド
オブジェクト指向で考えるAS3
サンプルファイル
sample.zip

講義後のアンケートをみたかんじでは参加者12名の反応はまずまず。
まったくわからなかったという人が居なかったので一安心。
10人中、1人でも「そうだったのか」とおもってくれれば良いと思っていたけど、半分くらいの人が理解が深まったと書いてくれたのでやったかいがありました。
よかったよかった。

[AS]TextField.textにNumber型のデータをStringにキャストせずに入れる方法

通常テキストフィールドのtextプロパティにはString型のデータを入れなくてはならない。
以下のように書くとエラーとなるのは既知。

//FlashIDEでのメインタイムラインにダイナミックテキストを配置
//インスタンス名:_txt

//メインタイムラインフレームアクション
_txt.text = 1000;

1067: 型 int の値が、関連しない型 String に暗黙で型変換されています。

ここでエラーにならず代入できちゃうケースがあることに気付いた。
やりかたは簡単TextFieldをMovieClipでラップする。

//FlashIDEでのメインタイムラインにMovieClipを配置
//インスタンス名:_mc
//_mcのタイムラインにTextFieldを配置
//インスタンス名:_txt

//メインタイムラインのフレームアクション
_mc._txt.text = 1000;

これはエラーにならずにTextFieldにちゃんと文字が表示される。
ちょっと気持ちわるい。

[AS]TypeError: Error #1006: frame1 は関数ではありません。 at _fla::MainTimeline/frame1()、となった場合の対処方法

MovieClipにおいて、特定のフレームのフレームアクションを実行することができるメソッドがあります。
任意のフレームのスクリプトを実行:frame + “フレーム数” + ();

たとえば、ステージに_mcというインスタンス名でMovieClipが配置してある場合。
(_mcには1,2,3フレームにスクリプトが書いてある)
frame+フレーム数というメソッドを実行することができます。

//_mc:ステージに配置してあるMovieClipインスタンスで
//1,2,3フレームにスクリプトが書いてあり、内容は以下の通り
//1フレーム目には、trace("_mc 1フレーム");
//2フレーム目には、trace("_mc 2フレーム");
//3フレーム目には、trace("_mc 3フレーム");

_mc.frame1(); //出力:_mc 1フレーム
_mc.frame2(); //出力:_mc 2フレーム
_mc.frame3(); //出力:_mc 3フレーム

このとき以下のようなエラーが発生するときがある。

TypeError: Error #1006: frame1 は関数ではありません。
at _fla::MainTimeline/frame1()

このときの原因の一つは、実行対象のMovieClipにリンケージ指定されているということ。
リンケージ指定した状態で、任意のフレームのスクリプトを実行しようと上記のようなエラーになるらしい。

また、動的に生成したMovieClipインスタンスについても、addFrameScript()メソッドでフレームにスクリプトを追加した場合についても、同じ結果になるようす。

以下、例

var mc:MovieClip = new MovieClip();
addChild(mc);
//ムービークリップの1フレーム目にファンクション:testを追加
mc.addFrameScript(0,test);
function test():void{
	trace("mc script")
}
mc.frame1()//上記のようなエラーが発生する

ということは、動的に生成したmcにaddFrameScript()でファンクションを追加しても実行する術はないということ!?
まぁ理由はわからないけどそんな挙動をするみたい。
まぁ、こんなのそうそう使わないけども。