Rigid Chips リファレンスマニュアル モデルデータ SCRIPT考察3-1


目次へ戻る

■SCRIPT考察3-1 「飛行機の製作:ワンタッチギアアップ/ダウン」


◆考え方


飛行機のランディングギア(タイヤ)をボタン1つで上げ下げします。
1つのボタンでいろいろな動きをさせる場合に、基本となる考え方が「状態遷移」です。
別の表現で「モード切替」と言った方が分かりやすいかもしれません。(以後、この表現を用います。)

モード切替を実現するにあたっては、まずモードが幾つあるかを定義する必要があります。
ギアの上げ下げについては、「ギアダウンモード」と「ギアアップモード」の2つのモードを定義します。
(厳密には、「ギアを上げきって止まっているモード」と「ギアを下げきって止まっているモード」のあと2つのモードがありますが、この2つのモードについては変数の上限値・下限値で制約することで、前の2つのモードに集約することができます。)

モード切替を行うには、現在がどのモードになっているかを記録(管理)する必要があるので、モード切替変数を設けます。
ここでは、モード切替変数が0のときをギアダウンモード、1のときをギアアップモードと定義します。
(勿論、定義は自由に行って構いませんが、あまり特殊な定義を行うと、スクリプトを組みにくくなってしまうので、なるべくシンプルな定義とするようにしましょう。)
スクリプトでは、最初にモード切替変数を参照し、その値が0であったらギアダウンを行い、1であったらギアアップを行うように動作させます。


◆実装


//plane
val{
	pitch(default=0,min=-10,max=10,step=1,disp=1)
	roll(default=0,min=-10,max=10,step=1,disp=1)
	yaw(default=0,min=-10,max=10,step=1,disp=1)
	jet(default=0,min=0,max=50000,step=0,disp=1)
gear_angle(default=80,min=80,max=170,step=0,disp=1) mode(default=0,min=0,max=1,step=0,disp=1)
} key{ 0:pitch(step=-1) 1:pitch(step= 1) 2:roll(step= 0.5) 3:roll(step=-0.5) 4:yaw(step=-1) 6:yaw(step= 1) 5:jet(step= 50000) 8:jet(step=-50000)
9:mode(step=1)
} body{ core(){ n:frame(angle=-20){ n:jet(angle=110,power=jet,effect=1){} } w:chip(){ w:trim(angle=roll){ w:chip(){} } } e:chip(){ e:trim(angle=roll){ e:chip(){} } } s:chip(){ s:chip(){ s:chip(){ w:chip(angle=-90){ s:chip(angle=-yaw){} } e:chip(angle=-90){ s:chip(angle=yaw){} } s:chip(){ w:trim(angle=pitch){} e:trim(angle=-pitch){} } } } } w:frame(angle=10){ w:wheel(angle=gear_angle){} } e:frame(angle=10){ e:wheel(angle=gear_angle){} } } } Lua{
function gear_updown() if(MODE==0) then GEAR_ANGLE=GEAR_ANGLE-5 -- ギアダウン else GEAR_ANGLE=GEAR_ANGLE+5 -- ギアアップ end end
function main()
gear_updown()
-- 表示 out(0,"Up/Down:Pitch, Left/Right:Roll, Z/C:Yaw, X:Jet-On, D:Jet-Off") out(1,"x=",_X(0),", y=",_Y(0),", z=",_Z(0)) out(2,"ax=",math.deg(_AX(0)),", ay=",math.deg(_AY(0)),", ez=",math.deg(_EZ(0))) out(3,"vx=",_VX(0),", vy=",_VY(0),", vz=",_VZ(0)) out(4,"wx=",_WX(0),", wy=",_WY(0),", wz=",_WZ(0)) end }
上記では、モード切替変数"MODE"を定義し、Dキーを押すことでMOE=0→MODE=1へと切り替えるようにしています。
実際のギアの上げ下げは、変数GEAR_ANGLEの値を変化させ、WHEELの接続角度を変化させます。
MODE=0のときはGEAR_ANGLEを5度刻みで減らし、MODE=1のときはGEAR_ANGLEを5度刻みで増やします。
しかし、この状態だと、MODEの切替をKEYブロックで行っているため、MODE=0→MODE=1への切り替えしか出来ず、上げたギアを再び下げることが出来ません。
かといって、
	mode(default=0,min=0,max=1,step=1,disp=1)
