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 に値が引き継がれます。