【はじめてのプチコン】武器の複製と問題点 | りょうのゲーム塾

りょうのゲーム塾

再開、準備中。

チェックポイント
同じ処理を行うプログラムを書く場合は必要な変数を配列にしておけばFORループなどの繰り返し処理で実行できます。
現在のプレイヤは武器が最高画面内1個しか使用できないので少々敵に当たりづらいので最高画面内3個まで増やしてあげましょう。


■プログラム
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 CLEAR
0019 SYS_CNT = 0
0020 RETURN
0021 '
0022 @SYS_MAIN
0023 VSYNC 1
0024 CLS
0025 SYS_CNT = SYS_CNT + 1
0026 SYS_KEY = BUTTON()
0027 RETURN
0028 '
0029 ' UFO task
0030 '
0031 @UFO_INI
0032 UFO_SX = 0.1
0033 UFO_F = 0
0034 UFO_CNT = 60
0035 RETURN
0036 '
0037 @UFO_TASK
0038 ON UFO_F GOTO @UFO_WAIT,@UFO_MVR,@UFO_MVL
0039 STOP
0040 '
0041 @UFO_WAIT
0042 UFO_CNT = UFO_CNT + 1
0043 IF UFO_CNT > 0 THEN RETURN
0044 GOTO @UFO_RSET
0045 ' move right
0046 @UFO_MVR
0047 LOCATE UFO_X, 0
0048 PRINT "A"
0049 UFO_X = UFO_X + UFO_SX
0050 IF UFO_X > 32 GOTO @UFO_LSET
0051 HITX = UFO_X
0052 HITY = 0
0053 GOSUB @WPN_HITC
0054 IF HITF GOTO @UFO_DETH
0055 RETURN
0056 '
0057 @UFO_LSET
0058 UFO_X = 31
0059 UFO_F = 2
0060 RETURN
0061 ' move left
0062 @UFO_MVL
0063 LOCATE UFO_X, 0
0064 PRINT "A"
0065 UFO_X = UFO_X - UFO_SX
0066 IF UFO_X < 0 GOTO @UFO_RSET
0067 HITX = UFO_X
0068 HITY = 0
0069 GOSUB @WPN_HITC
0070 IF HITF GOTO @UFO_DETH
0071 RETURN
0072 '
0073 @UFO_RSET
0074 UFO_X = 0
0075 UFO_F = 1
0076 RETURN
0077 '
0078 @UFO_DETH
0079 UFO_F = 0
0080 UFO_CNT = 60
0081 RETURN
0082 '
0083 ' player task
0084 '
0085 @PLY_INI
0086 PLY_X = 15
0087 PLY_SX = 0.5
0088 PLY_F = 0
0089 RETURN
0090 '
0091 @PLY_TASK
0092 LOCATE PLY_X,21
0093 PRINT "P"
0094 IF SYS_KEY AND 16 THEN GOSUB @WPN_FIRE
0095 ON PLY_F GOTO @PLY_STOP,@PLY_MVR,@PLY_MVL
0096 STOP
0097 ' stop
0098 @PLY_STOP
0099 IF SYS_KEY AND 8 GOTO @PLY1
0100 IF SYS_KEY AND 4 GOTO @PLY2
0101 RETURN
0102 @PLY1
0103 PLY_F = 1
0104 RETURN
0105 @PLY2
0106 PLY_F = 2
0107 RETURN
0108 ' move right
0109 @PLY_MVR
0110 PLY_X = PLY_X + PLY_SX
0111 IF PLY_X > 31 THEN PLY_X = 31
0112 IF SYS_KEY AND 8 THEN RETURN
0113 PLY_F = 0
0114 RETURN
0115 ' move left
0116 @PLY_MVL
0117 PLY_X = PLY_X - PLY_SX
0118 IF PLY_X < 0 THEN PLY_X = 0
0119 IF SYS_KEY AND 4 THEN RETURN
0120 PLY_F = 0
0121 RETURN
0122 '
0123 ' weapon task
0124 '
0125 @WPN_INI
0126 WPN_MAX = 3
0127 DIM WPN_F(WPN_MAX)
0128 DIM WPN_X(WPN_MAX)
0129 DIM WPN_Y(WPN_MAX)
0130 FOR I=0 TO WPN_MAX-1
0131 WPN_F(i) = 0
0132 NEXT I
0133 WPN_SY = 0.5
0134 RETURN
0135 '
0136 @WPN_TASK
0137 FOR WPN_I=0 TO WPN_MAX-1
0138 GOSUB @WPN_SUB
0139 NEXT WPN_I
0140 RETURN
0141 '
0142 @WPN_SUB
0143 ON WPN_F(WPN_I) GOTO @WPN_WAIT,@WPN_MOVE
0144 STOP
0145 '
0146 @WPN_WAIT
0147 RETURN
0148 '
0149 @WPN_MOVE
0150 LOCATE WPN_X(WPN_I),WPN_Y(WPN_I)
0151 PRINT "!"
0152 WPN_Y(WPN_I) = WPN_Y(WPN_I) + WPN_SY
0153 IF WPN_Y(WPN_I) >= 0 THEN RETURN
0154 WPN_F(WPN_I) = 0
0155 RETURN
0156 '
0157 @WPN_FIRE
0158 GOSUB @WPN_GET
0159 IF WPN_N < 0 THEN RETURN
0160 BEEP 10
0161 WPN_F(WPN_N) = 1
0162 WPN_X(WPN_N) = PLY_X
0163 WPN_Y(WPN_N) = 20
0164 RETURN
0165 '
0166 @WPN_HITC
0167 HITF = 0
0168 FOR WPN_N=0 TO WPN_MAX-1
0169 IF WPN_F(WPN_N) == 0 GOTO @WPN_NEXT
0170 IF FLOOR(WPN_X(WPN_N)) != FLOOR(HITX) GOTO @WPN_NEXT
0171 IF FLOOR(WPN_Y(WPN_N)) != FLOOR(HITY) GOTO @WPN_NEXT
0172 GOTO @WPN_HOK
0173 @WPN_NEXT
0174 NEXT WPN_N
0175 RETURN
0176 '
0177 @WPN_HOK
0178 HITF = 1
0179 '
0180 BEEP 13
0181 WPN_F(WPN_N) = 0
0182 RETURN
0183 '
0184 @WPN_GET
0185 FOR WPN_N=0 TO WPN_MAX-1
0186 IF WPN_F(WPN_N)==0 THEN RETURN
0187 NEXT WPN_N
0188 WPN_N = -1
0189 RETURN
0190 'End of line


