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


目次へ戻る

■SCRIPT考察2 「キーの複数同時押しを検出したい」


◆背景


Rigid Chipsが提供するユーザインタフェースの標準形はKEYブロックですが、KEYブロックは基本的にキーの押下を一つ一つ判定することしかできません。
KEYはデフォルト状態で16個が割り付けられていますが、通常はこれら全てを駆使するモデルは作られません。
恐らくは、殆どのユーザがキーボード操作を基本としているため、数多くのキー割付を行っても、それらを上手く使いこなせなかったり、直感的に判りやすいキー配置とならなかったりすることが理由として考えられます。
そこで、ユーザの中にはキーの複数同時押しで変数制御を行いたいという要求が発生することがあります。
ここでは、スクリプト初心者向けに、キーの複数同時押しを検出して、モデルの制御に用いる方法について紹介します。


◆考え方


キーの押下判定は、KEYブロックを用いる以外に、SCRIPTブロックやLUAブロック中で、関数「_KEY()」を用いることで判定可能です。
この関数「_KEY()」を駆使して、複数同時押しを検出します。
サンプルとして「Basic.txt」を使って、「Z+←」、「Z+→」と操作することで急ハンドルを切るように改造してみます。


◆実装


//BasicCar
Val
{
	Brake(default=0,min=0,max=80,step=80)
	HBrake(default=0,min=0,max=100,step=100)
	Handle(default=0,min=-20,max=20,step=5)
	Engine(default=0,min=-2500,max=2500,step=2500)
}
Key
{
	0:Engine(step=-500)
	1:Engine(step=500)
	2:Handle(step=-0.5)
	3:Handle(step=0.5)
	7:Brake(step=30),HBrake(step=20)
	8:HBrake(step=20)
}
Body {
	Core(){
		N:Chip(){
			N:Rudder(angle=Handle){
				W:Frame(){
					W:Wheel(angle=90,brake=Brake){
					}
				}
				E:Frame(){
					E:Wheel(angle=90,brake=Brake){
					}
				}
			}
		}
		S:Chip(){
			W:Frame(){
				W:Wheel(angle=90,power=Engine,brake=HBrake){
				}
			}
			E:Frame(){
				E:Wheel(angle=90,power=-Engine,brake=HBrake){
				}
			}
		}
	}
}
Script
{
if(_KEY(4)>0)&(_KEY(2)>0){ Handle=Handle-2 } if(_KEY(4)>0)&(_KEY(3)>0){ Handle=Handle+2 }
print 0,"Welcome to Rigid-Chips World." print 1," FPS=",_FPS()," Chips=",_CHIPS()," Weight=",_WEIGHT() print 2," Width=",_WIDTH()," Height=",_HEIGHT() print 3," Faces=",_FACE() print 4," Vel=",_VEL() print 5," R=",_RED(32,32) print 6," G=",_GREEN(32,32) print 7," B=",_BLUE(32,32) }
上記の青字箇所の記述を追加します。
まず関数「_KEY()」の動作についてですが、括弧の中にはキー番号を入れ、関数の戻り値が0ならばキーは押されていない、戻り値が1ならばキーが押されているということを表します。
デフォルト状態ならば、Zキーはキー番号4に割り付けられているので、「_KEY(4)」とすることで、Zキーの押下状態を判定することが出来ます。
従って、Zキーが押されているかいないかは、以下のように書くことで判定できるようになります。
if(_KEY(4)>0){
	[Zキーが押されている場合の動作]
	:
}
これでZキーの押下状態が判定できるようになります。
ここに←キーが押されているという条件を付け加えます。
Zキーが押されていて、かつ、←キーも押されている状態というのは、論理演算子「&」を用いて以下のように記述します。
if(_KEY(4)>0)&(_KEY(2)>0){
	[Zキーと←キーが同時に押されている場合の動作]
	:
}
Luaを用いて同じ機能を実装する場合は以下のように記述します。
Lua
{
function main()
	if(_KEY(4)>0)and(_KEY(2)>0) then
		HANDLE=HANDLE-2
	elseif(_KEY(4)>0)and(_KEY(3)>0) then
		HANDLE=HANDLE+2
	end
	out(0,"Welcome to Rigid-Chips World.")
	out(1,"  FPS=",_FPS(),"  Chips=",_CHIPS(),"  Weight=",_WEIGHT())
	out(2,"  Width=",_WIDTH(),"  Height=",_HEIGHT())
	out(3,"  Faces=",_FACE())
	out(4,"  Vel=",math.sqrt(_VX()^2+_VY()^2+_VZ()^2))
	out(5,"  R=",_RED(32,32))
	out(6,"  G=",_GREEN(32,32))
	out(7,"  B=",_BLUE(32,32))
end
}
※ Luaブロックの中に「function main() ・・・ end」を記述することを忘れないで下さい。
※ Luaブロックの中では「_VEL()」は使用できないので、その他の関数を用いて、計算で求めるようにしています。

なお、Luaブロックではユーザ関数が使用可能なので、以下のようにユーザ関数「key_and()」を定義することで、複数同時押し判定を行う新規関数を作ることが出来ます。
Lua
{
function key_and(k1,k2)
	local r=0
	if(_KEY(k1)>0)and(_KEY(k2)>0) then r=1 end
	return r
end

function main()
	if key_and(4,2)>0 then
		HANDLE=HANDLE-2
	elseif key_and(4,3)>0 then
		HANDLE=HANDLE+2
	end
	out(0,"Welcome to Rigid-Chips World.")
	out(1,"  FPS=",_FPS(),"  Chips=",_CHIPS(),"  Weight=",_WEIGHT())
	out(2,"  Width=",_WIDTH(),"  Height=",_HEIGHT())
	out(3,"  Faces=",_FACE())
	out(4,"  Vel=",math.sqrt(_VX()^2+_VY()^2+_VZ()^2))
	out(5,"  R=",_RED(32,32))
	out(6,"  G=",_GREEN(32,32))
	out(7,"  B=",_BLUE(32,32))
end
}

◆補足


上記の改造を施すと、Z+←/→とキーを押下した場合に、変数Handleが2.5度刻みで変化するようになります。
Scriptブロックでは「Handle=Handle-2」と書いているので、一見2度刻みで変化するように思われますが、KEYブロック内で←/→を押下した場合に0.5度刻みでHandleを増減させているため、この分の増減値が加算されて2.5度刻みとなります。
キーの押下を、KEYブロックとSCRIPT/LUAブロックの両方で検知し制御する場合は、それぞれのブロック内の制御結果が合算される点に注意してください。

目次へ戻る