あたり判定
やまぎ 2013/6/29(Sat) 23:31:21|NO.55341
#module
// 時間を正確に測るためのAPI
#uselib "kernel32.dll"
#func QueryPerformanceFrequency "QueryPerformanceFrequency" var
#func QueryPerformanceCounter "QueryPerformanceCounter" var
#deffunc __init_await
ddim fr, 1
ddim tm, 1
ddim tm2, 1
ddim wt, 1
ddim xtm, 1
ddim xfr, 1
QueryPerformanceFrequency fr
if stat = 0 : return 1
xfr = double(strf("%I64u", fr))
QueryPerformanceCounter tm
xtm = double(strf("%I64u", tm))
return 0
#undef await// 既存のawait命令を消す(いままでのawait命令を使用する場合はawait@hspで呼び出せます)
#deffunc await double wc
wait 0
if wc <= 0.0 {// await 0やawait -1で現在の時刻(?)を基準に設定
QueryPerformanceCounter tm
xtm = double(strf("%I64u", tm))
return
}
wt = xfr * wc / 1000
xtm += wt
repeat
QueryPerformanceCounter tm2
if double(strf("%I64u", tm2)) - xtm >= wt : break
loop
return
#global
__init_await
if stat : dialog "エラー", 1 : end
await 0// 基準設定。これを音ゲーのループの前に置く。
/**/
*音楽宣言
mmload "初期素材\\タン.wav",1,0
*配列宣言
dim 譜面,5
sdim 譜面_load,5
dim cut,5
dim humen,5,50
dim humen_flg,5,60
dim humen_y,5,60
dim humen_x,5,60
dim key,50
dim key_gata,50
dim x,50
dim y,50
dim hakusen_y,4
/**/
//譜面設定
譜面_load(1)="00000001000000000001000000000001000000000001"
譜面_load(2)=""
譜面_load(3)=""
譜面_load(4)=""
humen_dy=10
tenpo=185
kannkaku_set=10000000
hakusen_y(3)=50+240
hakusen_y(2)=50+120
hakusen_y(1)=50
for i,1,5,1
repeat 30
humen_x(i,cnt)=0
humen_y(i,cnt)=0
loop
x(i)=0
y(i)=0
next
*音ゲー_main
gosub *背景の初期化
gosub *キー判定
gosub *譜面の精製
gosub *譜面表示
gosub *拍線
for i,1,5,1
pos 0,20*i
color 255,255,255
mes 譜面(i)
next
color 20,100,250
pos 200,100
mes ""+score+":\n"+conbo+":"
mes "BMP:"+tenpo+"\n"+humen_y(1,2)+""
mes hakusen_y(1)
redraw 0
await 60000/tenpo/9
redraw 1
goto *音ゲー_main
*拍線
color 255,255,255
line 51,hakusen_y(1),253,hakusen_y(1)
line 51,hakusen_y(2),253,hakusen_y(2)
color 250,10,0
line 51,hakusen_y(3),253,hakusen_y(3)
for i,1,4
if hakusen_y(i)>=380 : hakusen_y(i)=20
hakusen_y(i)+=humen_dy
next
return
*背景の初期化
color :boxf 51,21,253,379 //背景
color 255,255,0
line 50,20,254,20
line 50,20,50,380
line 254,20,254,380
color 10,0,255
line 101,20,101,380
line 152,20,152,380
line 203,20,203,380
return
*キー判定
getkey key(1),68
getkey key(2),70
getkey key(3),74
getkey key(4),75
getkey key(5),27
if key(5)=1 : await 0 : goto *配列宣言
repeat 60
if key(i)>=1 & key_gata(i)=0{
kaisuu_key(i)++
if i=1 : gradf 52,21,49,360,1,$000000,$fcfb7e
if i=2 : gradf 103,21,49,360,1,$000000,$7ffc7f
if i=3 : gradf 154,21,49,360,1,$000000,$fc7e7e
if i=4 : gradf 205,21,49,360,1,$000000,$7ef5fc
if humen_y(i,cnt) <= 388 & humen_y(i,cnt) >=378 {
humen_flg(i,cnt) = 0
humen_y(i,cnt)=500
score=score+100+conbo*5/3
conbo++
key_gata(i)=1
color 0,0,0
boxf 50,400,300,415
color 170,170,100
pos i*50+8,400
mes "GREAT"
mmplay 1
}
if humen_y(i,cnt) <= 377 & humen_y(i,cnt) >=358 {
humen_flg(i,cnt) = 0
humen_y(i,cnt)=500
score=score+50+conbo*5/3
conbo++
key_gata(i)=1
color 0,0,0
boxf 50,400,300,415
color 170,170,100
pos i*50+8,400
mes "GOOD"
mmplay 1
}
if kaisuu_key(i)>=3 & key_gata(i)=0 : key_gata(i)=1 : kaisuu_key(i)=0
}
if key(i)=0 & key_gata(i)=1 : key_gata(i)=0
loop
return
*譜面の精製
for i,1,5,1
譜面(i)=int(strmid(譜面_load(i),cut(i),1)):cut(i)++
next
return
*譜面表示
for i,1,5,1
gosub *キー判定
if 譜面(i)=1{
repeat 60
if humen_flg(i,cnt) = 0 {
humen_flg(i,cnt) = 1
humen_x(i,cnt) = (x(i) + 20)
humen_y(i,cnt) = y(i)
break
}
loop
}
next
for i,1,5,1
repeat 60
if i=1 : color 255,0,138
if i=2 : color 250,250,10
if i=3 : color 10,250,0
if i=4 : color 10,250,250
if humen_flg(i,cnt)=1{
color 250,10,0
boxf 51*i,humen_y(i,cnt)-2,51*i+49,humen_y(i,cnt)+2
humen_y(i,cnt)+=humen_dy
if humen_y(i,cnt)>=388{
humen_flg(i,cnt) = 0
humen_y(i,cnt)=500
color 0,0,0
boxf 50,400,300,415
color 170,170,100
pos i*50+8,400
mes "MISS"
}
}
loop
next
return
左からDFJKですがなぜかあたり判定がうまくいきません
どこか悪いところありますか?
てれてれ 2013/6/30(Sun) 00:20:40|NO.55342
何が上手くいってないのかわかんないんだけど。。
やまぎ 2013/6/30(Sun) 00:25:30|NO.55343
>>てれてれ
いや・・・・あたり判定だけど?
押したときに重なってるはずなのにたまに判定がないときがある
でも自分で少し解決しましたがほかのやり方があるなら教えてほしいです
ちなみに変えた場所は
if kaisuu_key(i)>=3 & key_gata(i)=0 : key_gata(i)=1 : kaisuu_key(i)=0
ここ(↑)を↓にしました
if kaisuu_key(i)>=60 & key_gata(i)=0 : key_gata(i)=1 : kaisuu_key(i)=0
何か案があれば教えてほしいです
MillkeyStars 2013/6/30(Sun) 08:52:22|NO.55348
んー。スクリプトの判定位置みたけど、これって、判定が対になっていないよね。
某ビー○マニアとかでも、早めに押した場合と遅めに押した場合とで同じ範囲があると思うけど。
color 255,255,0 : boxf 51,20,254,400
color 0,0,0 : boxf 52,21,253,399
color 10,0,255
line 101,20,101,385
line 152,20,152,385
line 203,20,203,385
color 255,0,0 : line 51,379,515,379 : pos 520,370 : mes "基準ベース"
color 0,0,255 : line 51,374,420,374 : line 51,384,420,384
pos 425,360 : mes "GREAT範囲"
color 0,255,0 : line 51,369,320,369 : line 51,389,320,389
pos 325,355 : mes "GOOD範囲"
上記スクリプトみたいに、判定範囲が早め遅め共に同じ範囲の方がいいと思うけどとアドバイスしてみる。
スクリプトには、書かれていないけど、BAD (キー入力を認めて判定する)範囲も作った方がいいと思う。
BAD 範囲にない譜は、すべて判定しないとか。(音はなるけどね。)
質問の答えになっていないけど、良い物が作れるといいね^^
てれてれ 2013/6/30(Sun) 13:14:33|NO.55353
>押したときに重なってるはずなのにたまに判定がないときがある
わかりにくいから最初からそう書いて相手に伝える努力ぐらいしろよ。。
というか当たり判定以外の部分にも直すべき点がたくさんある。
まずawaitを自前で用意するのは勝手だが、その仕様だと常時Coreをまるまる1個専有しててユーザーに優しくない。
そしてredrawの使い方を間違えててやたらチカチカして目に優しくない()。
さらに譜面のBPMによって実行ファイルのFPSが左右されるってのは、何かと不都合な点が多い。
やまぎ 2013/6/30(Sun) 15:56:06|NO.55369
>>MillkeyStars
ありがとうございます。
参考にさせていただきます
やまぎ 2013/6/30(Sun) 16:00:46|NO.55370
>>てれてれ
awaitはどこからか拾ってきたものなのでどういう風になっているのかわかりませんが
これはない方がよいのですか?
redrawの方はたぶん自分のミスです上の方のredrawを1にして下の方を0にすれば直るはずです
BMPによりFPSが左右されるがされないようにするにはどうすればよいでしょう?
一応自分でも調べてみますがよければここで教えていただけるとありがたいです
てれてれ 2013/6/30(Sun) 20:16:46|NO.55389
waitに精度なんて持たせなくても、上から降ってくる棒がズレないような仕様にすれば良い。
例えばmci使って曲が再生されてからどれだけの時間が経過したかをチェックして、
その経過時間を元に上から降ってくる棒の座標を相対的に決めてやればいい。
(mciは環境によって、上手く再生時間が取得出来ない場合もあるらしいが、最近のPC(ツール)ならまず問題ないと思う。)
MillkeyStars 2013/6/30(Sun) 22:29:40|NO.55396
とりあえず、全部一気にやろうとしないで、一つずつがんばってみよう。
一般的なゲームは、一秒間に、60回描画するから、1000 / 60 = 16.6ms を維持できるようにしよう・・・
処理に時間かかる命令はどれか・・・
なんか無駄に処理してるのはないか・・・
などなど。
これは、譜管理の dim で気づいたこと。
譜に関しては、「使用状況・種類・譜ライン場所・現在の譜の高さ」で十分なので
dim humen,4,60 で十分だと思う。
humen(0,cnt) = 未使用:0 / 使用中:1 / 判定済み:2
humen(1,cnt) = 通常:0 / 長押し:1
humen(2,cnt) = z:0 s:1 x:2 d:3 c:4 譜がどの位置にあるか。|0|1|2|3|4| ←こんな感じ
humen(3,cnt) = 譜の落ちてくる現在の高さ位置
まぁ、これは標準的なデータ量で、あとは、譜面データと高さの位置をリンクさせればいい。
データの必要量は、同時に表示できる最大量があれば十分なので。
あと、dim は無駄に確保しないこと。これは、スタック領域に確保できる量が無限ではないのでエラーが起きる。
質問者さんのスクリプトを実行して、esc を 10回くらい押してみればわかると思うけどエラーが起きるので、
バグの温床になりかねない。
描画処理に関しては、どーしても処理が遅くなるので、初期の描画は、buffer などにコピーしてなるべく
一回のコピーであとは譜の描画だけにすると効率がよくなるかも。
>>BMPによりFPSが左右されるがされないようにするにはどうすればよいでしょう?
これって、「Beat Per Minute」(BPM)の事かな?
これは、FPSを固定したときに、描画一回につきの譜の落下幅に影響するだけなので、FPS
を固定されれば、BPM に影響することはない。(処理の遅延などの後処理は必要)
てれてれさんが言うように、mci などで音声データの再生時間と譜をリンクさせる場合は、
再生時間と譜の位置が一致するので、落下幅などの難しい処理は必要がない。
ただ処理時間の関係上、遅延は計算しないとダメ。
やまぎ 2013/6/30(Sun) 22:54:30|NO.55399
みなさまありがとうございました
いろいろと参考にして最後まで作り上げたいと思います
またわからないことがあれば掲示板に貼ると思いますが
その時はまた教えていただけるとありがたいです
ありがとうございました