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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0817
T.K複数表示10解決


T.K

リンク

2014/8/17(Sun) 17:05:05|NO.63891

音ゲーの譜面(楽譜)を複数表示したいのですが

#include "d3m.hsp" //タイマーだけ利用(timeGetTimeを使用してるだけだから精度は良くない) dim key,6 KEY_CODE = 0,'Z','X','C','V','B' KEY_POSX = 41 KEY_POSY = 423 BAR_SIZEX = 100 BAR_SIZEY = 20 PERFECT_LINE = 400 PERFECT_RANGE = 40 //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 gakuhu = "12345" ;0は無表示,1〜5はz〜bボタンを押す tenpo = 80 ;テンポの速さ onebeat = 60000/tenpo //一拍の時間(ms) perfect_tim = (1.0*PERFECT_LINE/480.0)*onebeat //バー発生からPERFECT_LINEまでの時間 movms = (480.0/onebeat) //1msの移動量(1画面の縦サイズを一拍の時間で割る) dim bt1,strlen(gakuhu) dim bt2,strlen(gakuhu) dim bt3,strlen(gakuhu) dim bt4,strlen(gakuhu) dim bt5,strlen(gakuhu) dim gakuhuend repeat 6 sbuf = strmid(gakuhu,cnt,1) if sbuf = "1"{ bt1(cnt)=1 } if sbuf = "2"{ bt2(cnt)=1 } if sbuf = "3"{ bt3(cnt)=1 } if sbuf = "4"{ bt4(cnt)=1 } if sbuf = "5"{ bt5(cnt)=1 } if sbuf = "*"{ gakuhuend=cnt } loop 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 500,0 color 255,255,255 mes ms redraw 1 await 16 loop
↑は譜面が1つずつしか表示できませんでした。どうすれば譜面を複数表示できるでしょうか?



この記事に返信する


たんす

リンク

2014/8/17(Sun) 23:42:21|NO.63918

複数表示というのは、
「1拍目と2拍目を同時に流したい」
「ZレーンとXレーンで同時押しするバーを流したい」
のどちらでしょうか。



あり

リンク

2014/8/18(Mon) 00:07:08|NO.63920

複数の物を同時に動かしたいなら、最低でも1フレーム(メインループ一回)中に
物の数の分だけの座標処理と表示処理が必要です。

スクリプトをざっと見る限り、黄色いバー(譜面?)の座標・表示処理は
1フレームに一回ずつしか行われていないようなので、その辺りから処理を見直して下さい。

処理の流れが分からないのであれば
今やろうとしている事に関係ない処理は一旦コメントアウトして
必要な処理の流れだけ追いかければ大分分かりやすくなります。
(今回の場合ならヒット表示の処理は必要ないのでコメントアウト可能)

それでも難しいのであれば必要な処理だけ組み込んだスクリプトを
一から作り直した方が無理に今のスクリプトを修正するより
結果的に完成が早くなる事も多いです。



T.K

リンク

2014/8/18(Mon) 11:24:23|NO.63928

>たんすさん
1拍目と2拍目を同時に流したいの方です。



きのよー

リンク

2014/8/18(Mon) 19:20:06|NO.63945

思ったのだけれど

dim bt1,strlen(gakuhu) dim bt2,strlen(gakuhu) dim bt3,strlen(gakuhu) dim bt4,strlen(gakuhu) dim bt5,strlen(gakuhu) dim gakuhuend repeat 6 sbuf = strmid(gakuhu,cnt,1) if sbuf = "1"{ bt1(cnt)=1 } if sbuf = "2"{ bt2(cnt)=1 } if sbuf = "3"{ bt3(cnt)=1 } if sbuf = "4"{ bt4(cnt)=1 } if sbuf = "5"{ bt5(cnt)=1 } if sbuf = "*"{ gakuhuend=cnt } loop
ここの変数群があとの処理で全然使われていないのだけれど……



T.K

リンク

2014/8/19(Tue) 11:25:54|NO.63971

皆さん、ありがとうございます。

もうちょっと見直してみたいと思います。



たんす

リンク

2014/8/22(Fri) 01:11:23|NO.64133

複数表示に対応させていたら時間がかかりました。
モジュール型変数を用いて音符(バー)単位で管理しています。