このようにしてしまうと、Dキーを押している間しか、ギアが上がった状態になりません。
そこで、キーを1回押すごとにモードを切り替えるようにするには、モード切替変数をKEYブロックではなく、スクリプトで制御してやる必要があります。
(なお、このような切替制御を実現する方法は複数あります。ここでは、あくまで一例を紹介します。)
//plane
val{
	pitch(default=0,min=-10,max=10,step=1,disp=1)
	roll(default=0,min=-10,max=10,step=1,disp=1)
	yaw(default=0,min=-10,max=10,step=1,disp=1)
	jet(default=0,min=0,max=50000,step=0,disp=1)
	gear_angle(default=80,min=80,max=170,step=0,disp=1)
	mode(default=0,min=0,max=1,step=0,disp=1)
}

key{
	0:pitch(step=-1)
	1:pitch(step= 1)
	2:roll(step= 0.5)
	3:roll(step=-0.5)
	4:yaw(step=-1)
	6:yaw(step= 1)
	5:jet(step= 50000)
	8:jet(step=-50000)
// 9:mode(step=1)
} body{ core(){ n:frame(angle=-20){ n:jet(angle=110,power=jet,effect=1){} } w:chip(){ w:trim(angle=roll){ w:chip(){} } } e:chip(){ e:trim(angle=roll){ e:chip(){} } } s:chip(){ s:chip(){ s:chip(){ w:chip(angle=-90){ s:chip(angle=-yaw){} } e:chip(angle=-90){ s:chip(angle=yaw){} } s:chip(){ w:trim(angle=pitch){} e:trim(angle=-pitch){} } } } } w:frame(angle=10){ w:wheel(angle=gear_angle){} } e:frame(angle=10){ e:wheel(angle=gear_angle){} } } } Lua{
function mode_change() local k=_KEY(9) -- Dキーの状態 if(k>0)and(key9==0) then -- 現在Dキー押下され、前フレームで押されていない場合 if(MODE==0) then MODE=1 -- ギアダウンモード else MODE=0 -- ギアアップモード end end key9=k -- Dキー押下状態を記憶する end
function gear_updown() if(MODE==0) then GEAR_ANGLE=GEAR_ANGLE-5 -- ギアダウン else GEAR_ANGLE=GEAR_ANGLE+5 -- ギアアップ end end function main()
mode_change()
gear_updown() -- 表示 out(0,"Up/Down:Pitch, Left/Right:Roll, Z/C:Yaw, X:Jet-On, D:Jet-Off") out(1,"x=",_X(0),", y=",_Y(0),", z=",_Z(0)) out(2,"ax=",math.deg(_AX(0)),", ay=",math.deg(_AY(0)),", ez=",math.deg(_EZ(0))) out(3,"vx=",_VX(0),", vy=",_VY(0),", vz=",_VZ(0)) out(4,"wx=",_WX(0),", wy=",_WY(0),", wz=",_WZ(0)) end }
上記ではDキーを1回押すごとにMODEの値が0と1とで切り替わります。
MODEの値をスクリプトで制御するため、KEYブロックの該当記述はコメントアウトしておきます。(削除しても構いません。)
ここでポイントとなるのは、Dキーを押している間に、MODEの値が0→1→0→・・・というように連続で切り替わってしまわないようにすることです。
Dキーを1回押したら、1回だけMODEの値が変わるようにするために、1フレーム前のDキーの押下状態を参照しています。
1フレーム前のDキーの押下状態は、直接関数によって参照することが出来ないので、グローバル変数"key9"に_KEY(9)の値を記憶しておき、次のフレームでこの値を参照することとしています。
MODEの値を切り替える条件として、「Dキーが押されていない状態から押された状態になったとき」としています。
この条件判定を行っている部分が、「if(k>0)and(key9==0) then」の箇所となっています。

目次へ戻る