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


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
1025
Yozane音ゲーのテンポについて6解決


Yozane

リンク

2013/10/25(Fri) 11:49:28|NO.57795

音ゲーで譜面の落ちてくるテンポを変えたいのですが、tempoあたりをこうしたら↓譜面が途中で消えてしまってバー発生からPERFECT_LINEまでの時間をいじってもうまくいかないのですが
どう変更したらいいでしょうか?

; stick命令によるメニュー選択サンプル ; cls 4 color 255,255,255 pos 230,180:mes "Stert Music!" a=1 x=280:y=180:sel=0:maxsel=3 *selmain color 0,0,0:boxf x,y,x+20,y+20 y=sel*20+180 color 255,255,255 pos x,y:mes "⇔" *selloop stick a,1 if a&2 : a=-1:goto *selchg if a&8 : a=1:goto *selchg if a&$30 : goto *selok await 10:goto *selloop *selchg a=a+sel if (a<0)or(a>maxsel) : a=sel sel=a:goto *selmain *selok *sound_play ; ファイル読み込みダイアログ dialog "wav;*.mp3;*.mid;*.wma", 16, "   " if stat = 0 : stop mes "ファイルパス: "+refstr ; 音楽ファイルの読み込み mmload refstr, 0 ; 音楽ファイルの再生 mmplay 0 #include "d3m.hsp" //タイマーだけ利用(timeGetTimeを使用してるだけだから精度は良くない) dim key,6 KEY_CODE = 0,'C','V','B','N','M' KEY_POSX = 41 KEY_POSY = 423 BAR_SIZEX = 100 BAR_SIZEY = 20 PERFECT_LINE = 400 PERFECT_RANGE = 30 //PERFECT_LINEから上下にずれてもperfectになるサイズ //背景バッファ初期化 buffer 1 color 0,0,0 :boxf:color 255,255,255 repeat 5 line BAR_SIZEX+cnt*BAR_SIZEX,0,BAR_SIZEX+cnt*BAR_SIZEX,640 loop line 0,PERFECT_LINE,500,PERFECT_LINE gsel 0 notesel gakuhu noteload "譜面.txt" tenpo = 128.5 ;テンポの速さ onebeat = 60000/tenpo //一拍の時間(ms) perfect_tim = (1.0*PERFECT_LINE/480.0)*onebeat //バー発生からPERFECT_LINEまでの時間 movms = (60.0/onebeat) //1msの移動量(1画面の縦サイズを一拍の時間で割る) font "",30 start_tim = d3timer() //開始時間 repeat redraw 0 gmode 0 pos 0,0 celput 1//背景画面コピー if (onebeat*gcnt) <= (d3timer()-start_tim) {//一拍ずつの経過時間を越えた use=0 gaku=int(strmid (gakuhu,gcnt,1)) bar_start_tim=onebeat*gcnt //バー発生時間 gcnt+1 } etim=d3timer()-start_tim //開始からの経過時間 bar_tim=etim-bar_start_tim //バー発生からの経過時間(これにmovmsを掛けてバー座標にする) repeat 6-1,1 getkey key(cnt),KEY_CODE(cnt) color 255,255*key(cnt),255 pos KEY_POSX+BAR_SIZEX*(cnt-1),KEY_POSY mes strf("%c",KEY_CODE(cnt)) loop if gaku { if use=0 { color 255,255,0 boxf (gaku*BAR_SIZEX)-BAR_SIZEX,movms*bar_tim-BAR_SIZEY/2,gaku*BAR_SIZEX,movms*bar_tim+BAR_SIZEY/2 //バーの基準点を中央に変更 } } //ヒット表示 if hitf<6 and hitf>0{//perfect=白、good=黄色、miss=赤 if hitf<4 { color 255,255,63+hitf*64 boxf hit_line_posx-BAR_SIZEX,hit_line_posy-BAR_SIZEY/2+hitf*3,hit_line_posx,hit_line_posy+BAR_SIZEY/2-hitf*3 } color 255,255-128*(use_bak=3),255-128*(use_bak>1) circle hit_line_posx-65-hitf*2,PERFECT_LINE-15-hitf*2,hit_line_posx-35+hitf*2,PERFECT_LINE+15+hitf*2,1 circle hit_line_posx-80-hitf*4,PERFECT_LINE-30-hitf*4,hit_line_posx-20+hitf*4,PERFECT_LINE+30+hitf*4,0 hitf++ } if (key(gaku)=1)&(use=0)&(gaku!0) { hitf=1 //ヒット表示フラグ hit_line_posx=gaku*BAR_SIZEX hit_line_posy=movms*bar_tim //ヒットした時の座標を保存 if abs(PERFECT_LINE-hit_line_posy) <= PERFECT_RANGE {//差がPERFECT_RANGE以下ならperfect ms="PERFECT" :use=1 }else{//PERFECT_RANGE*2以下ならgoodでそれより大きければmiss if abs(PERFECT_LINE-hit_line_posy) <= (PERFECT_RANGE*2) {ms="GOOD" :use=2}else{ms="MISS" :use=3 } } use_bak=use } pos 200,200 color 255,255,255 mes ms redraw 1 await 16 #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// 基準設定。これを音ゲーのループの前に置く。 loop