#include "d3m.hsp" //タイマーだけ利用(timeGetTimeを使用してるだけだから精度は良くない) //++++++++バー個別のデータ保持用 #module bar _Lane , _Ypos , flg_Hit #modinit int _p1 , int _p2 , double _p3 , int _p4 //int _p1 :レーン番号(0〜4) //int _p2 :拍番号、楽譜解読時のcnt値を使う //doubke _p3 :Y移動量 //int _p4 :テンポ _Lane = _p1 _Ypos = 480.0 - ( _p3 * _p2 * 60000.0 / _p4) //初期Y位置を計算 flg_hit = 0 //判定したかのフラグ return #modcfunc mod_get_lane //レーン取得用 return _Lane //レーン番号(0〜5)を返す。 #modcfunc mod_get_Ypos //Y位置取得用 return _Ypos //初期Y位置を返す。 #modcfunc mod_get_flg //判定したか否かの状態を取得 return flg_hit #modfunc mod_set_flg int _p5 flg_hit = _p5 return #global //-------- dim key,6 //++++++++定数初期化 KEY_CODE = 'Z','X','C','V','B' KEY_POSX = 41 KEY_POSY = 423 BAR_SIZEX = 100 //バーの幅 BAR_SIZEY = 20 //バーの高さ PERFECT_LINE = 400 //判定線のY座標 PERFECT_RANGE = 40 //PERFECT_LINEから上下にずれてもperfectになるサイズ ON_Draw = 5 //同時表示する拍数 tenpo = 120 ;テンポの速さ onebeat = 60000 / tenpo //一拍の時間(ms) perfect_tim = (1.0 * PERFECT_LINE / 480.0) * onebeat //バー発生からPERFECT_LINEまでの時間 movms = (480.0 / onebeat) / ON_Draw //1msの移動量(1画面の縦サイズを一拍の時間で割る) //変数初期化 dim hit_f,5 //キー入力とバーの判定を行ったら値が1になり、ヒットエフェクトのカウントになる。 dim hit_y,5 //ヒットエフェクトのY位置 dim use_bak,5 //ヒットエフェクトの色を決める値。評価で切り替える。 //-------- //++++++++背景バッファ初期化 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 //判定エリアを仮表示 color 0,0,128 line 0,PERFECT_LINE - PERFECT_RANGE , 500 , PERFECT_LINE - PERFECT_RANGE line 0,PERFECT_LINE + PERFECT_RANGE , 500 , PERFECT_LINE + PERFECT_RANGE color 0,128,0 line 0,PERFECT_LINE - PERFECT_RANGE- PERFECT_RANGE , 500 , PERFECT_LINE - PERFECT_RANGE- PERFECT_RANGE line 0,PERFECT_LINE + PERFECT_RANGE+ PERFECT_RANGE , 500 , PERFECT_LINE + PERFECT_RANGE+ PERFECT_RANGE //-------- //++++++++楽譜準備 gakuhu = "000000112233445506789*" ;0は無表示,1〜5はz〜bボタンを押す dim gakuhuend repeat strlen( gakuhu ) //楽譜変換 sbuf = strmid( gakuhu , cnt , 1 ) //newmod モジュール型変数配列名(mod_v),モジュール型変数タイプ(bar),レーン番号,拍数(cnt),移動量,テンポ if sbuf = "1"{ newmod mod_v,bar,0,cnt,movms,tenpo} //単音のみ if sbuf = "2"{ newmod mod_v,bar,1,cnt,movms,tenpo} if sbuf = "3"{ newmod mod_v,bar,2,cnt,movms,tenpo} if sbuf = "4"{ newmod mod_v,bar,3,cnt,movms,tenpo} if sbuf = "5"{ newmod mod_v,bar,4,cnt,movms,tenpo} if sbuf = "6"{ newmod mod_v,bar,0,cnt,movms,tenpo : newmod mod_v,bar,1,cnt,movms,tenpo} //同時押し対応 if sbuf = "7"{ newmod mod_v,bar,1,cnt,movms,tenpo : newmod mod_v,bar,2,cnt,movms,tenpo} if sbuf = "8"{ newmod mod_v,bar,2,cnt,movms,tenpo : newmod mod_v,bar,3,cnt,movms,tenpo} if sbuf = "9"{ newmod mod_v,bar,3,cnt,movms,tenpo : newmod mod_v,bar,4,cnt,movms,tenpo} if sbuf = "*"{ gakuhuend=cnt} loop //-------- gsel 0 gmode 0 font "",30 start_tim = d3timer() //開始時間 repeat redraw 0 //描写停止 gosub *clr_screen //画面初期化 gosub *get_beat //拍数のカウント etim = d3timer() - start_tim //開始からの経過時間 await 0 repeat 5 //キー入力を判定する。 getkey key(cnt),KEY_CODE(cnt) if key(cnt){ color 64,80,80 boxf cnt * bar_sizeX + 1 , 0 , ( cnt + 1 ) * bar_sizex - 1 , ginfo_sy color 255,255,255 line cnt * bar_sizeX , perfect_line , ( cnt + 1 ) * bar_sizex , perfect_line } color 255 , 255 * key(cnt) , 255 pos KEY_POSX + BAR_SIZEX * ( cnt ) , KEY_POSY mes strf ( "%c" , KEY_CODE( cnt ) ) loop foreach mod_v //バー情報のモジュール変数配列分だけ繰り替えす mod_x = mod_get_Lane( mod_v(cnt) ) //レーン番号をmod_xに代入 mod_y = mod_get_Ypos( mod_v(cnt) ) //初期Y位置をmod_yに代入 mod_y = mod_y + ( movms * etim ) //現在のY位置を算出 color 255,255,255 boxf mod_x * bar_sizex ,mod_y ,( mod_x + 1 ) * bar_sizex ,mod_y + bar_sizey //バーを描写 mod_f = mod_get_flg( mod_v(cnt) ) //判定状態を取得 switch mod_f //判定状態による分岐 //______________ case 0 //未判定 if ( mod_y > ( -3 * PERFECT_RANGE + PERFECT_LINE )) {//バーが判定線に近ければ 判定を開始 if key( mod_x ){ //キー入力がされている hit_f(mod_x) = 1 //hitエフェクト用数値 設定 use = 3 //評価メッセージの 表示寿命 key( mod_x ) = 0 //キー入力状態を初期化 if abs(PERFECT_LINE -( bar_sizey / 2 + mod_y)) <= PERFECT_RANGE {//差がPERFECT_RANGE以下ならperfect ms="perfect" //評価メッセージ設定 use_abk(cnt)=1 //ヒットエフェクトの色計算用 設定 mod_set_flg mod_v(cnt),1 //バー情報に判定結果を記録。 }else{//PERFECT_RANGE*2以下ならgoodでそれより大きければmiss if abs(PERFECT_LINE -( bar_sizey / 2 + mod_y)) <= ( PERFECT_RANGE * 2 ) { ms="good" use_bak(cnt)=2 mod_set_flg mod_v(cnt),2 }else{ ms="miss" use_bak(cnt)=3 mod_set_flg mod_v(cnt),3 } } } } swbreak //_____________ case 1 //パーフェクト 判定後のバーの色 if mod_y < perfect_line{ //判定済み&ライン手前で再びキー入力があったら key(mod_x)=0 //打ち消しておく } color 120,120,255 swbreak //_____________ case 2 //グッド 判定後のバーの色 if mod_y < perfect_line{ //判定済み&ライン手前で再びキー入力があったら key(mod_x)=0 //打ち消しておく } color 200,255,200 swbreak //_____________ case 3 //バッド 判定後のバーの色 if mod_y < perfect_line{ //判定済み&ライン手前で再びキー入力があったら key(mod_x)=0 //打ち消しておく } color 255,64,64 swbreak //_____________ swend boxf mod_x * bar_sizex + 1 ,mod_y + 1 ,( mod_x + 1 ) * bar_sizex - 1 ,mod_y + bar_sizey - 1 //判定後色でバーの内側を塗りつぶし if mod_y > double( ginfo_sy ){ if mod_f = 0{ //無判定で流れた。 ms = "Bad!" use = 3 } delmod mod_v(cnt) //下に流れたバー情報は削除 } await 0 loop ;//ヒット表示 repeat 5 if hit_f(cnt)<6 and hit_f(cnt)>0{ if hit_f(cnt)<4{ //押してから4カウント color 255,255,63+hit_f(cnt)*64 boxf (cnt+1)*bar_sizex,hit_y(cnt)-bar_sizey/2+hit_f(cnt)*3,(cnt+2)*bar_sizex,hit_y(cnt)-bar_sizey/2-hit_f(cnt)*3 } color 255 , 255 - 128 * ( use_bak = 3 ) , 255 - 128 * ( use_bak > 1 ) circle (cnt+1)*bar_sizex - 65 - hit_f(cnt) * 2 , PERFECT_LINE - 15 - hit_f(cnt) * 2 , (cnt+1)*bar_sizex - 35 + hit_f(cnt) * 2 , PERFECT_LINE + 15 + hit_f(cnt) * 2 , 1 circle (cnt+1)*bar_sizex - 80 - hit_f(cnt) * 4 , PERFECT_LINE - 30 - hit_f(cnt) * 4 , (cnt+1)*bar_sizex - 20 + hit_f(cnt) * 4 , PERFECT_LINE + 30 + hit_f(cnt) * 4 , 0 hit_f(cnt)++ } loop //++++++++(判定表示) pos 500,0 color 255,255,255 mes ms //-------- redraw 1 await 16 loop stop end //++++++++画面初期化 *clr_screen pos 0,0 :celput 1//背景画面コピー return //-------- //++++++++拍数のカウント *get_beat if (onebeat*gcnt) <= (d3timer()-start_tim) {//一拍ずつの経過時間を越えた if (use < 0){ //評価が更新されてからのカウントダウンが切れたら ms = "" }else{ use-- } } return //--------

