Category Archive: ActionScript

[AS]if文の条件式の中には代入式も書ける

例えば、

//フレームアクション
var n:Boolean = true;
stage.addEventListener(MouseEvent.CLICK, xClick);
function xClick(e:MouseEvent):void {
n = !n;
	if (n) {
		trace("true:"+n);
	} else {
		trace("false:"+n);
	}
}

↑を↓のように書いても同じこと。

var n:Boolean = true;
stage.addEventListener(MouseEvent.CLICK, xClick);
function xClick(e:MouseEvent):void {
	if (n = !n) {
		trace("true:"+n);
	} else {
		trace("false:"+n);
	}
}

[AS][?→ok]スコープがよくわからない・・・

スコープがあってないと思うのだけど理屈がよくわからない・・・

例えば、こんなカスタムイベントはOK
(ステージに_mc1インスタンスを配置)

//////////
//フレームアクション

import mx.events.EventDispatcher;
import mx.utils.Delegate;

var frog1:Object = new Object();
EventDispatcher.initialize(frog1);
	function passPoint(eventObj:Object):Void {
		trace(eventObj.child);
	}
	frog1.addEventListener("passPoint",this);

_mc1.onRelease = function() {
	trace("on");
	trace("this;"+this);
	var testObj:test2 = new test2(frog1);
};

//////////
//カスタムクラス(test2.as)

class test2 {
	var childID = 300;
	var frog1:Object;
	public function test2(frog1) {
		this.frog1 = frog1;
		tat();
	}
	function tat() {
		frog1.dispatchEvent({type:"passPoint", child:childID});
	}	
}

//////////
でもこれを以下のようにフレームアクションを変えるとイベントが受信できない。

//////////

import mx.events.EventDispatcher;
import mx.utils.Delegate;

var frog1:Object = new Object();
EventDispatcher.initialize(frog1);

_mc1.onRollOver = Delegate.create(this, testOver);
function testOver() {
	trace("this:"+this);
	function passPoint(eventObj:Object):Void {
		trace(eventObj.child);
	}
	frog1.addEventListener("passPoint",this);
};

_mc1.onRelease = function() {
	trace("on");
	trace("this;"+this);
	var testObj:test2 = new test2(frog1);
};

function testOverは委譲しているので、this参照は_lovel0になっているのに。
・・・何か別の問題があるのだろうか?

/////////////////////////////////////
12/5 追記
理解しました。
function内にfunctionが入っているとそれはローカル変数的なfunctionになるのだそう。
(passPointがtestOverに含まれてしまっているということ)
this参照が_lovel0でもグローバル的な関数にはなりえないってことらしい。

つまり・・・
////////////////////////
//これはtraceできないけど。。。

var test:Function;
function main(){
	//test = test();
	function test(){
		trace("a");
	};
}
main();
test();

////////////////////////
//これならできる、みたいな

var test:Function;
function main(){
	test = test();
	function test(){
		trace("a");
	};
}
main();
test();

[AS]委譲する際に引数を持たせる方法

参考サイト
http://katapad.com/wp/2008/05/25/study_as2_delegate_create/

Delegate.asを以下のように書き換える。

static function createWithArgs(obj:Object, func:Function, args:Array):Function//args:Arrayを追加
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments.callee.args.concat()); //ここを追加
	};

	f.target = obj;
	f.func = func;
	f.args = args; //ここを追加
	return f;
}

配列で引数を渡せるみたい。
ただし、配列として色んな値を格納して、それを取り出すなんてことはできないみたい。

例えば、ステージに_mcというインスタンスをおいた状態で、

import mx.utils.Delegate;
var tstArray:Array = new Array();
tstArray.push(100);
tstArray.push(200);
_mc.onRollOver =  Delegate.create(this, onRollOverTest,tstArray);
function onRollOverTest(x){
trace("delegate+"+x);//出力:100
}

これでは値はunderfinedになってしまった。

import mx.utils.Delegate;
var tstArray:Array = new Array();
tstArray.push(100);
tstArray.push(200);
_mc.onRollOver =  Delegate.create(this, onRollOverTest,tstArray[0]);
function onRollOverTest(x){
trace("delegate+"+x);//出力:100
}

[AS]EventDispatcherでイベント配信

AsBroadcasterでのイベント配信との使い分けがよくわからんです。
イベントオブジェクトにプロパティがもてるのでより柔軟に使えるってことかしら。

//EventDispatcherにパスを通す
import mx.events.EventDispatcher;

//ブロードキャスターとなるオブジェクトを作成
var casterObj:Object = new Object();
//ブロードキャスター(イベントをdispatchする人)に登録する
EventDispatcher.initialize(casterObj);

//リスナーとなるオブジェクトを作成
var listenerObj:Object = new Object();

//リスナーオブジェクトにメソッド(リスナーメソッド)を定義
listenerObj.eventComp = function(e:Object){
	trace("end");
	//イベントオブジェクトのプロパティを参照できる
	trace("target:"+e.type);//出力:target:eventComp
}

//リスナーオブジェクトとイベントをブロードキャスターのリスナーとして登録
casterObj.addEventListener("eventComp",listenerObj);