この記事に返信する


check

リンク

2013/10/25(Fri) 13:04:44|NO.57797

ソース丸々貼り付けるのはやめた方がいいと言ったのに……

「ある変数の値をソースコード上で弄ったら思う通りに表示されなくなった」ということは、
「そのソースコードを完全に理解していない」のと同じじゃあないのか。

HSP掲示板の利用規約を持ち出すなら、投稿時の注意に
>11.不要部分の多い長いスクリプトの投稿はご遠慮ください。
と書いてある。スレ主のスクリプトはそれにあたるのではないであろうか。

なぜなら、どこで問題が起こっているかを多少なりとも自力で調べず、
ソース全体を貼り付けているから。

少し言葉遣いが強くなってしまったが、スレ主が改善してくれることを願っている。



check

リンク

2013/10/25(Fri) 13:06:27|NO.57798

まあ、暇な人がいれば質問に答えてくれると思うよ。
多分な。



Yozane

リンク

2013/10/25(Fri) 13:25:39|NO.57800

すみませんね
ここをどう変えたらいいでしょうか?

notesel gakuhu noteload "譜面.txt" tenpo = 128.5 ;テンポの速さ onebeat = 60000/tenpo //一拍の時間(ms) perfect_tim = (1.0*PERFECT_LINE/480.0)*onebeat //バー発生からPERFECT_LINEまでの時間 movms = (60.0/onebeat) //1msの移動量(1画面の縦サイズを一拍の時間で割る)



check

リンク

2013/10/25(Fri) 18:18:34|NO.57807

そもそも"譜面.txt"が無いから実行できない。
何も外部ファイルがなくても実行できるようにしたほうがいい、
という俺のアドバイスは無視されているのか。

問題があるのは
>movms = (60.0/onebeat) //1msの移動量(1画面の縦サイズを一拍の時間で割る)
ここだろう。
なぜ画面の高さを変えているんだ?

後、Stert MusicはStart Musicの誤りか?



暇人

リンク

2013/10/26(Sat) 23:38:40|NO.57830

NO.57795そのモジュールの使い方は間違ってると書いたと思うんだが・・・
>movms = (60.0/onebeat) //1msの移動量(1画面の縦サイズを一拍の時間で割る)
一拍で進む移動量と同じ意味になる(上のだとmovms*onebeat=60.0の意味)
画面上の速度を変えたいなら割る方を変えるonebeatは一拍だから
480.0/(onebeat*4)にしてやれば1小節分の時間で480ドット進むようになる

ただ複数の表示に対応してないので結局次の一拍で先に表示されてるのが消える
これはgaku等のバー表示関係の変数を配列にして複数対応にすれば良い


キー判定部分を省いて複数表示対応にしたサンプル
ただ、NO.57795のとは結構変ってる(時間をnote側のCOUNT単位にして処理するようにした)
モジュールはNO.57795のとは別物なので注意