今後の課題
・楽譜の終端まで行っても終わらない。→終端処理を実装する。
・楽譜を一気に読み込んでいるのでメモリを食いすぎる。→拍カウントを利用して、直近のみを準備させる。
・得点の処理?
・もろもろ調整。


参考になれば幸いです。



T.K

リンク

2014/8/22(Fri) 14:50:06|NO.64143

>たんすさん
凄いですね・・・・
わざわざここまでありがとうございます><

とても参考になりました。

あと少しで完成を迎えられそうです。ありがとうございました^^



T.K

リンク

2014/8/22(Fri) 15:17:51|NO.64144

ごめんなさい、最後に・・・

ゲームオーバ判定を追加するにはどうしたらいいですか??

repeat strlen( gakuhu ) //楽譜変換 sbuf = strmid( gakuhu , cnt , 1 ) //newmod モジュール型変数配列名(mod_v),モジュール型変数タイプ(bar),レーン番号,拍数(cnt),移動量,テンポ if sbuf = "1"{ newmod mod_v,bar,0,cnt,movms,tenpo} //単音のみ if sbuf = "2"{ newmod mod_v,bar,1,cnt,movms,tenpo} if sbuf = "3"{ newmod mod_v,bar,2,cnt,movms,tenpo} if sbuf = "4"{ newmod mod_v,bar,3,cnt,movms,tenpo} if sbuf = "5"{ newmod mod_v,bar,4,cnt,movms,tenpo} if sbuf = "6"{ newmod mod_v,bar,0,cnt,movms,tenpo : newmod mod_v,bar,1,cnt,movms,tenpo} //同時押し対応 if sbuf = "7"{ newmod mod_v,bar,1,cnt,movms,tenpo : newmod mod_v,bar,2,cnt,movms,tenpo} if sbuf = "8"{ newmod mod_v,bar,2,cnt,movms,tenpo : newmod mod_v,bar,3,cnt,movms,tenpo} if sbuf = "9"{ newmod mod_v,bar,3,cnt,movms,tenpo : newmod mod_v,bar,4,cnt,movms,tenpo} if sbuf = "*"{ gakuhuend=cnt} loop

の 
sbuf = strmid( gakuhu , cnt , 1 )

sbuf  = peek(gakuhu,gcnt)-'0'
	if sbuf  < 0 {break}
に置き換えればいいのでしょうか?



たんす

リンク

2014/8/22(Fri) 18:02:45|NO.64149

楽譜の終了は、
拍数をカウントして終了拍を少し過ぎたころに終了処理を入れることで実装できます。

//++++++++拍数のカウント *get_beat if ( onebeat * gcnt ) <= ( d3timer() - start_tim ) {//一拍ずつの経過時間を越えた if (use < 0){ //評価が更新されてからのカウントダウンが切れたら ms = "" }else{ use -= 1 } if (gakuhuend + 2) < gcnt{ //終了点を少し越えて、終了処理 dialog "終了!" end } gcnt += 1 //現在の拍数をカウントアップ } return //--------



T.K

リンク

2014/8/23(Sat) 02:16:07|NO.64167

ありがとうございます。助かります。



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