HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2007
0121
アーム貫通弾について7解決


アーム

リンク

2007/1/21(Sun) 12:11:40|NO.4972

HSPDXFIX使用のシューティングを作っているのですが
敵一体につき一回だけダメージを与える貫通弾が作れません
一度当たった敵と弾の衝突判定を行わないようにするには
どういったスクリプトを組めばよいのでしょうか・・・
ご教示お願いします。



この記事に返信する


D.K

リンク

2007/1/22(Mon) 00:26:16|NO.4996

敵を配列で管理しているならば、
その弾が最後に当たった敵の番号を変数に保存しておいて
当たった敵の番号がその番号と一致する場合はダメージを与えない
などではダメでしょうか?
一度別の敵に当たった後でもう一度当たった場合は
ダメージが入ってしまいますが…。
流れとしては大体下のようになります。

当たり判定
 ↓
 当たっているなら
 今当たった敵の番号と最後に当たった敵の番号を比較
  ↓
  番号が一致していればさっき当たっているのでノーダメージ
  番号が一致していなければダメージ
  ↓
  最後に当たった敵の番号に今当たった敵の番号を保存

最初に戻る



KIMU

リンク

2007/1/22(Mon) 00:35:27|NO.4997

es_check p1,p2,p3,p4,p5,p6
p5=検索を開始するスプライトNo.
これを利用

p1 に敵のナンバー入っていたら
p6 に入れた数以上ならその弾のチェックは終わり
違うならそのナンバーに1加えて p5 にセットして再チェック

弾No開始=弾No0 repeat es_find 弾No,type弾,弾No開始,弾No終了 if 弾No<0 {break} 敵No開始=敵No0 repeat es_check p1,弾No,type敵,p4,敵No開始,敵No終了 if p1<0 {break} /* ここで弾が当たった時の処理が終わったとして続く */ if p1=敵No終了 { break }else{ 敵No開始=p1+1 } loop 弾No開始=弾No+1 loop
こんな感じ

for のカウンタセットとカウンタが加算されるのを利用して

for 弾No,弾No0,弾No終了+1 es_find 弾No,type弾,弾No,弾No終了 if 弾No<0 {_break} for p1,敵No0,敵No終了+1 es_check p1,弾No,type敵,p4,p1,敵No終了 if p1<0 {_break} /* ここで弾が当たった時の処理が終わったとして続く */ next next
こんな風にも出来るかな
(両方試してないから不都合があるかもしれない・・・)

スプライトのナンバーを使う用途で振り分けてないなら
敵No終了は使用出来るスプライトの最大数にして、敵No0は0にすればいいかな
(弾の検索も同じ)



KIMU

リンク

2007/1/22(Mon) 00:51:36|NO.4998

あぁ、D.Kさんの解釈が正しい場合
自分のは役に立ちません。

>敵一体につき一回だけダメージを与える貫通弾が作れません
>一度当たった敵と弾の衝突判定を行わないようにするには

自分には、敵と当たった弾が1フレームで敵が死ぬまで
判定を続けてしまうので、その回避策を聞きてるんだと読めた・・・
(一度当たった敵には二度と当たらないってのが想像しにくいので・・・)



As

リンク

2007/1/22(Mon) 14:22:44|NO.5010


if (当たり判定(cnt))&(弾が当たった(cnt)=0){ 弾が当たった(cnt)=1 } if 弾がウィンドウ外(cnt)(もしくは見えなくなる){ 弾が当たった(cnt)=0 }



アーム

リンク

2007/1/22(Mon) 23:16:45|NO.5025

返答ありがとうございます。
一度当たった敵には二度と当たらない、です。敵も配列で管理してます。
わかり辛い言い方ですいませんでした。
挙げていただいたスクリプトを試してみたのですが
どうもうまく動きません。
もう少しだけわかりやすく教えてもらえませんでしょうか。
よろしくお願いします。



KIMU

リンク

2007/1/24(Wed) 07:15:35|NO.5068

NO.4997で変数名に漢字を使っちゃったから面倒なのでそのまま・・・


