Flash ActionScriptでクロージャ



使ってないと忘れそうなので、ひさしぶりにFlash のリハビリ。(ただしMXしか買って無いのでAS1) ついでに、昔、リファレンス読んでも判らなかったところも克服したい。

以下、チラシの裏。。。

クロージャ

とりあえず、面白そうなほうから。
Python始めてから憶えたクロージャをAS1でも使えるか調べてみる。

delete x,y
function f1(x){
   return function (y){ return x+y }
   //無名関数&関数のネスト
}
trace("global x="+x+" y="+y)
f3=f1(3)
trace("f3(1)="+f3(1)+"   f3(100)="+f3(100))

global x= y=
f3(1)=4 f3(100)=103

こんなことが出来るとは知りませんでした。
昔読んだ合気道の本に「他の武術も習ったほうがうまくなる」って書かれてましたけれども、そういうこともあるのかも。(おおげさ)

クロージャでジェネレータもどき

オセロの定石文字列を与えると、 呼び出すたびにx,y座標でひとつづつ返す関数を作成。妥当性チェックしてないです

function gkifu(kifu_str){
	var kifu_array=kifu_str.split("")
	var x0="a".charCodeAt(0)-1
	var y0="0".charCodeAt(0)
	var idx=0
	var idxend=length(kifu_array)/2
	return function(){
		ret=(idx<idxend) ? [kifu_array[idx].charCodeAt(0)-x0,					_	kifu_array[idx+1].charCodeAt(0)-y0] :undefined
		idx+=2 //演算できます
		return ret
	}
}
nezumi="f5f4e3f6d3" //子年だけにネズミ定石
g=gkifu(nezumi)
i<length(nezumi)/2
for( i=g(); i!=undefined; i=g()) trace("i="+i)

i=6,5 (以下略)
一手目は「f5」 だから、左から6マス目、上から5マス目

盤のふちにパディングがある、という想定なので座標は1からはじまります。ちょっと長いな。
avm2で動くPythonが有ったら便利やのに、と激しく思う私。作ってー adobe様

iter相当

Pythonの組込関数iter相当をクロージャで。

function iter(a_array){
  var idx=0
  var l=a_array.length
  return function(){
     return ((idx)<l) ?a_array[idx++] : undefined
  }
}
n=iter([0,1,2,3])
s=""
for(i=n(); i!=undefined; i=n()){
	s+=" "+i
}

n()を呼ぶたびに一個づつ返ってくる。終わるとundefinedを返す
(AS1は例外処理無いんで)

0 1 2 3

クロージャは全部ローカル変数だから、クラスで組むよりも名前解決が微妙に速いような気がする。

任意個の引数

function x(){
   trace("arguments="+arguments.join(", "))
}
x("a","b","c")

arguments=a, b, c

呼び出したい関数を文字列で与える

funcname="Math.sin"
trace(funcname+" pi/2 ="
   +eval(funcname).apply(null,[0.5*Math.PI]))

Function.applyの第一引数はthis。
Pythonでクラス外からメソッドを呼ぶときにself渡すようなものだと思っていただければ。 計算結果は

Math.sin π/2 =1


このへんからつまんなくなります。

値渡し

function f(x,y){ x=y }
a=1; b=2
f(a,b)
trace("a="+a)

数値、文字は関数側で操作しても影響を受けない

a=1

参照渡し

function f(a_array){
	for (i=0;i<a_array.length;i++){
		a_array[i]=i
	}
}
x_array=Array(10)
trace(x_array.join(","))
f(x_array)
trace(x_array.join(","))

Arrayは変更できる

,,,,,,,,,
0,1,2,3,4,5,6,7,8,9

変数の大文字小文字

AS1.0は同一視。 AS3.0以降は区別するはず
AS1.0はダックタイピング。AS2.0以降でダックタイピングやるとコンパイラに怒られる。IDEなら、できなくもないらしい

ブロック

トップレベルでは

delete a
trace("a="+a)
{ var a=100; trace("a="+a)}
trace("global a="+a)

a=300
global a=300

{}でくくっただけじゃブロックになってない。

関数の引数、ローカル変数

delete a; delete b
function f1(a){
   var b=a+1
   c="c"
   trace("arg a= "+a+ " local b="+b+ "local c="+c)
}
f1(100)
trace("global a="+a+" global b="+b+" global c="+c)

arg a=100 local b=101

global a= global b= global c=c

関数ならvar 宣言でローカル変数になる。var宣言しないとグローバル変数

オブジェクト(ムービークリップ)のプロパティへ配列風にアクセス

ステージにムービークリップm1_mcを作成して

trace(m1_mc._x==m1_mc["_x"])

trueが返ってきます。

m1_mc["_x"]=0

こんなふうに値を代入するのとムービークリップの位置が変化
何がうれしいのかといいますとー 
Movieクリップの動きをキューに入れておくときには、このほうが便利かな、と。


キューの作り方は、また今度。

Tags: ,

Related posts

タグ: ,

コメントは受け付けていません。