LAST UPDATE 1998/08/22


『 その11-4 』




 ■ ゲートの表示を追加する

image115.gif

 追加先はJmainF/General/Gameというサブルーチン内である。ボールの表示処理の前にコードを書く。
    If (GflipCount >= 0) Then
この変数の値は普段-1になっている。そしてボールがゲートを通過し終わると18が格納される。この部分はゲートを裏返しているとき以外は処理されない。
    If (GateNo = 20) Then
     ………・
    End If
この部分で動かすべきゲートの番号によって分岐し、実際に回転している。
    GflipCount = GflipCount - 1
次にタイマーイベントが発生した時のためにカウンターを1こ減らしている。この値が-1になった時点でこの部分のコードは処理されなくなる。


 ■ ボールがブロックを通過した時の処理

image113.gif
    If (Ba.count < 0) Then
ボールがブロックを通過し終わったということはBa.Countの値が-1になったときである。
    Ba.bx = Ba.bx + Int(Ba.vx + 0.5)
    Ba.bz = Ba.bz + Int(Ba.vz + 0.5)
 通過し終わったということは、次のブロックに乗り移るということであるから、ボールのブロック上での座標を管理しているBa.bxとBa.bzに新しい値を格納しなければならない。
 理論上はこの時点で、vxとvzには-1か0か+1のどれかが入っているはずである。しかし値は三角関数を使って計算される。角度をラジアンに変換する際にπであるべきところを3.14159という近似値を使って計算しているために、90度であるべきところが正確に90度でなかったりして、vxとvzには-1か0か+1に近いが正確にはちょっと違う数値が入っている場合がある。Ba.bxやBa.bzは配列の場所指定に使われる変数なので、値は整数でなければならない。
 そこでInt(Ba.vx + 0.5)という数式が使われる。これは古典的な四捨五入のテクニックで小数点以下1桁を四捨五入している。
 例えばBa.vxの値が0.49だったとしよう。0.49+0.5=0.99だからそのIntの値は0になる。ではBa.vxの値が0.51だったとした場合が0.51+0.5=1.01でIntの値は1になる。このようにして浮動小数点演算で発生した誤差を取り除いているのである。
    Ba.bno = BlockInfo(Ba.bx, Ba.bz, 1)
 上記の命令で得られた配列上での座標を元にボールが今乗っているブロックの番号を得ている。
    If (Ba.bno = -1) Then Call GovLoad: Exit Sub
 上の行で得たブロック番号が-1である場合は行き先がないということである。よってゲームオーバーの処理を呼び出している。
    Ba.Rdir = BdirConn(Ba.bno, Ba.Rdir)
 Ba.Rdirにはそのブロックの出口の進行方向(0~3)が格納されている。BdirConnという配列にはブロック番号と入ったときの進行方向を入れてやることにより、出口の進行方向が得られるようにデータを与えてある。
 これについては後で詳しく説明する。
    If (Ba.Rdir = -1) Then Call GovLoad: Exit Sub
 上の行で得た出口の方向の値が-1である場合は、やはり行き先がないということを意味しているのでゲームオーバーになる。
 どんな場合かというと、例えば5番のブロックは下と右にのみ出入り口を持っているが、このブロックに上や左から入ろうとしている場合などである。
pic_01.gif
    If (Ba.bno < 20) Then
      Ba.count = BCMax - 1
    Else
      Ba.count = BCMax * 2 - 1
    End If
通常ブロック(0~9)かゲート(20~23)であるかをチェックして、Ba.countの初期値を入れている。
    Call Rotate_R(Ball_ID, -BRANG * Ba.vz, 0, -BRANG * Ba.vx)
 ボールを回転させている。-BRANG*Ba.vzでXの回転角度を求めているわけだが、BRANGはJmainB/General/Decralationsで定数として値を定義されている。
    Public Const BRANG! = (2 / BCMax) / (0.8 * 3.14159!) * 360
 これは2というブロックの1枚分の距離をBCMAX回で渡りきる、そしてその直径は0.8でその円周を計算し、それを一回あたりの回転角に直している。実は玉の半径は0.35なので、円周の計算には0.7を使うのが本当なのだが、それだと回転が少し速すぎて転がっているように見えなかったので、少し大きめの数値を与えた。これも「それらしく見えるから良いんでないべか」方式である。
 X軸回転とは前後に回す回転である。ボールが手前から奥もしくはその逆に転がっている場合にボールの進行方向ベクトルであるBa.vzは1か-1になっているし、左右に転がっている場合は0が入っている。ボールが横に動いている場合に前後に回転してはいけない。ということで、X軸回転にはvzを掛け、Z軸回転にはvxを掛けてやればボールはちゃんと進行方向通りに回転するわけである。
    Call Move_A(Ball_ID, Ba.px, Ba.py, Ba.pz)
 ボールを移動させている。これは特に説明はいらないと思う。







その 11-1 | その 11-2 | その 11-3 | その 11-4 | その 11-5 | その 11-6

『 サルのゲーム製作講座 』 目次 | その 1 | その 2 | その 3 | その 4 |
その 5 | その 6 | その 7 | その 8 | その 9 | その 10 | その 11


もどる

e-mail: sc_3da@magical2.egg.or.jp