|
|
|
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
| |
|
2013/10/25(Fri) 13:04:44|NO.57797
ソース丸々貼り付けるのはやめた方がいいと言ったのに……
「ある変数の値をソースコード上で弄ったら思う通りに表示されなくなった」ということは、
「そのソースコードを完全に理解していない」のと同じじゃあないのか。
HSP掲示板の利用規約を持ち出すなら、投稿時の注意に
>11.不要部分の多い長いスクリプトの投稿はご遠慮ください。
と書いてある。スレ主のスクリプトはそれにあたるのではないであろうか。
なぜなら、どこで問題が起こっているかを多少なりとも自力で調べず、
ソース全体を貼り付けているから。
少し言葉遣いが強くなってしまったが、スレ主が改善してくれることを願っている。
|
|
2013/10/25(Fri) 13:06:27|NO.57798
まあ、暇な人がいれば質問に答えてくれると思うよ。
多分な。
|
|
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画面の縦サイズを一拍の時間で割る)
|
|
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等)のを参考にすれば良い
| |
|
2013/10/27(Sun) 18:34:28|NO.57849
暇人さん、いろいろとありがとうございます。
がんばってみます。
|
|