では解説です。

0017 @SYS_INI
0018 CLEAR
0019 SYS_CNT = 0
0020 RETURN

これはプチコンの独特な仕様だと考えています。
本来はありえないことです。
通常のベーシックではRUNコマンドで実行すると変数は初期化されるのでこのCLEAR命令は必要ありません。
私の知っている限りのベーシックではこの必要はありません。
しかしプチコンはエラーがでるので仕方なくCLEARしておきます。
今後も必ずここでCLEARしておけばいいでしょう。

0125 @WPN_INI
0126 WPN_MAX = 3
0127 DIM WPN_F(WPN_MAX)
0128 DIM WPN_X(WPN_MAX)
0129 DIM WPN_Y(WPN_MAX)
0130 FOR I=0 TO WPN_MAX-1
0131 WPN_F(i) = 0
0132 NEXT I
0133 WPN_SY = 0.5
0134 RETURN

武器の複製を行います。
武器の使う変数を配列宣言します。
必要数をWPN_MAXに代入して使っているのには利点があるからです。
さてその利点とはなんでしょうか?
考えてみてくださいね!

配列宣言の後は武器の重要な変数であるフラグを0に初期化します。

0136 @WPN_TASK
0137 FOR WPN_I=0 TO WPN_MAX-1
0138 GOSUB @WPN_SUB
0139 NEXT WPN_I
0140 RETURN

本来の武器タスクのプログラムは@WPN_SUBへ移動します。
この部分は必要数分の武器タスクを実行するループに変更してあります。

0142 @WPN_SUB
0143 ON WPN_F(WPN_I) GOTO @WPN_WAIT,@WPN_MOVE
0144 STOP
0145 '
0146 @WPN_WAIT
0147 RETURN
0148 '
0149 @WPN_MOVE
0150 LOCATE WPN_X(WPN_I),WPN_Y(WPN_I)
0151 PRINT "!"
0152 WPN_Y(WPN_I) = WPN_Y(WPN_I) + WPN_SY
0153 IF WPN_Y(WPN_I) >= 0 THEN RETURN
0154 WPN_F(WPN_I) = 0
0155 RETURN

今までの武器プログラムですが変数が配列になっています。

0157 @WPN_FIRE
0158 GOSUB @WPN_GET
0159 IF WPN_N < 0 THEN RETURN
0160 BEEP 10
0161 WPN_F(WPN_N) = 1
0162 WPN_X(WPN_N) = PLY_X
0163 WPN_Y(WPN_N) = 20
0164 RETURN

武器の発射ルーチンですが@WPN_GETが発射可能な武器を探します。
WPN_Nに-1が入っている場合には発射できる武器が無かったことになります。
0~2の場合にはその番号の武器が発射できます。

0166 @WPN_HITC
0167 HITF = 0
0168 FOR WPN_N=0 TO WPN_MAX-1
0169 IF WPN_F(WPN_N) == 0 GOTO @WPN_NEXT
0170 IF FLOOR(WPN_X(WPN_N)) != FLOOR(HITX) GOTO @WPN_NEXT
0171 IF FLOOR(WPN_Y(WPN_N)) != FLOOR(HITY) GOTO @WPN_NEXT
0172 GOTO @WPN_HOK
0173 @WPN_NEXT
0174 NEXT WPN_N
0175 RETURN
0176 '
0177 @WPN_HOK
0178 HITF = 1
0179 '
0180 BEEP 13
0181 WPN_F(WPN_N) = 0
0182 RETURN

この部分が当たり判定ですが少し複雑になりましたね。
前回の場合は武器が1個だったんで判定が簡単でしたが今回は複数になりました。
今回はすべての判定をしてすべて当たっていないとき当たり判定が失敗となります。

0184 @WPN_GET
0185 FOR WPN_N=0 TO WPN_MAX-1
0186 IF WPN_F(WPN_N)==0 THEN RETURN
0187 NEXT WPN_N
0188 WPN_N = -1
0189 RETURN

発射可能な武器の検索です。

ではこれを実行してみてください。
武器は複数でるはずですが…どうでしょう?

変ですよね?