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」の箇所となっています。
目次へ戻る