var col = blue;
col = blue;
DEF Sc Script {
eventIn SFTime colorChange
eventOut SFColor ballColor
field SFColor col 0 1 0 # 緑
field SFColor blue 0 0 1 # 青
url "javascript:
function initialize () {
col = blue;
}
function colorChange () {
ballColor = col;
}
"
}
initialize
関数の中の col
の前に var
を付けていました。
これは新規に col という名前のローカル変数を生成したことを意味します。
関数の中で var 宣言をして生成された変数はローカル変数となります。
ローカル変数はそれを生成した関数(この場合 initialize
関数)が終了すると破棄されます。
field
で定義した col
はグローバル変数扱いであり、ローカル変数が有効な範囲では影響を受けません。
その為、先の例では 0 1 0 (緑色)が colorChange
関数で ballColor
に代入されたのです。initialize
関数の中で var
宣言をしていません。
これは field
で定義したグローバル変数 col
への代入となります。 colorChange
関数では initialize
関数で代入された
blue
の値が ballColor
に代入される為、クリックすると青く変わるのです。
field SFColor col 0 1 0 # 緑
DEF Sc Script {
eventIn SFTime colorChange
eventOut SFColor ballColor
field SFColor blue 0 0 1 # 青
url "javascript:
function initialize () {
col = blue;
}
function colorChange () {
ballColor = col;
}
"
}
initialize
関数が終了しても破棄されないまま他の関数に値を引き継ぐことができます。initialize
関数で生成された 変数 col はローカル変数になり、この関数が終了すると破棄されます。
colorChange
関数で未定義変数 col
を ballColor
に代入しようとした為、エラーとなるのです。Cosmo | Cortona | Contact | |
---|---|---|---|
field もしくは eventOut で定義された変数 |
グローバル変数 | グローバル変数 | グローバル変数 |
関数内で var 宣言しないで生成された変数 |
グローバル変数 | グローバル変数 | ローカル変数 |
関数内で var 宣言して生成された変数 |
ローカル変数 | ローカル変数 | ローカル変数 |
field
で定義し、ローカル変数は関数内で var
宣言して生成するようにしてください。
field
を設定する際、同時に型を定義する必要がありますが、
その定義された変数に型が異なる値を代入するとどうなるか確かめてみましょう。
DEF Sc Script {
eventIn SFTime colorChange
eventIn SFTime translationChange
eventOut SFColor ballColor
eventOut SFVec3f boxTranslation
field SFColor col 0 1 0 # 緑
field SFColor blue 0 0 1 # 青
field SFVec3f vect 0 0 1
url "javascript:
function colorChange () {
col = vect;
ballColor = col;
}
function translationChange () {
var col = vect;
boxTranslation = col;
}
"
}
colorChange
関数が実行され、
右の黄色い箱をクリックすると translationChange
関数が実行されます。field
で定義されている blue
と vect
は値こそ同じ 0 0 1 ですが、それぞれ SFColor
と SFVec3f
という異なった型が設定されてます。colorChange
関数では変数 col
とは型が異なる vect
を代入しています。col
に vect
の値は代入されません。
field
もしくは eventOut
で定義した変数に代入する値は、型が同じである必要があります。SFString
で定義された変数に数値を代入すると、その数値は自動的に文字列に変わります。
SFInt32
型の変数に小数点以下が含まれた実数を代入すると、自動的に整数化されます。translationChange
関数はローカル変数 col に代入しています。field
で定義された値など
型が示されている値を JavaScript で扱う際は、以下のような型変換が行われます。
SFBool
( TRUE or FALSE ) → bool値 ( true or false )SFInt32, SFFloat, SFTime
→ 倍精度実数SFString
→ 文字列SFColor, SFVec3f, SFRotation
など → その型のフィールドオブジェクトcol
は SFColor
オブジェクト、vect
は SFVec3f
オブジェクトが値として入っている、といえます。
field
もしくは eventOut
で定義されている変数へのオブジェクトの代入は、「参照」ではなく「複写」が行われます。eventOut
で定義されている変数からスクリプト内で生成された変数への代入は「参照」で行われます。eventOut
で定義されているならば、この代入された変数値が、関数終了時にMF型オブジェクトの要素となってイベント出力されます。
DEF Sc Script {
eventIn SFTime touched_Ball
eventIn SFTime touched_Box
eventOut SFColor ballColor
eventOut SFColor boxColor
field SFColor black 0 0 0
field SFColor red 1 0 0
field SFColor col 0 1 1
url "javascript:
function initialize () {
ballColor = red;
}
function touched_Ball () {
// c0 is reference of ballColor.
var c0 = ballColor;
var b = c0.b;
c0.b = c0.g;
c0.g = c0.r;
c0.r = b;
// c0 is reference of black.
c0 = black;
}
function touched_Box () {
// c1 is reference of col.
var c1 = col;
// boxColor is copy of c1.
boxColor = c1;
var b = c1.b;
c1.b = c1.g;
c1.g = c1.r;
c1.r = b;
print( 'boxColor = ' + boxColor );
print( 'col = ' + col );
}
"
}
touched_Ball
関数において、最初のc0 = ballColor;
ballColor
の「参照」となります。
よって、それ以降 c0 を操作すると ballColor
は c0 と同じ値になります。
但し、c0 = black;
black
の「参照」となりますので、ballColor
も黒くなるようなことはありません。touched_Box
関数において、c1 = col;
col
の「参照」となります。
しかし、その次のboxColor = c1;
boxColor
に「複写」されます。
boxColor
は c1 の「参照」ではありません。
以降 c1 を操作すると col
も同じ値になりますが、boxColor
は影響を受けません。
col
の内容は次回の関数実行時に boxColor
に値が引き継がれます。