;高分解能パフォーマンスカウンタモジュール #module "mod_qpc" #uselib "kernel32.dll" #func QueryPerformanceFrequency "QueryPerformanceFrequency" sptr #func QueryPerformanceCounter "QueryPerformanceCounter" sptr //モジュール初期化 #deffunc QueryPerformance_init dim qpf,2 dim qpc,2 ddim qpt,1 QueryPerformanceFrequency varptr(qpf) if stat=0 {return -1} pf2=((4294967296.0+qpf)\4294967296.0)//符号付きintを正の数のdoubleにする pf2=(pf2+4294967296.0*qpf(1))//64ビットintをdoubleにする QueryPerformanceCounter varptr(qpc) if stat=0 {return -1} stqpc=((4294967296.0+qpc)\4294967296.0) stqpc=(stqpc+4294967296.0*qpc(1)) return 0 //---------QueryPerformance_init実行からの時間を単位を指定して取得-------- //GetQPtime(p1) // p1 = 何分の1秒かを指定(省略時1000)[ミリ秒なら1000] //整数部が指定単位になる #define global ctype GetQPtime(%1=1000) _GetQPtime(%1) #defcfunc _GetQPtime int q QueryPerformanceCounter varptr(qpc) qpt=((4294967296.0+qpc)\4294967296.0) return ((qpt+4294967296.0*qpc(1))-stqpc)/pf2*q #global QueryPerformance_init //高分解能パフォーマンスカウンタを初期化してGetQPtime()が使えるようにする ;dim key,7 //大文字の変数名は曲読み込み後変更無し ;KEY_CODE = 0,'C','V','B','N','M',' ' KEY_POSX = 41 KEY_POSY = 423 BAR_SIZEX = 100 BAR_SIZEY = 20 PERFECT_LINE = 400.0 //PERFECTタイミングの画面上の座標 //背景バッファ初期化 buffer 1 color 0,0,0 :boxf:color 255,255,255 repeat 5 line BAR_SIZEX+cnt*BAR_SIZEX,0,BAR_SIZEX+cnt*BAR_SIZEX,640 loop line 0,PERFECT_LINE,500,PERFECT_LINE gsel 0 BAR_COUNT = 10000.0 //1小節のカウント(COUNT単位とする) QUARTER_NOTE_COUNT = BAR_COUNT/4 //四分音符分のカウント PERFECT_RANGE_COUNT = BAR_COUNT/16 //PERFECT_LINEから上下にずれてもperfectになるCOUNT (BAR_COUNT/16は16分音符分を表す) QUARTER_NOTE_MAX=8 //PERFECT_LINEまでに四分音符何個縦に分置けるようにするか MOVE_SPEED = PERFECT_LINE/(QUARTER_NOTE_COUNT*QUARTER_NOTE_MAX) //1COUNTの移動量(任意サイズを指定COUNTで割る QUARTER_NOTE_COUNT*8なら4分音符8個分で2小節分) ;notesel note_dat ;noteload "譜面.txt" note_dat={"123456565432101012233224545"} ddim note_start_count,1 dim note_f,1 total_count=0.0 note_max=0 //譜面データからnoteを取り出し全てnote_start_count、note_keyに登録して判定有効フラグnote_fをセット repeat strlen(note_dat) note_key(note_max)=int(strmid(note_dat,gcnt,1)) if note_key(note_max) {//0以外なら発生カウントを設定してnote_max+1 note_start_count(note_max)=total_count //note発生カウントセット note_f(note_max)=1 //表示しても判定は無効にしたい時用のフラグ note_max++ } total_count+QUARTER_NOTE_COUNT gcnt+1 loop font "",30 Bpm = 128.5 ;1分間の4分音符の数(テンポ) start_tim = GetQPtime()+5000 //開始時間(+5000は5秒後に最初の小節がPERFECT_LINEに到達するようにしてる) repeat redraw 0 gmode 0 pos 0,0 celput 1//背景画面コピー onebeat =60000.0/Bpm//一拍の時間(ms) //今回は使ってないけど曲の途中でBpmを変える事もあるのでゲームループに置いてる count_factor=onebeat/QUARTER_NOTE_COUNT //経過時間(ms)をcount_factorで割るとCOUNT単位になる etim=GetQPtime()-start_tim //開始からの経過時間 etim_count=etim/count_factor //経過時間を経過カウントに変換(0以上なら最初の小節がPERFECT_LINEを超えた) screen_First_count=etim_count+PERFECT_LINE/MOVE_SPEED //画面の一番上を示すcount screen_Fast_count=etim_count-(double(ginfo_winy)-PERFECT_LINE)/MOVE_SPEED //画面の一番下を示すcount // 小節ラインを表示 color 100,100,100 bar_line=(etim_count\BAR_COUNT)*MOVE_SPEED //経過カウントを基に小節ラインを表示 repeat QUARTER_NOTE_MAX/4+2 //何本表示するか(QUARTER_NOTE_MAXを4で割って小節数にする、確実に表示させたいから+2) line 0,PERFECT_LINE+bar_line-MOVE_SPEED*BAR_COUNT*cnt,640,PERFECT_LINE+bar_line-MOVE_SPEED*BAR_COUNT*cnt loop //note表示処理 repeat note_max if note_key(cnt)>0 and note_start_count(cnt)<screen_First_count { //noteがセットされてて画面内countなら表示処理 if note_start_count(cnt)<screen_Fast_count {note_key(cnt)=0}//画面外にでたらnoteクリア color 255,255,0 note_rest_count=note_start_count(cnt)-etim_count//PERFECT_LINEとのずれCOUNT(正ならまだ到達してない負なら超えた) if note_rest_count>(-PERFECT_RANGE_COUNT*5) and note_f(cnt)=1 { //ここに来れる物だけ判定すれば良い(デバッグ用にこうしてるだけでここで判定する必要はない) if abs(note_rest_count)<=PERFECT_RANGE_COUNT {//PERFECT範囲だったら赤で表示(デバッグ用) color 255 }else{ if abs(note_rest_count)<PERFECT_RANGE_COUNT*3 {color 0,,255}//PERFECTの外でPERFECT_RANGE_COUNT*3以内だったら青で表示(デバッグ用) } }else{//判定範囲を超えたので判定フラグクリア note_f(cnt)=0 } //MOVE_SPEED*note_rest_countが0の時にPERFECT_LINE座標になる boxf (note_key(cnt)*BAR_SIZEX)-BAR_SIZEX,PERFECT_LINE-MOVE_SPEED*note_rest_count-BAR_SIZEY/2,note_key(cnt)*BAR_SIZEX,PERFECT_LINE-MOVE_SPEED*note_rest_count+BAR_SIZEY/2 //noteの基準点を中央にして表示 } loop redraw 1 await 16 title "小節数("+int(etim_count/BAR_COUNT)+") 経過count("+etim_count+") 経過時間("+etim+")" loop
同じ高さに複数noteを表示したり
note間隔を変更(音符の長さを可変にする)したいなら
まず譜面のフォーマットが、それに対応した書式にする必要がある
自分で考えるか既にある(BMS等)のを参考にすれば良い



Yozane

リンク

2013/10/27(Sun) 18:34:28|NO.57849

暇人さん、いろいろとありがとうございます。
がんばってみます。



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