注: このページで作るゲームは macOS High Sierra で不具合が出るようです。原因を調べています。
これからポン・ゲーム(PONG)を作ります。もっと効率良くスマートな方法もあかもしれませんが、今まで学んだ基礎的な知識をもう少し発展させた、対戦相手のいない単純なインターラクティブなアニメーションです。このページで作るスタックはこのビデオのようになります。
command moveGrc pItem1, pItem2
repeat forever -- ゲームセットまでリピートを繰り返す
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
-- wait 10 ticks この行を削除する
end repeat
end moveGrc
「get」は「put」と似ていますが、ある値(value)をいつでも「it」に収納します。感覚的には「it」という自分に、取り込むという感じでしょうか。「put」はそれに対して、ある対象物に値を入れる感じです。上に書いた「get (-2, 2) 」では「it」の中身は「-2, 2」になります。この「it」にある2つのアイテム(カンマで繋がれた項目)
からどちらかの値をランダム(無作為)に選び出すのに、「any item of it (itに収納されているどちらかの項目)」を使います。「get」で「it」に値(-2,2)を取り込む処から始めから書きます。「it」からランダムに選び出した値は「put」を使って「tX」と「tY」に入れます。
get (-2, 2)
put any item of it into tX -- -2 か +2 のどちらかが tX に収納される
put any item of it into tY -- -2 か +2 のどちらかが tY に収納される
カードに書きこむカスタム・コマンド「moveGrc」の全部を書いてみます。
command moveGrc -- pItem1, pItem2 パラメータは必要ないので削除する
get (-2, 2)
put any item of it into tX -- it に収納されているどちらかのアイテムを tX に入れる
put any item of it into tY -- it に収納されているどちらかのアイテムを tY に入れる
repeat forever
set the loc of grc 1 to item 1 of the loc of grc 1 + tX, \
item 2 of the loc of grc 1 + tY -- pItem1, pItem2 は tX とtY に変える
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
end repeat
end moveGrc
switch tX,tY -- tX,tY に何が入っているか
case 2,2 -- tX,tY が 2,2 の場合
put -2 into tX
put 2 into tY
break -- 該当するものが見つかったらswitch から抜ける
case -2,2 -- tX,tY が -2,2 の場合
put -2 into tX
put -2 into tY
break -- 該当するものが見つかったらswitch から抜ける
case 2,-2 -- tX,tY が 2,-2 の場合
put 2 into tX
put 2 into tY
break -- 該当するものが見つかったらswitch から抜ける
case -2,-2 -- tX,tY が -2,-2 の場合
put 2 into tX
put -2 into tY
break -- 該当するものが見つかったらswitch から抜ける
end switch
-- スウィッチを出たところで tX と tY は新しい値になっている
上に書いたカードに書きこむカスタム・コマンド「moveGrc」全文にこの「switch」を書き込みますが、ボールがスタックのエッジにバウンスして方向を変えて、動きが中断されないで更に進んで行くように、「send mouseUp to btn "reset"」と「exit repeat」は削除します。まだこれはテストなので、いつでも「shiftKey シフトキー」を押した時にボールの進行がストップするスクリプトも加えておきます。
command moveGrc
get (-2, 2)
put any item of it into tX
put any item of it into tY
repeat forever
if the shiftKey is down then exit to top
-- もしシフトキーが押されたら すべてのスクリプトから抜ける(exit to top)
-- ボールがストップする
set the loc of grc 1 to item 1 of the loc of grc 1 + tX, \
item 2 of the loc of grc 1 + tY
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
beep
-- send mouseUp to btn "reset" 削除する
-- exit repeat 削除する
switch tX,tY
case 2,2
put -2 into tX
put 2 into tY
break
case -2,2
put -2 into tX
put -2 into tY
break
case 2,-2
put 2 into tX
put 2 into tY
break
case -2,-2
put 2 into tX
put -2 into tY
break
end switch
end if
end repeat
end moveGrc
グラフィック「ball ボール」がボタン「ブロック」にぶつかったら、スタックのエッジにぶつかったようにバウンスするスクリプトを追加して行きます。グラフィック「ボール」が下にある「ブロック」にぶつかるのはボールの「bottomRight 」と「bottomLeft」ですから、このどちらかが「the rect of btn "block" ボタン『ブロック』の矩形」の「within 中」にあるかをチェックするスクリプトを、グラフック「ボール」がバウンスする時の条件に「or」でつないで書き加えます(下に書いたスクリプトの赤字の部分を追加します)。
if the topLeft of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is within the rect of btn "block" or \
the bottomLeft of grc "ball" is within the rect of btn "block" then
beep
switch tX,tY -- が続く
case .....
end switch
end if
ボタン「block ブロック」を左右に移動させるスクリプトが必要です。マウスが動いた時天地には動かないで、左右だけ動くようにします。「the mouseLoc」でマウスのロケーション(XY座標)を得ることができますから、Y座標はボタン「block ブロック」そのまま、X座標(item 1 of the mouseLoc)だけ移動するようにしました。
set the loc of btn "block" to item 1 of the mouseLoc, item 2 of the loc of btn "block"
このスクリプトを「repeat forever」の中の始めの行に書き加えます。もうひとつボールがスタックの一番下に到達した時に、ゲームオーバーになるスクリプトを加えます。ゲームオーバーは、グラフィック「ボール」の動きをストップさせてカードの中央に戻し、ボタン「ブロック」もマウスの動きから外して始めの位置に戻すようにします。グラフィック「ボール」がスタックの底に触れたのを知るにはグラフィック「ボール」の「item 2 of the bottomLeft(または bottomRight)」がカードの高さと同じか越えていれば良いわけです。
if item 2 of the bottomLeft of grc "ball" >= the height of this cd then
set the loc of btn "block" to \
item 1 of the width of this card div 2, item 2 of the loc of btn "block"
set the loc of grc "ball" to the loc of this cd
exit repeat
command moveGrc
get (-2, 2)
put any item of it into tX
put any item of it into tY
repeat forever
set the loc of btn "block" to \
item 1 of the mouseLoc, item 2 of the loc of btn "block"
if the shiftKey is down then exit to top
set the loc of grc "ball" to item 1 of the loc of grc "ball" + tX, \
item 2 of the loc of grc "ball" + tY
if item 2 of the bottomLeft of grc "ball" >= the height of this cd then
beep
set the loc of btn "block" to \
item 1 of the width of this card div 2, item 2 of the loc of btn "block"
set the loc of grc "ball" to the loc of this cd
exit repeat
else -- 上にif文を追加したので、次の条件を書き込む前に「else もしくは」を書く
if the topLeft of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is within the rect of btn "block" or \
the bottomLeft of grc "ball" is within the rect of btn "block" then
beep
switch tX,tY
case 2,2
put -2 into tX
put 2 into tY
break
case -2,2
put -2 into tX
put -2 into tY
break
case 2,-2
put 2 into tX
put 2 into tY
break
case -2,-2
put 2 into tX
put -2 into tY
break
end switch
end if
end if --「if文」を追加したので最後に「end if」で追加した条件を閉じる
end repeat
end moveGrc
create btn "ballSpeed"
set the style of btn "ballSpeed" to "menu"
set the menuMode of btn "ballspeed" to "option"
set the text of btn "ballSpeed" to "ゆっくり" & cr & "少し早く" & cr & "もっと早く"
command moveGrc
if the label of btn "ballSpeed" is "ゆっくり" then
put 2 into tSpeed -- 2ピクセルのスピード
else if the label of btn "ballSpeed" is "少し早く" then
put 6 into tSpeed -- 6ピクセルのスピード
else -- それ以外 3つの選択なので書かなくても"もっと早く"
put 10 into tSpeed -- 10ピクセルのスピード
end if
get (-tSpeed, tSpeed) -- 上で取得した値がtSpeedに入っている
put any item of it into tX
put any item of it into tY
repeat forever
set the loc of btn "block" to \
item 1 of the mouseLoc, item 2 of the loc of btn "block"
if the shiftKey is down then exit to top
set the loc of grc "ball" to item 1 of the loc of grc "ball" + tX, \
item 2 of the loc of grc "ball" + tY
if item 2 of the bottomLeft of grc "ball" >= the height of this cd then
beep
set the loc of btn "block" to \
item 1 of the width of this card div 2, item 2 of the loc of btn "block"
set the loc of grc "ball" to the loc of this cd
exit repeat
else
if the topLeft of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is not within the rect of this cd or \
the bottomRight of grc "ball" is within the rect of btn "block" or \
the bottomLeft of grc "ball" is within the rect of btn "block" then
beep
switch tX,tY
case tSpeed,tSpeed -- どちらもプラスの値
put -tSpeed into tX
put tSpeed into tY
break
case -tSpeed,tSpeed -- tXがマイナス tYがプラスの値
put -tSpeed into tX
put -tSpeed into tY
break
case tSpeed,-tSpeed -- tXがプラス tYがマイナスの値
put tSpeed into tX
put tSpeed into tY
break
case -tSpeed,-tSpeed -- どちらもマイナスの値
put tSpeed into tX
put -tSpeed into tY
break
end switch
end if
end if
end repeat
end moveGrc