//ブロードキャスターがイベント”eventComp”イベントを配信する。
//dispatchEvent(eventObject)
//eventObjectはtypeプロパティにイベント名のStringを持たなければ駄目
casterObj.dispatchEvent({type:"eventComp"});

[AS]AsBroadcasterでイベント配信

AsBroadcasterでイベントを配信できる。
EventDispatcherとの違いがよくわからないのだが・・・
下記のような順番で書いていくこと。

//ブロードキャスターとなるオブジェクトを作成
var casterObj:Object = new Object();
//ブロードキャスターに登録する
AsBroadcaster.initialize(casterObj);

//リスナーとなるオブジェクトを作成
var listenerObj:Object = new Object();

//リスナーオブジェクトにメソッド(リスナーメソッド)を定義
listenerObj.eventComp = function(){
	trace("end");
}
listenerObj.eventComp1 = function(){
	trace("end1");
}


//リスナーオブジェクトをブロードキャスターのリスナーとして登録
casterObj.addListener(listenerObj);

//ブロードキャスターがイベント”eventComp”を配信する。
casterObj.broadcastMessage("eventComp");

//ブロードキャスターがイベント”eventComp”を配信する。
casterObj.broadcastMessage("eventComp1");

[AS]委譲について

委譲という言葉自体よくわからんが、こんなことらしい。

as2での例
ステージに_mcというMCがあり、メインのタイムラインのフレームアクション

_mc.onEnterFrame = xEnterFrame;
function xEnterFrame(){
trace(this)
}
//出力_level0._mc

ここでthisを他のものに変えたい時には以下のように書く

_mc.onEnterFrame = Delegate.create(this.xEnterFrame);
function xEnterFrame(){
trace(this)
}
//出力_level0

Delegate.create(第一引数.第二引数);
第一引数でスコープオブジェクトを指定できる。

[AS]オブジェクトの変数名をfor文で回せるの?

どうやればいいのだろう。
これだと、nullになっちゃう。
配列につっこんで管理するしかないのか?

for(var i:uint = 0; i<3;i++){
	var sh0:Sprite;
	var sh1:Sprite;
	var sh2:Sprite;
	
	var sp:Shape = "sh"+i  as Shape;
	sp = new Shape();
	var spg = sp.graphics;
	
	spg.lineStyle(5,0xff0000,1,true);
	spg.moveTo(0,0);
	spg.curveTo(100,100,i*50,200+i*10);
	spg.endFill();
	
	addChild(sp);
}
trace(sh1);//nullになる

///////////////////////////////////////
//12/5 追記
//根本的に書き方がおかしかった
//これなら参照できるけど、sh0,sh1,sh2の定義がfor文で重複してる。。。
//もう少しマシな書き方がありそう・・・

for(var i:uint = 0; i<3;i++){
	var sh1:Shape;
	var sh2:Shape;
	var sh0:Shape;
	
	var sp:Shape = new Shape();
	this["sh"+i] = sp
	var spg = sp.graphics;
	
	spg.lineStyle(5,0xff0000,1,true);
	spg.moveTo(0,0);
	spg.curveTo(100,100,i*50,200+i*10);
	spg.endFill();
	
	addChild(sp);
}
trace(sh1)

[AS]PV3Dのオブジェクトの上に2DのMovieCLipをのっける

偉人たちのTwitterの会話をメモ・・・
>PV3Dのオブジェクトのピッタリ狙った位置とサイズに2Dのムービークリップを重ねる技術
>Camera3D の focus * zoom がちょうどスクリーン座標と 3D 座標が一致する距離
>DisplayObject3D に screen てプロパティ。screen 座標。
>逆にDisplayObjectをScreen座標にあわせられます。
>autoCalcScreenCoords を true にしとかないと計算してくれいないぽい。

2009/5/31追記
具体的には、こんな設定でちょうど縦横100%で表示されるようす。

camera = new Camera3D();
camera.z = -1000;
camera.focus = 1000;
camera.zoom = 1;

[AS]フレームアクションを使った時間の調整

///////////////
//AS2の場合

stop();
var waitTime:Number = 500;
//待ち時間関数
function WaitTime() {
	clearInterval( WaitTimeId );
	play();
}
//waitTime秒間停止させる
WaitTimeId = setInterval(WaitTime, waitTime);

///////////////
//AS3の場合

stop();
var waitTime:Number = 1000;
var wt:Timer = new Timer(waitTime);
wt.addEventListener(TimerEvent.TIMER, WaitTime);
wt.start();
//待ち時間関数
function WaitTime(e:TimerEvent):void {
	play();
}

[AS]ステージサイズの取得について

ステージサイズを小さくすると、stage.stageWidth(Height)で正しい値が返ってこないときがある。

例(FlashCS3 AS3)
Flash上でステージサイズを200×200に設定。
ステージ上にダイナミックテキストをtfという名前で配置。

tf.text = String(stage.stageHeight);

上記スクリプトを書いてムービープレビューすると、181と表示される。
ただしパブリッシュした状態ではちゃんと200と表示される。

つまりムービープレビューでの表示がバグっぽいので気にしなくてよし。