#include "hspdxfix.as" screen 0,640,480,0 es_ini es_screen 640,480,16,,1,1 if stat=0 : goto *start dialog "エラー",1 end *start gosub *datinit es_window 0,0,640,480 buffer 10,256,256 cls 4:color 0,100,250:grect 16,16,3.1415/4,24,24:color 0,200,00:circle 32,0,32+32,32:color 100,150,250:boxf 64+14,2,64+14+4,30:color 200,100,050:circle 64+12+32,8,64+12+8+32,30 mref se_stat,64:se_stat=0:es_buffer 10,0,0,,1:if stat=1 :dialog "エラー",1:end es_size 32,32,100,0:es_pat 1,0,0,0:es_new myspno,0:es_set myspno,250,250,1,1,0 es_pat 2,32,0,0 :es_size 32,32,60,0 :es_pat pat弾A,64,0,0 :es_pat pat弾B,96,0,0 gsel 0 repeat es_exboxf 0,0,640,480,$4040 stick ky,255:if ky&128{end} if ky&1{x-4}else{if ky&4{x+4}} :if ky&2{y-4}else{if ky&8{y+4}} :x=limit(x,0,640-32):y=limit(y,0,480-32):es_pos myspno,x,y if (ky&(16+64)){kycnt++}else{kycnt=0} if (kycnt\8)=1 { //スペース=貫通弾 : コントロール=通常弾 if ky&16 {type弾=type弾A :pat弾=pat弾A :spd弾=spd弾A} else {type弾=type弾B :pat弾=pat弾B :spd弾=spd弾B} repeat 4 ;一度に4発撃つ es_new 弾No,弾No0 if 弾No<弾No終了 { es_set 弾No,弾x(cnt)+x,弾y(cnt)+y,pat弾,1,0 :es_type 弾No,type弾 :es_adir 弾No,32,spd弾 //弾にIDを付ける 弾ID++ :弾(弾No)=弾ID } loop } if 敵数<敵Max{ es_new 敵No,敵No0 :es_set 敵No,rnd(440)+100,rnd(200)+50,2,1,0 :es_type 敵No,type敵 //敵に違う弾が当たった数のカウンタをクリア 敵当数(敵No)=0 :HP(敵No)=20 :敵数++ } if 敵数{gosub *check} es_draw 0 color 250,100,0 for 敵No,敵No0,敵No終了+1 es_find 敵No,type敵,敵No,敵No終了 if 敵No<0 {_break} es_get 敵x,敵No,3 :es_get 敵y,敵No,5 pos 敵x+8,敵y+8 :es_mes str(HP(敵No)) c=limit(敵当数(敵No),0,当数Max) repeat c pos 敵x+16,敵y+16+cnt*16 :es_fmes str(敵(cnt,敵No)) loop next es_sync 16,1 :await 0 :es_getfps fps :title str(fps) loop *datinit 弾Max=50 :敵Max=10 :当数Max=10 ;弾Max,敵Maxはそれぞれの最大数 :当数Maxは一つの敵で弾のIDを保存できる数(これを越えた時は最初に戻り上書きされる) x=300:y=400 :弾No0=50:弾No終了=弾No0+弾Max :敵No0=200:敵No終了=敵No0+敵Max 弾x=-8,8,-20,20:弾y=-8,-8,0,0 :spd弾A=1200:spd弾B=800 :type弾A=2:type弾B=4:type敵=256 :pat弾A=3:pat弾B=4 :spmax=512 dim HP,spmax ;スプライトNoを利用するのでスプライトの使える最大数(初期値)まで確保 dim 弾,spmax ;弾のID用 dim 敵,当数Max,spmax ;当たった弾のIDを入れる dim 敵当数,spmax ;違う弾が当たったカウント用 return *check for 弾No,弾No0,弾No終了+1 es_find 弾No,type弾A+type弾B,弾No,弾No終了 if 弾No<0 {_break} for 敵No,敵No0,敵No終了+1 es_check 敵No,弾No,type敵,p4,敵No,敵No終了 if 敵No<0 {_break} es_get type,弾No,13 if type弾A=type {;貫通弾(攻撃力1) n=弾(弾No) ;弾のIDを取り出す c=limit(敵当数(敵No),0,当数Max) ;違う弾が当たった数を取り出す(当数Maxを上限として) for checkcnt,0,c if 敵(checkcnt,敵No)=n {checkcnt=-1:_break} ;現在の弾と同じIDがすでに当たっていたら途中で終了(checkcnt=-1で途中で終わった事を記録) next if checkcnt=c { ;最後までチェックが出来たから同じ弾は当たっていない 敵(敵当数(敵No)\当数Max,敵No)=n ;弾のIDを入れる(入れる場所を 0〜(当数Max-1) でループさせる) 敵当数(敵No)++ ;違う弾が当たった数をカウント HP(敵No)-- ;HPを減らす } }else{HP(敵No)-3 :es_kill 弾No} ;通常弾(攻撃力3) if HP(敵No)<1{es_kill 敵No:敵数-- :_break} next next return

この方法だと、弾の速度や数、敵の判定の大きさによって「当数Max」を調節する必要があるかも
一回当たった弾が、敵から抜ける前に「当数Max」以上の弾数に当たると上書きされるので
再度当たる事になる



アーム

リンク

2007/1/25(Thu) 23:08:21|NO.5135

無事に動きました。
アドバイスくださった方々
本当にありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.