【プチコン4講座】斧とワンパク君に衝突判定を実装
こんにちは。なおキーヌです。
ブログ毎日更新は283日目になります。
振り向きとジャンプの仕組みを作ろうの続きの記事になります。
左右に動くとき、ハカセを進行方向に向かせることが出来てジャンプも実装出来ました。
前回の最後に衝突判定それぞれのスプライトに準備したので、
それを使って斧をワンパク君に当ててみます。
それでは木こりゲーム作り第4回目、始めていきましょう。
斧がハカセ以外のスプライトに当たったら
全てのスプライトに衝突判定の準備をしたので、
斧はハカセ以外のスプライトに当たったらヒットしたスプライトを取得することにしましょう。
範囲で指定してどのスプライトに当たったかを判別してくれる
「SPHITSP」という便利な命令があるのでこれを使います。
早速斧とハカセ以外のスプライトを設定してみましょう。
VAR HITSP = -1
LOOP
' 斧とハカセ以外のスプライトの判定を取る
HITSP = SPHITSP(100,1,3)
PRINT HITSP
ENDLOOP
取得に関してはこれだけでOKです。
当たっていればその当たったスプライトの番号を取得でき、
何も当たっていなければ-1が返ってきます。
条件を満たしたらワンパク君を消滅させる
判定を取ることが出来たので、ワンパク君を認識することが出来るようになりました。
ワンパク君はイノシシ役なので画面外から突撃してもらいます。
ハカセは斧でそれを迎え撃ちます。
とりあえずは斧がワンパク君にあたったら消滅させてみます。
一旦スプライト非表示でいいでしょう。
LOOP
' 斧とハカセ以外のスプライトの判定を取る
HITSP = SPHITSP(100,1,3)
IF HITSP == 1 THEN
SPHIDE 1
ENDIF
ENDLOOP
これだけですね。
インテリや神崎を消したい場合は条件分岐の2や3を設定すればOKです。
簡単ですね!
消滅したら時間を計測して一定時間で復活させる
ワンパク君を消滅させることが出来たので、消えた直後にカウントを開始する関数を作りましょう。
そして一定フレーム数を越えたら復活させましょう。
本来は画面外で復活させたいのですが、今回は仕組み作りだけを重視します。
座標はあとから変えられますからね。
カウントはそれぞれで持ちたいのでスプライト変数にしましょう。
SPVAR 1, "HIDE", 0
LOOP
' 斧とハカセ以外のスプライトの判定を取る
HITSP = SPHITSP(100,1,3)
IF HITSP == 1 THEN
SPHIDE 1
SPVAR 1, "HIDE", 1
ENDIF
HIDE_COUNT
ENDLOOP
' 消滅時のカウント
DEF HIDE_COUNT
IF SPVAR(1,"HIDE") >= 1 THEN
SPVAR 1, "HIDE", SPVAR(1, "HIDE")+1
IF SPVAR(1, "HIDE") > 300 THEN
SPSHOW 1
SPVAR 1, "HIDE", 0
ENDIF
ENDIF
END
斧が当たった瞬間にHIDE変数に1を与えます。
そして常に呼び出しているHIDE_COUNT関数内で、
HIDEが1になったらカウント開始という感じです。
これ結構重要なことなので覚えておいてください!
何かがトリガーになって動くということはゲームではよく使う処理です。
#petitcom #プチコン4 #NintendoSwitch pic.twitter.com/8GIXzrc3LB
— なおキーヌ@ゲームクリエイターLv5 (@naokeyzmt) October 9, 2019
今回は短いですが、これぐらいにしておきましょう。
次回はこの処理を活かしてワンパク君を走らせたり再出減させたりしたいですね。
最後に今回のソースコードを置いておきます。
それでは!
ACLS
' 地面と判定するための座標定数
CONST #GND = 160
' ループ用変数
VAR G_I = 0
' 衝突判定用変数
VAR HITSP = -1
' ジャンプ配列アクセス用変数
VAR JPPC = 0
' ジャンプ配列
DIM JUMP_PROCESS[] = [-14,-10,-8,-6,-4,-2,2,4,6,8,10,14]
' スプライト定義
SPSET 0, 1432
SPCOL 0
SPVAR 0, "X", 35
SPVAR 0, "Y", #GND
SPVAR 0, "DIRECT" , #FALSE
SPVAR 0, "SWING" , #FALSE
SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")
SPVAR 0, "JUMP" , #FALSE
' 斧スプライト定義(非表示にしておく)
SPSET 100, 161, 0
SPCOL 100
SPVAR 100, "ROTATE", 0
' アトリビュートの基準点を変更
SPHOME 100, 8, 16
' その他スプライト定義
SPSET 1, 1436
SPSET 2, 1438
SPSET 3, 1442
SPOFS 1, 200,160
SPOFS 2, 100,200
SPOFS 3, 300,50
SPCOL 1
SPCOL 2
SPCOL 3
SPVAR 1, "HIDE", 0
' 青空ぽい背景描写
FOR G_I=0 TO 240
GLINE 0,I,400,I,RGB(I/2, 125+ROUND(I/2), 255)
NEXT
' 地面を描写
FOR G_I = 0 TO 24
TPUT 0, G_I, 14, &HECC2
TPUT 0, G_I, 14, &HED02
TPUT 0, G_I, 14, &HED02
NEXT
LOOP
D_CONTROLLER
' 斧とハカセ以外のスプライトの判定を取る
HITSP = SPHITSP(100,1,3)
IF HITSP == 1 THEN
SPHIDE 1
SPVAR 1, "HIDE", 1
ENDIF
HIDE_COUNT
ENDLOOP
' コントローラー関数
'───────────────────────────────
DEF D_CONTROLLER
' 0番目のコントローラー(つまり1コン)の押されているボタンを取得
VAR B = BUTTON(0)
' 斧を振っていなかったら
IF SPVAR(0,"SWING") == #FALSE THEN
' 左ボタン処理
IF (B AND 1 << #B_LLEFT) != 0 THEN
SPVAR 0, "X", SPVAR(0,"X")-1
SPVAR 0, "DIRECT", #TRUE
ENDIF
' 右ボタン処理
IF (B AND 1 << #B_LRIGHT) != 0 THEN
SPVAR 0, "X", SPVAR(0,"X")+1
SPVAR 0, "DIRECT", #FALSE
ENDIF
' 向き変更
IF SPVAR(0, "DIRECT") == #TRUE THEN
SPCHR 0,,,32,32,#A_REVH
SPCHR 100,,,,,#A_REVH
' 向きに合わせて斧の位置を変える
SPOFS 100, SPVAR(0,"X"), SPVAR(0,"Y")+24
ELSE
SPCHR 0,,,32,32,0
SPCHR 100,,,,,0
' 向きに合わせて斧の位置を変える
SPOFS 100, SPVAR(0,"X")-32, SPVAR(0,"Y")+24
ENDIF
' 移動処理
IF SPVAR(0,"X") < -16 THEN
SPVAR 0,"X", -16
ELSEIF SPVAR(0,"X") > 400-16 THEN
SPVAR 0,"X", 400-16
ENDIF
SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")
' Yボタン処理
IF (B AND 1 << #B_LRIGHT) != 0 THEN
' 振った音を鳴らす
BEEP 100
' ハカセのグラを変更
IF SPVAR(0, "DIRECT") == #TRUE && SPVAR(0,"JUMP") != #TRUE THEN
SPCHR 0,1433,,32,32,#A_REVH
ELSE
SPCHR 0,1433,,32,32,0
ENDIF
' 斧振りフラグON
SPVAR 0,"SWING", #TRUE
ENDIF
' ジャンプ中か調べる
IF SPVAR(0,"JUMP") != #TRUE THEN
' ジャンプ中じゃなければAボタン処理が効く
IF (B AND 1 << #B_RRIGHT) != 0 THEN
' ジャンプフラグをONにする
SPVAR 0,"JUMP", #TRUE
' 上昇中フラグに切り替える
SPVAR 0,"UPDOWN", #TRUE
ENDIF
ELSE
' 現在座標にジャンプ配列の該当する値を取り出して足す
SPVAR 0, "Y", SPVAR(0,"Y") + JUMP_PROCESS[JPPC]
' 次のジャンプ配列にアクセスするためにインクリメント
INC JPPC
' もしアクセス変数と配列の長さが同じになったら
IF JPPC == LEN(JUMP_PROCESS)-1 THEN
' プレイヤーのY座標補正
SPVAR 0, "Y", #GND
' ジャンプフラグを解除
SPVAR 0,"JUMP", #FALSE
' 次のジャンプのためにアクセス変数を初期化しておく
JPPC = 0
ENDIF
ENDIF
ENDIF
END
' 斧振り関数
'───────────────────────────────
DEF D_SWING_AXE
IF SPVAR(0,"SWING") == #TRUE THEN
' 斧を出現させる
SPSHOW 100
' 向きによって振る方向を変更
IF SPVAR(0, "DIRECT") == #TRUE THEN
' 斧を指定位置まで回転させる
IF SPVAR(100, "ROTATE") > -90 THEN
SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")-5
SPROT 100, SPVAR(100, "ROTATE")
ELSE
SPHIDE 100
SPVAR 100, "ROTATE", 0
SPROT 100, SPVAR(100, "ROTATE")
SPVAR 0,"SWING", #FALSE
ENDIF
ELSE
' 斧を指定位置まで回転させる
IF SPVAR(100, "ROTATE") < 90 THEN
SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")+5
SPROT 100, SPVAR(100, "ROTATE")
ELSE
SPHIDE 100
SPVAR 100, "ROTATE", 0
SPROT 100, SPVAR(100, "ROTATE")
SPVAR 0,"SWING", #FALSE
ENDIF
ENDIF
ENDIF
END
' 消滅時のカウント
'───────────────────────────────
DEF HIDE_COUNT
IF SPVAR(1,"HIDE") >= 1 THEN
SPVAR 1, "HIDE", SPVAR(1, "HIDE")+1
IF SPVAR(1, "HIDE") > 300 THEN
SPSHOW 1
SPVAR 1, "HIDE", 0
ENDIF
ENDIF
END