チェックポイント 武器の発射ができたら今度は当たり判定です。 今回のゲームは敵キャラや武器キャラがキャラクタ単位で移動し表示されています。 表示に関しては実際には小数部を持つ実数での移動なんですが表示座標が整数なので小数部分が切り捨てられています。 この場合の当たり判定は敵と武器の位置が一致しているかを判断すればいいのです。
|
| ■プログラム |
0001 ' initialize 0002 GOSUB @SYS_INI 0003 GOSUB @PLY_INI 0004 GOSUB @WPN_INI 0005 GOSUB @UFO_INI 0006 ' game loop 0007 @LOOP 0008 GOSUB @SYS_MAIN 0009 ' task 0010 GOSUB @PLY_TASK 0011 GOSUB @WPN_TASK 0012 GOSUB @UFO_TASK 0013 GOTO @LOOP 0014 ' 0015 ' system 0016 ' 0017 @SYS_INI 0018 SYS_CNT = 0 0019 RETURN 0020 ' 0021 @SYS_MAIN 0022 VSYNC 1 0023 CLS 0024 SYS_CNT = SYS_CNT + 1 0025 SYS_KEY = BUTTON() 0026 RETURN 0027 ' 0028 ' UFO task 0029 ' 0030 @UFO_INI 0031 UFO_SX = 0.1 0032 UFO_F = 0 0033 UFO_CNT = 60 0034 RETURN 0035 ' 0036 @UFO_TASK 0037 ON UFO_F GOTO @UFO_WAIT,@UFO_MVR,@UFO_MVL 0038 STOP 0039 ' 0040 @UFO_WAIT 0041 UFO_CNT = UFO_CNT + 1 0042 IF UFO_CNT > 0 THEN RETURN 0043 GOTO @UFO_RSET 0044 ' move right 0045 @UFO_MVR 0046 LOCATE UFO_X, 0 0047 PRINT "A" 0048 UFO_X = UFO_X + UFO_SX 0049 IF UFO_X > 32 GOTO @UFO_LSET 0050 HITX = UFO_X 0051 HITY = 0 0052 GOSUB @WPN_HITC 0053 IF HITF GOTO @UFO_DETH 0054 RETURN 0055 ' 0056 @UFO_LSET 0057 UFO_X = 31 0058 UFO_F = 2 0059 RETURN 0060 ' move left 0061 @UFO_MVL 0062 LOCATE UFO_X, 0 0063 PRINT "A" 0064 UFO_X = UFO_X - UFO_SX 0065 IF UFO_X < 0 GOTO @UFO_RSET 0066 HITX = UFO_X 0067 HITY = 0 0068 GOSUB @WPN_HITC 0069 IF HITF GOTO @UFO_DETH 0070 RETURN 0071 ' 0072 @UFO_RSET 0073 UFO_X = 0 0074 UFO_F = 1 0075 RETURN 0076 ' 0077 @UFO_DETH 0078 UFO_F = 0 0079 UFO_CNT = 60 0080 RETURN 0081 ' 0082 ' player task 0083 ' 0084 @PLY_INI 0085 PLY_X = 15 0086 PLY_SX = 0.5 0087 PLY_F = 0 0088 RETURN 0089 ' 0090 @PLY_TASK 0091 LOCATE PLY_X,21 0092 PRINT "P" 0093 IF SYS_KEY AND 16 THEN GOSUB @WPN_FIRE 0094 ON PLY_F GOTO @PLY_STOP,@PLY_MVR,@PLY_MVL 0095 STOP 0096 ' stop 0097 @PLY_STOP 0098 IF SYS_KEY AND 8 GOTO @PLY1 0099 IF SYS_KEY AND 4 GOTO @PLY2 0100 RETURN 0101 @PLY1 0102 PLY_F = 1 0103 RETURN 0104 @PLY2 0105 PLY_F = 2 0106 RETURN 0107 ' move right 0108 @PLY_MVR 0109 PLY_X = PLY_X + PLY_SX 0110 IF PLY_X > 31 THEN PLY_X = 31 0111 IF SYS_KEY AND 8 THEN RETURN 0112 PLY_F = 0 0113 RETURN 0114 ' move left 0115 @PLY_MVL 0116 PLY_X = PLY_X - PLY_SX 0117 IF PLY_X < 0 THEN PLY_X = 0 0118 IF SYS_KEY AND 4 THEN RETURN 0119 PLY_F = 0 0120 RETURN 0121 ' 0122 ' weapon task 0123 ' 0124 @WPN_INI 0125 WPN_F = 0 0126 WPN_SY = 0.5 0127 RETURN 0128 ' 0129 @WPN_TASK 0130 ON WPN_F GOTO @WPN_WAIT,@WPN_MOVE 0131 STOP 0132 ' 0133 @WPN_WAIT 0134 RETURN 0135 ' 0136 @WPN_MOVE 0137 LOCATE WPN_X,WPN_Y 0138 PRINT "!" 0139 WPN_Y = WPN_Y + WPN_SY 0140 IF WPN_Y >= 0 THEN RETURN 0141 WPN_F = 0 0142 RETURN 0143 ' 0144 @WPN_FIRE 0145 IF WPN_F THEN RETURN 0146 BEEP 10 0147 WPN_F = 1 0148 WPN_X = PLY_X 0149 WPN_Y = 20 0150 RETURN 0151 ' 0152 @WPN_HITC 0153 HITF = 0 0154 IF WPN_F == 0 THEN RETURN 0155 IF FLOOR(WPN_X) != FLOOR(HITX) THEN RETURN 0156 IF FLOOR(WPN_Y) != FLOOR(HITY) THEN RETURN 0157 HITF = 1 0158 ' 0159 BEEP 13 0160 WPN_F = 0 0161 RETURN 0162 'End of line |
では変更部分の説明を行います。
0002 GOSUB @SYS_INI
0003 GOSUB @PLY_INI
0004 GOSUB @WPN_INI
0005 GOSUB @UFO_INI
0006 ' game loop
0007 @LOOP
0008 GOSUB @SYS_MAIN
0009 ' task
0010 GOSUB @PLY_TASK
0011 GOSUB @WPN_TASK
0012 GOSUB @UFO_TASK
0013 GOTO @LOOP
まずメインでの変更はUFOのタスクの実行を最後に実行しています。
これは今回の当たり判定を行ううえで武器とその当たる相手(敵)の実行がこの順番の方が都合が良かったからです。
しかし実行の順番はゲームループのなかのタスクを呼んでいる命令を入れ替えればいいだけです。
サブルーチンでなかったらこの入れ替えは大変なことになっていたかもしれませんね。
ちなみに初期化の部分は入れ替えなくても問題は無かったのですが私の血液型がA型のせいか揃えています。
0017 @SYS_INI
0018 SYS_CNT = 0
0019 RETURN
0020 '
0021 @SYS_MAIN
0022 VSYNC 1
0023 CLS
0024 SYS_CNT = SYS_CNT + 1
0025 SYS_KEY = BUTTON()
0026 RETURN
システム部分は変更はありませんが、前回の内容についての確認のために説明します。
初期化の部分では SYS_CNT を0で初期化してあります。
これは今後このゲーム中で時間の概念を入れる際のストップウォッチのようなものです。
ここでストップウォッチをスタートしたようなものです。
@SYS_MAIN はゲームループ内から呼び出されます。
SYS_CNT が+1されカウントされています。
0030 @UFO_INI
0031 UFO_SX = 0.1
0032 UFO_F = 0
0033 UFO_CNT = 60
0034 RETURN
0035 '
0036 @UFO_TASK
0037 ON UFO_F GOTO @UFO_WAIT,@UFO_MVR,@UFO_MVL
0038 STOP
UFO部分は少々変更が多いので重要な点だけ解説します。
今までUFOはいきなり画面に現れましたが少しだけ時間を空けて(間を取って)現れるように変更しました。
今までUFOは右へ移動しその後左に移動する、これらを繰り返したわけですが画面に出る前に待つという状態も追加されました。
そこでプレイヤと同じようなプログラムへ変更されました。
UFO_CNT はUFOが画面現れるまでの待ち時間を表します。
今回60という値が代入されていますがこれはどういう意味かわかりますか?
0040 @UFO_WAIT
0041 UFO_CNT = UFO_CNT - 1
0042 IF UFO_CNT > 0 THEN RETURN
0043 GOTO @UFO_RSET
実際にUFOが待つタスクです。
UFO_CNT から1ずつ引いて0でなければ今のままですね。
0になると @UFO_RSET へジャンプしますがこれはただ単に今までの画面左上から右上まで移動するタスクへと変更しているだけです。
すると・・・
そうです1秒間待つのです。
ゲームループを60回待つと約1秒になるからです。
今後、この時間の概念は忘れないこと!!
0045 @UFO_MVR
0046 LOCATE UFO_X, 0
0047 PRINT "A"
0048 UFO_X = UFO_X + UFO_SX
0049 IF UFO_X > 32 GOTO @UFO_LSET
0050 HITX = UFO_X
0051 HITY = 0
0052 GOSUB @WPN_HITC
0053 IF HITF GOTO @UFO_DETH
0054 RETURN
0055 '
0056 @UFO_LSET
0057 UFO_X = 31
0058 UFO_F = 2
0059 RETURN
0060 ' move left
0061 @UFO_MVL
0062 LOCATE UFO_X, 0
0063 PRINT "A"
0064 UFO_X = UFO_X - UFO_SX
0065 IF UFO_X < 0 GOTO @UFO_RSET
0066 HITX = UFO_X
0067 HITY = 0
0068 GOSUB @WPN_HITC
0069 IF HITF GOTO @UFO_DETH
0070 RETURN
0071 '
0072 @UFO_RSET
0073 UFO_X = 0
0074 UFO_F = 1
0075 RETURN
UFOの移動部分はかなり変更されているようにみえますがそうでもありません。
UFOの表示が移動してきました。
これは画面に表示せずに待つタスクが追加されたのでここで表示しないと都合が悪くなったからです。
右も左も同様です。
IF 文は判定が逆になりました。
画面端にきたら右移動は左移動へジャンプ、左移動は右移動へジャンプしています。
では追加されたのは?
0066 HITX = UFO_X
0067 HITY = 0
0068 GOSUB @WPN_HITC
0069 IF HITF GOTO @UFO_DETH
これは当たり判定のサブルーチンを呼び出しています。
呼び出す前に今回当たり判定するための位置データを HITX および HITY にコピーしています。
なぜコピーするかはおいおいわかってきますのでここでは気にしないでください。
例えば上のプログラムの場合当たり判定したい対象、今回はUFOなのでUFOのX座標とY座標を代入しています。
@WPN _HITC は武器のヒット(当たり)をチェックするサブルーチンです。
その結果が HITF に代入されて返ってきます。
HITF が0でないときUFOが消滅するプログラムへジャンプします。
0077 @UFO_DETH
0078 UFO_F = 0
0079 UFO_CNT = 60
0080 RETURN
再びUFOを発生させるためフラグを0にしカウントを60にし60フレーム待つタスクへジャンプすることになります。
タスクのジャンプは他のプログラムのように GOTO 文は使いません。
ですのでジャンプという呼び方は不適当です。
今後は
タスクが移行すると呼ぶことにします。
0144 @WPN_FIRE
0145 IF WPN_F THEN RETURN
0146 BEEP 10
0147 WPN_F = 1
0148 WPN_X = PLY_X
0149 WPN_Y = 20
0150 RETURN
武器の発射ルーチンはデバッグの際にわかりやすいように発射音を鳴らしました。
0152 @WPN_HITC
0153 HITF = 0
0154 IF WPN_F == 0 THEN RETURN
0155 IF FLOOR(WPN_X) != FLOOR(HITX) THEN RETURN
0156 IF FLOOR(WPN_Y) != FLOOR(HITY) THEN RETURN
0157 HITF = 1
0158 '
0159 BEEP 13
0160 WPN_F = 0
0161 RETURN
最後に当たり判定のルーチンです。
サブルーチンの実行前に HITX および HITY に当たり判定の対象の座標が入っているのでこれと武器の座標を比べます。
最初に HITF に0を代入しているのは当たっていない条件を判断してその場合に終了するため最初は判定はNGの意味で0が代入されています。
0154行目は武器フラグが0のときは発射されていないのでNGで戻ります。
0155行目は武器のX座標と対象のX座標が違う場合NGとなります。
0156行目は同様にY座標の場合です。
ここまで来るとすべての条件がOKだったので当たったと判断しています。
当たったら武器は発射前の待ちタスクへ移行します。
さあ、どうでしょうか?
理解できましたか?
ちなみに座標の判定を行っている部分で FLOOR という関数を使っています。
これは引数(かっこの中に書いた変数の値)の小数部分を切り捨てた値、要するに整数部分を返します。
なぜだかわかりますよね?