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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0310
ミント選択肢の処理を正常に作動させたい13解決


ミント

リンク

2012/3/10(Sat) 11:06:58|NO.45328

どうもこんにちは。そうでない方は始めまして。
さて・・・久しぶりに質問するハメになったんだが・・・きっと自分の考え方が悪い・・・orz
後もうちょっとで出来ると思うんだけど、そのもうちょいがわからねぇ・・・


 【やりたいこと】 
最初っからやり直す → はい
            いいえ

はい   → (今は何も無いですが、本ソースでは処理出来てます)
いいえ  → 「最初っからやり直す」にカーソルが戻る
 ↑
この「いいえ」の部分


 いつもどおりソースです つ
------------------------------------------

screen 0,640,480 ;***************メインループ************ *メイン redraw 2 : color : boxf ;***************カウンター************** color 255, pos 0,0 : mes "メインメニューのカウント(MNI_c) " + MNI_c pos 0,20 : mes "Zキーカウント(ZKE_c) " + ZKE_c pos 0,40 : mes "はい、いいえカウント(HI_IIE_c) " + HI_IIE_c pos 0,60 : mes "最初っからフラグ(SI_HI_f) " + SI_HI_f pos 0,80 : mes "いいえカウント(IIE_c) " + IIE_c if(ZKE_c >= 2) : pos 0,120 : mes "はいが押されました " ;*************************************** getkey Zkey,90 ;決定(Zキー) if MNI_c == 1 { ;2番目のメニューにカーソルがある場合, if Zkey { ;Zキーを押した場合 = 実行 SI_HI_f = 1 ;最初っからやりなおすフラグ ([はい、いいえ]のカーソルが動いた数を数えるためのフラグ) if cek = 0 : ZKE_c++ : cek = 1 ;Zキーカウント } else { cek = 0 } ;はいを選択した場合 if HI_IIE_c == 0 { ;[はい]の場所にカーソルがある場合 = 実行 if(ZKE_c >= 1): ZKE_c+1 } ;いいえを選択した場合 if HI_IIE_c == 1 AND Zkey { ;[いいえ]の場所にカーソルがある場合,Zキーを押した場合 = 実行 SI_HI_f = 0 ;最初っからやりなおすフラグ ([はい、いいえ]のカーソルが動かないようにする) //HI_IIE_c = 0 ;[はい、いいえ]カウント //ZKE_c-1 ;Zキーカウントをマイナス ([はい、いいえ]の表示を消す) if cek1 = 0 : cek1 = 1 } else { cek1 = 0 } ;数ストッパー (Zキーを押すと,条件が成り立って,Zキーカウントが増えていくための防止) if(ZKE_c >= 2): ZKE_c-1 ;[はい]にカーソルを合わせると,Zキーカウントが増えていくための防止 if(ZKE_c <= -1): ZKE_c+1;[いいえ]を実行した後,Zキーを押すと増えていくための防止 } getkey Xkey,88 ;キャンセル(Xキー) if Xkey { ;Xキーを押したら実行 SI_HI_f = 0 ;最初っからやりなおすフラグ ([はい、いいえ]のカーソルが動かないようにする) HI_IIE_c = 0 ;[いいえ]でキャンセルされてもいいようにする } ;[はい、いいえ]から戻れる if (ZKE_c >= 1) { ;Zキーカウントが1以上の時 = 実行 if Xkey : ZKE_c-1 ;キャンセルされた場合、Zキーカウントをマイナス1 ([はい、いいえ]の表示を消す) } ;************キーを読むこむ************* stick kaso ;カーソルキー取得 if ( kaso & 2 ) { ;↑ボタン gosub *↑ボタン } if ( kaso & 8 ) { ;↓ボタン gosub *↓ボタン } ;*************文字を出す**************** if ( MNI_c == 0 ) { color 255,255,255 : pos 130,200 : mes "一時停止解除" ;白 } else { color 77,67,64 : pos 130,200 : mes "一時停止解除" ;黒 } ;最初っからやりなおす if ( MNI_c == 1 ) { color 255,255,255 : pos 130,240 : mes "最初っからやりなおす" ;白 } else { color 77,67,64 : pos 130,240 : mes "最初っからやりなおす" ;黒 } ;**************[はい,いいえ]************ ;はい if ZKE_c >= 1 { ;Zキーが押されたら見える if ( HI_IIE_c == 0 ) { color 255,255,255 : pos 330,230 : mes "はい" ;白 } else { color 77,67,64 : pos 330,230 : mes "はい" ;黒 } ;いいえ if ( HI_IIE_c == 1 ) { color 255,255,255 : pos 330,250 : mes "いいえ" ;白 } else { color 77,67,64 : pos 330,250 : mes "いいえ" ;黒 } } redraw : await 15 goto *メイン ;*************↑ボタン****************** *↑ボタン if SI_HI_f = 0 { ;最初っからやりなおすフラグ (押されてない場合は,普通のカーソル数で動く) MNI_c -- if ( MNI_c < 0 ) : MNI_c = 1 } ;最初っからやり直すにカーソルがある場合 AND [はい、いいえ]フラグがたった場合, if MNI_c == 1 AND SI_HI_f = 1 { ;[はい、いいえ]のカーソル数をカウントする HI_IIE_c -- if ( HI_IIE_c < 0 ) : HI_IIE_c = 1 } return ;*************↓ボタン****************** *↓ボタン if SI_HI_f = 0 { ;最初っからやりなおすフラグ (押されてない場合は,普通のカーソル数で動く) MNI_c ++ MNI_c \= 2 } ;最初っからやり直すにカーソルがある場合 AND [はい、いいえ]フラグがたった場合, if MNI_c == 1 AND SI_HI_f = 1 { ;[はい、いいえ]のカーソル数をカウントする HI_IIE_c ++ HI_IIE_c \= 2 } return
---------------------------------------------
 【コメントアウトがなっているところの説明】 (HI_IIE_c = 0)
「いいえ」を選択したさいに、元の選択肢に戻せばいい。それが (HI_IIE_c = 0)
けどこれだと、Zキーを押した瞬間に(HI_IIE_c = 0)になって
「はい」にカーソルが動いてしまう。当然の結果ですね・・・



if MNI_c == 1 { ;2番目のメニューにカーソルがある場合, if Zkey { ;Zキーを押した場合 = 実行 SI_HI_f = 1

が実行されているから「SI_HI_f = 1」のフラグがたっちゃう。
だったら
>>if Zkey { ;Zキーを押した場合 = 実行
のところに「AND HI_IIE_c = 0」を入ればいいんじゃねー?っと思ったら余計ひどくなった。



もう一個の「コメントアウト」の「//ZKE_c-1」は
「HI_IIE_c = 0」を「コメントアウト」した場合、「//ZKE_c-1」の「コメントアウト」を解除しないといけない。



っとここまでが、試したこと&説明になります。
>>SI_HI_f = 1 ;最初っからやりなおすフラグ ([はい、いいえ]のカーソルが動いた数を数えるためのフラグ)
今回()を使ってみたけど、どうかな?
この()の中だけをコメントにするべきかな?と思いつつも悩んでこのようにしちゃったんだけど・・・



アドバイス、または考え方がダメ!とかでもいいです。
正直この方法でいいのか不安なんだぜ・・・
まぁ、そんなわけでよろしくお願いいたします。



この記事に返信する


たんす

リンク

2012/3/10(Sat) 14:43:02|NO.45334

改造したのは4点です。
・複数階層のメニューを管理するのにswitch〜swendを使いました。
・Zキーの入力が連続で判定されてしまったようなので待ち時間を設けました。
・上下キーの入力を簡素化しました。
・メニュー表示のif文をまとめました。


;==========既存の変数と説明 MNI_c=0 ;第一層メニュー選択アイテム HI_IIE_c=0 ;第二層メニュー選択アイテム ZKE_c=0 ;メニュー全体の管理変数?未使用 Zkey=0 ;Zキー入力状態 Xkey=0 ;Xキー入力状態 IIE_c=0 ;?未使用 cek=0 ;?未使用 SI_HI_f=0 ;?未使用 kaso=0 ;上下の入力 ;==========以下:追加した変数 Zkey_wait=0 ;入力間隔をあけるための待ち時間 Active_LayerID=0 ;アクティブ層ID screen 0,640,480 ;***************メインループ************ *メイン redraw 2 : color : boxf ;***************カウンター************** color 255, pos 0,0 : mes "メインメニューのカウント(MNI_c) " + MNI_c pos 0,20 : mes "はい、いいえカウント(HI_IIE_c) " + HI_IIE_c pos 0,40 : mes "アクティブ層ID(Active_LayerID) " + Active_LayerID if(Active_LayerID >= 2) : pos 0,120 : mes "はいが押されました " ;*************************************** await 10 if Zkey_wait=0{ ;一度Zが押されたら、しばらく判定しないように getkey Zkey,90 // title "待ち時間なし" }else{ // title "待ち時間残り"+(Zkey_wait*10)+"ms" Zkey_wait--;待ち時間の消化 if Zkey_wait<0{ Zkey_wait=0 ;もしマイナスになってしまったら0に戻す } } if Zkey{ ;Zが押されたら以下の判定 Zkey=0 Zkey_wait=10 ;待ち時間の設定[Z_wait*10ms] switch Active_LayerID ;Active_LayerIDの値により分岐します。 case 0 ;「解除or最初から」選択中 if MNI_c{ ;「最初から」でZ入力 Active_LayerID++ ;次の層へ移行 }else{ ;「解除」でZ入力 } swbreak case 1 ;「はいorいいえ」の選択中 if HI_IIE_c{;「いいえ」でZ入力 Active_LayerID-- ;カーソルを「解除or最初から」に戻す }else{ ;「はい」でZ入力 Active_LayerID++ ;次の層へ移行 } swbreak case 2 ;「はい」が押されたあとにZ入力 Active_LayerID-- ;「はいorいいえ」に戻す Zkey=0 ;Z入力状態を解除 swbreak swend } ;Z入力時の処理 終了 getkey Xkey,88 ;キャンセル(Xキー) if Xkey { ;Xキーを押したら実行 Active_LayerID=0 } ;************キーを読むこむ************* stick kaso ;カーソルキー取得 if ( kaso & 2 ) { ;↑ボタン gosub *↑ボタン } if ( kaso & 8 ) { ;↓ボタン gosub *↓ボタン } ;*************文字を出す**************** if ( MNI_c == 0 ) { color 255,255,255 : pos 130,200 : mes "一時停止解除" ;白 color 77,67,64 : pos 130,240 : mes "最初っからやりなおす" ;黒 } else { color 77,67,64 : pos 130,200 : mes "一時停止解除" ;黒 color 255,255,255 : pos 130,240 : mes "最初っからやりなおす" ;白 } ;**************[はい,いいえ]************ if Active_LayerID >= 1 { ;第二層(はい、いいえ)以降で表示 if ( HI_IIE_c == 0 ) { color 255,255,255 : pos 330,230 : mes "はい" ;白 color 77,67,64 : pos 330,250 : mes "いいえ" ;黒 } else { color 77,67,64 : pos 330,230 : mes "はい" ;黒 color 255,255,255 : pos 330,250 : mes "いいえ" ;白 } } redraw : await 15 goto *メイン ;*************↑ボタン****************** ;*************↓ボタン****************** ;選択項目が2種類ずつしかない場合に限る(状態の値が[0]と[1]で交互に切り替わる) *↑ボタン *↓ボタン switch Active_LayerID case 0;[解除、最初から]選択中 MNI_c=1-MNI_c swbreak case 1;[はい、いいえ]選択中 HI_IIE_c=1-HI_IIE_c swbreak case 2 ;「はい」が選択されたとき Active_LayerID=1 ;「はいorいいえ」選択中に戻す swend return



ミント

リンク

2012/3/11(Sun) 21:56:50|NO.45372

遅くなりました。

たんすさんソースありがとうございます ペコリ(o_ _)o))
さて、今から解析に入りますので少々お時間いただきます・・・
とりあえずレス見ましたよっていう返事のみとさせていただきます。

「理解したら or わからなかったら」また書きににきます。


こういうのは(レス見ましたよとか)書く必要ないけど、書くとやる気がでるんだよね〜
今から自分と勝負してきます!



ミント

リンク

2012/3/11(Sun) 23:31:35|NO.45375

解析終わりました。

「switch」の命令は使用したことなかったので、その機能に驚いています。
前々から知り合いから言われてたけどこういう意味ね・・・

「switch」は「一種の[if]みたいな物」っていう解釈でいいのかな?
これを使用すると余計なインデントがなくなり見やすくなりますねぇ〜
それにインデントによるミスもなくなりかなりいいです (多かったり、少なかったりするのは誰もが通る道)



switch case ;比較したい値 swbreak
を書くだけですぐに判断できるのはいいですね。
「switch」は1回用意すればいいだけなので、2個目以降は「case , swbreak」だけでいいとか・・・すごい!



まとめられるところを色々見落とてたんですけど、たんすさんが改善してくれたおかげで、 新しく気付けたものがありました。
後「*↑ボタン、*↓ボタン」
コメントにも書いてあるけど、確かにこれは2種類しかない場合のみしか出来ませんね。

MNI_c = 1-MNI_c ;1週目:どっちに動かそうが,[1]になるのでカーソルが動く ;2週目:1週目の[1]の値が入っているので,[1-1]で[0]になるのでカーソルが動く
本ソース2種類を超える項目があるので、「別の方法、これを改良したもの」を考えないとね。
まぁ、それは次のステップなので今はこのソースを使いこなす方が先。


たんすさんわかりやすいソースと内容。ありがとうございます!
余談だけど「Zキーの役割とかを書くのを」たんすさんのソース見てから思い出すという・・・やらかしたぁ・・・





後気になった部分があったので質問させていただきます!
出来れば答えてほしいです!お手数ですがすいません><
 【Q1】

if Zkey_wait<0{ Zkey_wait=0 ;もしマイナスになってしまったら0に戻す }
の「Zkey_wait=0」は無くっても問題ないのはわかっていると思いますが、
これは「もしマイナスになってしまったら」という応急処置っていうか、バグ?ん〜なんて言ったらいいだろう・・・
とりあえず、そんな感じなのを見越してのあれですよね?


 【Q2】

case 2 ;「はい」が押されたあとにZ入力 Active_LayerID-- ;「はいorいいえ」に戻す Zkey=0 ;Z入力状態を解除
これの「Zkey=0」はコメントアウトしても動作に問題なかったので、なんであるのかわからない・・・
もし自分のデバッグ不足なら申し訳ねぇ・・・


 【Q3】

case 2 ;「はい」が押されたあとにZ入力 Active_LayerID-- ;「はいorいいえ」に戻す Zkey=0 ;Z入力状態を解除 swbreak swend
ここでは「swbreak」を使って〆てある。


case 2 ;「はい」が選択されたとき Active_LayerID=1 ;「はいorいいえ」選択中に戻す swend
ここだと「swbreak」を使って〆てない。
「swend」前にある「case」を処理する場合、「swbreak」を使って〆るなくっても大丈夫なのかな?
ヘルプで見た感じだとどっちかわからないけど、役割的に考えると「swbreak」で〆る必要がないだろうけど
心配な私はつい聞きたくなっちゃうんだぜ・・・ (悪い癖その1:考えすぎ)



たんす

リンク

2012/3/11(Sun) 23:54:11|NO.45376

【A1】
念のためです。
しかし、少し上のif条件を

if Zkey_wait=0{ ;一度Zが押されたら、しばらく判定しないように
から

if Zkey_wait<=0{ ;一度Zが押されたら、しばらく判定しないように
にすると、不要になりますね。


【A2】
消し忘れです。
すべてのcaseでZkey=0にしてましたが、「共通じゃね?」と思い消してたのですが^^;


【A3】
最期のswbreakは不要です。
caseの順番は影響しないはずなのですが、
調整中にcaseの順番を入れ替えたりしていたので選択肢の部分にはswbreakをつけていました。

しかし、ミスを無くす&他人が読みやすくなるために
「case〜swbreak」はセットで覚えておくと良いと思います。



たんす

リンク

2012/3/12(Mon) 02:34:59|NO.45377

選択肢が複数存在する場合について、実際に考えてみました。

1、↑↓キーにカーソルの移動量(kaso_add)を割り当てます。
2、ZKE_cの値により分岐させ、カーソル位置変数に移動量(kaso_add)を加えます。
3、上限、下限を超えたときの処理をします。(ループさせる、させないもここで決定)

また、選択肢表示も変えてみました。
1、すべてのカーソル位置に黒で書いておきます。
2、黒で書き終えたら「switch HI_IIE_c」により個別に白文字で書き重ねます。

【おまけ】←キーで一番上へ、→キーで一番下へカーソル移動させてみました。


;前略 ;************キーを読むこむ************* stick kaso ;カーソルキー取得 ;入力されたキーごとに、カーソルの移動量を設定してカーソル処理に飛ばします。 if ( kaso & 2 ) { ;↑ボタン kaso_add=-1 gosub *↑↓←→ボタン } if ( kaso & 8 ) { ;↓ボタン kaso_add=1 gosub *↑↓←→ボタン } if ( kaso & 1 ){;←キー kaso_add=-50;極端なマイナス gosub *↑↓←→ボタン } if ( kaso & 4 ){;→キー kaso_add=50;極端なプラス gosub *↑↓←→ボタン } ;*************文字を出す**************** if ( MNI_c == 0 ) { color 255,255,255 : pos 130,200 : mes "一時停止解除" ;白 color 77,67,64 : pos 130,240 : mes "最初っからやりなおす" ;黒 } else { color 77,67,64 : pos 130,200 : mes "一時停止解除" ;黒 color 255,255,255 : pos 130,240 : mes "最初っからやりなおす" ;白 } ;**************[はい,いいえ]************ if Active_LayerID >= 1 { ;第二層(はい、いいえ)以降で表示 ;すべての選択肢を黒で書いておく color 77,67,64 : pos 330,230 : mes "はい" ;黒 color 77,67,64 : pos 330,250 : mes "いいえ" ;黒 color 77,67,64 : pos 330,270 : mes "いい絵" ;黒 color 77,67,64 : pos 330,290 : mes "いい家" ;黒 ;カーソル位置だけ白く書き直す switch HI_IIE_c case 0 color 255,255,255 : pos 330,230 : mes "はい" ;白 swbreak case 1 color 255,255,255 : pos 330,250 : mes "いいえ" ;白 swbreak case 2 color 255,255,255 : pos 330,270 : mes "いい絵" ;白 swbreak case 3 color 255,255,255 : pos 330,290 : mes "いい家" ;白 swbreak swend } redraw : await 15 goto *メイン ;*************↑↓←→ボタン****************** *↑↓←→ボタン switch Active_LayerID case 0;[解除、最初から]選択中 MNI_c =MNI_c + kaso_add if MNI_c<0{ MNI_c=0;ループさせない // MNI_c=1;ループさせる } if MNI_c>1{ MNI_c=1;ループさせない // MNI_c=0;ループさせる } swbreak case 1;[はい、いいえ]選択中 HI_IIE_c = HI_IIE_c + kaso_add if HI_IIE_c<-20 :HI_IIE_c=0;←キーで、極端なマイナス値にしたら一番上の選択肢へ。 if HI_IIE_c>20 :HI_IIE_c=3;→キーで、極端なプラス値にしたら一番下の選択肢へ。 if HI_IIE_c<0{ // HI_IIE_c=0;ループさせない HI_IIE_c=3;ループさせる } if HI_IIE_c>3{ // HI_IIE_c=3;ループさせない HI_IIE_c=0;ループさせる } swbreak case 2 ;「はい」が選択されたとき Active_LayerID=1 ;「はいorいいえ」選択中に戻す swbreak swend return

こんな時間になんですが、布団に入りながら考えていて
「起きたら忘れていそうだな。よし、書くか!」という状況です。

よし、寝よう。



ミント

リンク

2012/3/12(Mon) 07:24:30|NO.45378

【A1】
>>念のためです。
やっぱそうでしたか。
でも、何かあった場合の処置が必要(必須じゃない)だったのを思い出せました。


【A2】
>>消し忘れです。
これも上の処置類かな?でも違うかな?とかごちゃ*2思ってたけど、なるほど〜。


【A3】
>>最期のswbreakは不要です。
>>「case〜swbreak」はセットで覚えておくと良いと思います。
ふむふむ。
ちゃんとセットであったほうがよさそうね。沢山追加すると何か起きるかもしれないし・・・


わざわざ質問その2に答えてくれてありがとうございます!
心配性な自分は・・・考えすぎですぞ!



ミント

リンク

2012/3/12(Mon) 09:31:38|NO.45379

わざわざソースありがとうございます!

>>【おまけ】←キーで一番上へ、→キーで一番下へカーソル移動させてみました。
しかもこんな便利なおまけまで・・・!ありがたいです!


case 0 ;[解除、最初から]選択中 MNI_c = MNI_c + kaso_add ; 第一層メニューのある場所 + 押したボタンの値 if MNI_c < 0{ ;[第一層]これがないと,どんどん↑に行ってしまう MNI_c = 1 ;[一時停止解除]のところで↑を押した場合,↓のカーソル値にする } if MNI_c > 1{ ;[第一層]これがないと,どんどん↓に行ってしまう MNI_c = 0 ;[最初っからやりなおす]のところで↓を押した場合,↑のカーソル値にする } swbreak ;ブロックが終了
のところ(改造しちゃっているけど)は計算方法と条件式を用意すればいいんですね。なるほど〜


switch HI_IIE_c ;比較元 (値はX) case 0 ;[はい]にカーソルがあったら白くする color 255,255,255 : pos 330,230 : mes "はい" ;白 swbreak ;ブロックが終了
そういえば画像の条件式にも使えるのですね (当然です)
んで、沢山比較対照がある場合は、[case 0,swbreak]を使った方がよさそうですね。
私の本ソースに革命がおきる!だが修正に心が折れそうな量・・・がんばるしかない!



>>こんな時間になんですが、布団に入りながら考えていて
>>「起きたら忘れていそうだな。よし、書くか!」という状況です。
実は私も寝る時間を過ぎてたのですが、解析途中で寝ると忘れそうだったので、一気にやりました。
そして、寝る時間をおしんで書いてくれた、たんすさんには感謝します。


さてこれからこれを本ソースにぶち込みつつ正常作動させなければならない。
正常作動したら解決にチェックしときますね (ちょっと時間かかると思います)



ヂオン

リンク

2012/3/12(Mon) 23:32:20|NO.45395

まだ解決していないようなので、書いてしまったスクリプトを載せます。
モジュール変数を使ってみました。

#ifndef MOD_PICTMENU #module MOD_PICTMENU m_flg , m_text , m_cmd , m_long // モジュール内の 4byte データの配列。 #define n_maxlen m_long(pmlong_maxlen) #define n_total m_long(pmlong_linetotal) #define n_usedata m_long(pmlong_userdata) #enum global pmlong_maxlen = 0 // 最大の文字数 #enum global pmlong_linetotal // Menuの行数 #enum global pmlong_userdata // ユーザー定義の32bit 値 #enum PICTMENULONGDATA_ELETOTAL // モジュールの初期化 #modinit local rt_ dim m_long,PICTMENULONGDATA_ELETOTAL:n_maxlen = 0x80000000 dim m_flg:sdim m_text:dim m_cmd:mref rt_,2 return rt_ // 配列の最後にデータを追加 #const global PICMENUF_IS_LINK 1<<31 // ポップアップリンク #modfunc picmenu_append int flg_ , int cmd_ , str txt_ , local t_,local l_ t_=n_total:m_flg.t_= flg_:m_cmd.t_= cmd_:m_text.t_= txt_ l_=strlen(txt_):if(l_>n_maxlen){n_maxlen=l_}:n_total++ return t_ // Menuに定義づけられた処理の識別子 #modcfunc picmenu_GetCommand int idx_ return m_cmd.idx_ // Menuに定義づけられた属性 #modcfunc picmenu_Getflg int idx_ return m_flg.idx_ // Menuに定義づけられたテキスト #modcfunc picmenu_GetText int idx_ return m_text.idx_ // ロングデータ配列のクローンを作成 #modfunc picmenu_GetLongdata array rt_ dup rt_,m_long:return // %1=非アクティブ時(0xBBGGRR),%2=アクティブ時(0xBBGGRR) #define global picmenu_Draw_SetColor(%1=0x505050,%2=0xFFFFFF)\ SELECTCOLOR@MOD_PICTMENU = %1 , %2 // defaultの描画処理 ; m_long(pmlong_userdata) を activeなメニューのインデックスとして使用します。 #modfunc picmenu_DrawDefault int mag_ repeat n_total cl=SELECTCOLOR(n_usedata==cnt) color cl&0xFF,cl>>8&0xFF,cl>>16&0xFF mes m_text.cnt:pos,ginfo_cy+mag_ loop:return #global picmenu_Draw_SetColor #endif// MOD_PICTMENU Eof //--------------------------------------- ; アプリケーションで使用するグローバルな関数群 goto *gfuncs_eof #defcfunc CreatePictMenu newmod MENULIST,MOD_PICTMENU app_selectmenu stat,1 return stat #deffunc app_selectmenu int tgt_,int f_ select_menuidx = tgt_&0x7FFFFFFF SELMENU = MENULIST(select_menuidx) if(f_==0):picmenu_GetLongdata SELMENU ,long return #deffunc app_Append int flg_,int cmd_,str txt_ picmenu_append SELMENU,flg_,cmd_,txt_ return stat #deffunc app_pushmenu int mid_ , int px_ , int py_ asmOrder.smTotal = mid_ aleft.smTotal = px_//aleft(smTotal-1) + (n_maxlen *(FONTSIZE/2)) +MARGIN atop.smTotal = py_//atop(smTotal-1) + FONTSIZE*n_cursor -MARGIN app_selectmenu mid_ gosub*proc_calc_rightbottom smTotal++ return *gfuncs_eof //--------------------------------------- // 定数 #enum IDPM_YESNO_YES = 1 // メニューId #enum IDPM_YESNO_NO #enum IDPM_BREAK #enum IDPM_RETURN_RESET #const MARGIN 7 // 箱の上下左右の余白 #const MARGIN_LINETOLINE MARGIN // 行間の余白 #const FONTSIZE 16 // フォントのサイズ #define n_cursor long(pmlong_userdata) // 現在のカーソル #define n_maxlen long(pmlong_maxlen) // 現在の最大の文字数 #define n_linetotal long(pmlong_linetotal) // 現在の行数 // asmOrder = 表示されているメニューの配列 // aLeft = メニューの左座標の配列 // aTop = メニューの上座標の配列 // aRight = メニューの右座標の配列 // aBottom = メニューの下座標の配列 // smTotal = 表示されているメニューの総数 // long = モジュールの情報が代入されている変数のクローン // メニューを作成 hpm_yesno = CreatePictMenu() app_Append 0,IDPM_YESNO_YES,"はい" app_Append 0,IDPM_BREAK,"いいえ" hpm_test2 = CreatePictMenu() repeat 3:app_Append 0,0,"下へ"+cnt:loop app_Append 0,IDPM_BREAK,"キャンセル" hpm_test1 = CreatePictMenu() tx="":repeat 10:tx+="go":app_Append 0,0,tx:loop app_Append PICMENUF_IS_LINK,hpm_test2,"したへ" app_Append 0,IDPM_BREAK,"キャンセル" hpm_return = CreatePictMenu() app_Append 0 , IDPM_RETURN_RESET ,"戻る" app_Append PICMENUF_IS_LINK , hpm_yesno ,"最初っからやりなおす" app_Append PICMENUF_IS_LINK , hpm_test1 ,"GO" // 最初にアクティブなメニュー app_pushmenu hpm_return , 20-MARGIN,20-MARGIN n_cursor = n_linetotal-1 // 初めから選択されているindex。 font MSGOTHIC,FONTSIZE *@ stick key if(key&8/*下*/):n_cursor=(n_cursor+1)\n_linetotal//カーソル移動処理(下のみ) if(key&2/*上*/):if(n_cursor==0){n_cursor=n_linetotal-1}else{n_cursor--} if(key&32/*エンター*/){ cmd = picmenu_GetCommand(SELMENU,n_cursor) flg = picmenu_GetFlg(SELMENU,n_cursor) if(flg&PICMENUF_IS_LINK){ #define CPX aleft(smTotal-1)+(n_maxlen*(FONTSIZE/2))+MARGIN #define CPY atop(smTotal-1)+FONTSIZE*n_cursor-MARGIN + MARGIN_LINETOLINE*(n_cursor-1) app_pushmenu cmd,CPX,CPY }else{ if(cmd==IDPM_YESNO_YES) {dialog "yes"} else:if(cmd==IDPM_BREAK) {smTotal--:app_selectmenu asmOrder(smTotal-1)} else:if(cmd==IDPM_RETURN_RESET) {dialog "reset"} } } // 描画 redraw 0:color:boxf repeat smTotal c=0xFF:count=cnt repeat 2 mag = 1-cnt:color c,c,c:c^=0xFF boxf aleft.count-mag,atop.count-mag, aright.count+mag , abottom.count+mag loop pos aleft.cnt+MARGIN,atop.cnt+MARGIN picmenu_DrawDefault MENULIST(asmOrder.cnt),MARGIN_LINETOLINE loop redraw:await 30 goto *@b *proc_calc_rightbottom lt = n_linetotal aright.smTotal = ( aleft.smTotal + (n_maxlen*FONTSIZE/2) + MARGIN*2 )-1 abottom.smTotal= ( atop.smTotal + (lt*FONTSIZE) + (MARGIN*2) + (lt-1)*MARGIN_LINETOLINE )-1 return



たんす

リンク

2012/3/13(Tue) 01:23:01|NO.45400

ヂオンさんのスクリプトは解読に時間がかかりますが、
ぱっとみ見でif文を削れそうだったので書いておきます。
*@
stick key if(key&8/*下*/):n_cursor=(n_cursor+1)\n_linetotal//カーソル移動処理(下のみ) ; if(key&2/*上*/):if(n_cursor==0){n_cursor=n_linetotal-1}else{n_cursor--} if(key&2/*上*/):n_cursor=(n_cursor-1+n_linetotal)\n_linetotal if(key&1/*左*/):n_cursor=0 ;左で一番上に if(key&4/*右*/):n_cursor=n_linetotal-1 ;右で一番下に
上キーが押された&現在のカーソル位置が0だった場合に一番下にループさせていましたが、
現在位置に項目数-1を加え、項目数で割ることでn_cursorが0でも1でも共通の処理になりました。

ついでに左右キーでのカーソル移動も付記。



>ここから自分で書いたスクリプトの話。
複数の選択肢を表示するときにswitchで列挙するのも芸がないかなと思い、配列変数で組んでみました。
あらかじめ準備しておくのが
・選択肢の文字列
・各層の選択肢の数
・基準となる表示位置
・選択肢ごとの位置間隔
それと
・各層のカーソル位置を記憶する配列型変数。(MNI_cとHI_IIE_cとを統合)
です。

;既存の変数と説明
Zkey=0 ;Zキー入力状態 Xkey=0 ;Xキー入力状態 kaso=0 ;上下の入力 ;以下:追加した変数 Zkey_wait=0 ;入力間隔をあけるための待ち時間 Active_LayerID=0 ;アクティブ層ID sdim select_mes,50,10,5 ;20文字の選択肢10種、5層までを用意。 select_mes(0,0) = "一時停止解除" ,"はい" ," " ," " ," " ;各層の1項目 select_mes(0,1) = "最初っからやりなおす" ,"いいえ" ," " ," " ," " ;各層の2項目 select_mes(0,2) = " " ,"いい絵" ," " ," " ," " select_mes(0,3) = " " ,"いい家" ," " ," " ," " dim select_max,5 ;それぞれの階層の選択肢数を設定 select_cmax=1,3,0 dim Layer_c,5 ;各層のアクティブな選択肢番号 dim def_sel_x,5 ;選択肢表示X位置 dim def_sel_y,5 ;選択肢表示Y位置 def_sel_x=130,330,0 def_sel_y=200,230,500 dim add_sel_x,5 ;選択肢ごとのX軸増加分 dim add_sel_y,5 ;選択肢ごとのY軸増加分 add_sel_x=0,0,0 add_sel_y=40,20,0 Layer_cnt=0 ;選択肢表示での 2重repeatのcnt確保変数 ;変数宣言終了 screen 0,640,480 ;***************メインループ************ *メイン redraw 2 : color : boxf ;***************カウンター************** color 255, pos 0,0 : mes "1層目のカウント(Layer_c(0)) " + Layer_c(0) pos 0,20 : mes "2層目のカウント(Layer_c(1)) " + Layer_c(1) pos 0,40 : mes "アクティブ層ID(Active_LayerID) " + Active_LayerID if(Active_LayerID >= 2) : pos 0,120 : mes "はいが押されました " ;*************************************** await 10 if Zkey_wait<=0{getkey Zkey,90 }else{Zkey_wait--} if Zkey{Zkey=0:Zkey_wait=10 switch Active_LayerID case 0 ;「解除or最初から」選択中 if Layer_c(0){ ;1層目の選択が1:「最初から」 Active_LayerID++ ;次の層へ移行 }else{ ;1層目の選択が0:「解除」 } swbreak case 1 ;「はいorいいえ」の選択中 if Layer_c(1){;2層目の選択が1:「いいえ」、2:いい絵、3:いい家(要は0:はい 以外) Active_LayerID-- ;カーソルを「解除or最初から」に戻す }else{ ;2層目の選択が0:「はい」 Active_LayerID++ ;次の層へ移行 } swbreak case 2 ;「はい」が押されたあとにZ入力 Active_LayerID-- ;「はいorいいえ」に戻す swbreak swend } getkey Xkey,88 ;キャンセル(Xキー) if Xkey {Active_LayerID=0};Xキーを押したら実行 ;************キーを読むこむ************* stick kaso ;カーソルキー取得 kaso_add=0 ;上下左右入力が無い時にカーソルを動かさないための初期化 if ( kaso & 2 ) { kaso_add=-1 };↑ボタン if ( kaso & 8 ) { kaso_add=1 };↓ボタン if ( kaso & 1 ) { kaso_add=-50};←;極端なマイナス if ( kaso & 4 ) { kaso_add=50 };→;極端なプラス if kaso_add!=0:gosub *↑↓←→ボタン ;************繰り替えしを使って文字を出す。 repeat Active_LayerID+1 ;現在の階層+1 くりかえす Layer_cnt=cnt ;何層目の描写かをLayer_cntに。 repeat select_cmax(cnt)+1 ;何層目かの選択肢数+1 くりかえす。 if cnt=Layer_c(Layer_cnt){ ;選択中な項目なら color 255,255,255 ;白 }else{ ;選択されていないなら color 77,67,64 ;灰 } pos (cnt * add_sel_x(Layer_cnt)) + def_sel_x(Layer_cnt) , (cnt * add_sel_y(Layer_cnt)) + def_sel_y(Layer_cnt) ;cnt*変化量+基準位置 // mes ""+Zcnt+"層"+cnt+"番:"+select_mes(Layer_cnt,cnt) ;確認用 mes ""+select_mes(Layer_cnt,cnt) ;選択肢表示 loop loop redraw : await 15 goto *メイン ;*************↑↓←→ボタン****************** *↑↓←→ボタン switch active_LayerID case 2 ;「はい」が選択されたとき Active_LayerID=1 ;「はいorいいえ」選択中に戻す swbreak default ;case 0,case 1(case2以外)の共通処理 Layer_c(Active_LayerID) = ( Layer_c(Active_LayerID) + kaso_add + select_max(Active_LayerID)+1 ) \ (select_max(Active_LayerID)+1) ;現在の層のカーソル位置を変化 if kaso_add<-20 { Layer_c(Active_LayerID)=0 } ;←キーで、極端なマイナス値にしたら一番上の選択肢へ。 if kaso_add>20 { Layer_c(Active_LayerID)=select_max(Active_LayerID) } ;→キーで、極端なプラス値にしたら一番下の選択肢へ。 swend return
まとめすぎると可読性は下がりますね。



ヂオン

リンク

2012/3/13(Tue) 04:26:02|NO.45402

カーソル位置のスクリプトの指摘有難うございます。
毎回 if 文を使用していたので、今後は、幾分かスクリプトがすっきりする様に思います。



ミント

リンク

2012/3/13(Tue) 18:52:23|NO.45409

>>ヂオンさん
ソースありがとうございます!だけど・・・


でた!モジュール変数!
今まで何度が会って・・・何度か無視して・・・ (理解出来なかったので)
そしてまた来たのか・・・はてさて今の自分にこいつを倒せるのだろうか?

とりあえず後回しになってしまうことは確定的に明らかだが・・・
今もなお、本ソースぶちこんで動作確認をしてますが、不具合が生じているため時間かかりそうです。
解決したら「ヂオンさん」のソースに手を出しますのでしばしお待ちを・・・



ミント

リンク

2012/3/15(Thu) 21:26:34|NO.45430

ふぅ・・・時間かかりすぎだろ・・・私・・・
そんなわけで本スクリプトにテストソースを入れて、望み動作の動作になったので解決しました!
本当にありがとうございます!



さて私がいままで避けてきた「モジュール変数」と戦わねば・・・
しかしリアル事情により解読にはものすごく時間がかかると思います。
それにまったく理解してないしね・・・


「でかい変数?」ていう認識からスタートと言えば、どれだけ時間かかるか皆にはわかると思うんだ。
もし挫折したら「ヂオン」さんのソースが無駄になっちまう・・・
それに連鎖して、改良した「たんす」さんのソースも・・・

そうならないように、なるべくがんばるけど、多分折れる。





 【今回の結果】(余談程度で、なおかつ見せる用にはなっておりません)
----------------------------------------------------

screen 0,640,480 goto *ゲーム準備 ;***************初期化****************** *初期化 MNI_c = 0 ;メニューの値 Activ_ID = 0 ;アクティブIDの値 Zkey_wait = 0 ;待ち時間 kaso_add = 0 ;カーソルの値 ;*************************************** *ゲーム準備 buffer 5 picload "システム\\システム.bmp" gsel 0,1 ;効果音 mmload "効果音\\ポーズ音.wav",2 mmload "効果音\\キャンセル音.wav",3 mmload "効果音\\決定音.wav",4 mmload "効果音\\カーソル音.wav",5 ;***************メインループ************ *メイン color : boxf ;背景を黒で塗る ;*************エスケープー************** stick ESC ;ESC if ESC = 128 { ;一時停止 mmplay 2 ;ポーズ音 repeat redraw 2 : color : boxf if Zkey_wait <= 0{ ;一度Zが押されたら、しばらく判定しないように getkey Zkey,90 ;決定 (Zキー) if Zkey & MNI_c = 0 { HI_IIE_c = 0;はい,いいえの数値を初期化 mmplay 4 ;決定音 break ;エスケープーのループから抜ける } }else{ Zkey_wait-- ;Zkey_waitの消化 (10-1) mmplay 4 ;決定音 } if Zkey{ ;決定 (Zキー)が押されたら以下の判定 Zkey = 0 ;これがないとZキーを押した状態になってしまう Zkey_wait = 10 ;待ち時間の設定 switch Activ_ID ;比較元 (値はX) case 0 ;「解除or最初から」選択中 if MNI_c = 2{ ;「最初から」でZ入力 Activ_ID++ ;次の層へ移行 }else{ ;第一層メニューの数値が[0]の場合 = 実行 } swbreak ;比較実行脱出 case 1 ;「はいorいいえ」の選択中 if HI_IIE_c{;「いいえ」でZ入力 Activ_ID-- ;カーソルを「解除or最初から」に戻す }else{ ;「はい」でZ入力 Activ_ID++ ;次の層へ移行 } swbreak ;比較実行脱出 case 2 ;「はい」が押されたあとにZ入力 Activ_ID-- ;「はいorいいえ」に戻す swend ;ブロックが終了 };Z入力時の処理終了 getkey Xkey,88 ;キャンセル(Xキー) if Xkey { ;Xキーを押したら実行 Activ_ID = 0 ;第一層メニューに戻る mmplay 3 ;キャンセル音 } ;************キーを読むこむ************* stick kaso ;カーソルキー取得 if ( kaso & 2 ) { ;↑ボタン kaso_add = -1 gosub *↑↓ボタン } if ( kaso & 8 ) { ;↓ボタン kaso_add = 1 gosub *↑↓ボタン } ;*******第一層メニューの文字を出す****** switch MNI_c case 0 pos 130,200 : gmode 2,221,24,255 : gcopy 5,1,147 ;一時停止解除(白 pos 130,240 : gmode 2,146,23,255 : gcopy 5,1,123 ;タイトルに戻る(黒 pos 130,280 : gmode 2,183,24,255 : gcopy 5,1,223 ;最初っからやりなおす(黒 swbreak ;ブロックが終了 case 1 pos 130,200 : gmode 2,221,24,255 : gcopy 5,1,172 ;一時停止解除(黒 pos 130,240 : gmode 2,146,23,255 : gcopy 5,1,99 ;タイトルに戻る(白 pos 130,280 : gmode 2,183,24,255 : gcopy 5,1,223 ;最初っからやりなおす(黒 swbreak ;ブロックが終了 case 2 pos 130,200 : gmode 2,221,24,255 : gcopy 5,1,172 ;一時停止解除(黒 pos 130,240 : gmode 2,146,23,255 : gcopy 5,1,123 ;タイトルに戻る(黒 pos 130,280 : gmode 2,183,25,255 : gcopy 5,1,197 ;最初っからやりなおす(白 swbreak ;ブロックが終了 swend ;***************カウンター************** color 255, pos 0,0 : mes "メインメニューのカウント(MNI_c) " + MNI_c pos 0,20 : mes "はい、いいえカウント(HI_IIE_c) " + HI_IIE_c pos 0,40 : mes "アクティブ層ID(Activ_ID) " + Activ_ID pos 0,60 : mes "待ち時間(Zkey_wait) " + Zkey_wait pos 0,80 : mes "カーソル値(kaso_add) " + kaso_add if(Activ_ID >= 2) : pos 0,100 : mes "はいが押されました " ;**************[はい,いいえ]************ if Activ_ID >= 1 { ;第二層(はい、いいえ)以降で表示 ;すべての選択肢を黒で書いておく color 77,67,64 : pos 330,270 : gmode 2,36,17,255 : gcopy 5,55,248 ;はい(黒 color 77,67,64 : pos 330,300 : gmode 2,53,16,255 : gcopy 5,55,267 ;いいえ(黒 ;カーソル位置だけ白く書き直す switch HI_IIE_c ;比較元 (値はX) case 0 ;[はい]にカーソルがあったら白くする color 255,255,255 : pos 330,270 : gmode 2,36,17,255 : gcopy 5,1,248 ;はい(白 swbreak ;ブロックが終了 case 1 ;[いいえ]にカーソルがあったら白くする color 255,255,255 : pos 330,300 : gmode 2,53,16,255 : gcopy 5,1,267 ;いいえ(白 swbreak ;ブロックが終了 swend ;最初っからになる if Activ_ID >= 2 {;はいが押されたら実効 mmplay 4 ;決定音 goto *初期化 } }redraw : await 10 : loop } ;*************ポーズ処理終了************ redraw 0 : color : boxf ;*************************************** /*/ gosub *自機弾の移動 ;敵 repeat TEK_MAX ;敵の最大数(79) if TEKF(cnt) = 1 : color ,255 : pos TEKX(cnt),TEKY(cnt) : gmode 4,26,22,255 : gcopy 61,1,1 loop とか入れる場所 /*/ redraw 1 : await 15 goto *メイン ;*************↑↓ボタン**************** *↑↓ボタン mmplay 5 ;カーソル音 switch Activ_ID ;比較元 (値はX) ;第一層メニュー case 0 ;[解除、最初から]選択中 MNI_c = MNI_c + kaso_add ; 第一層メニューのある場所 + 押したボタンの値 if MNI_c < 0{ ;[第一層]これがないと,どんどん↑に行ってしまう MNI_c = 2 ;[一時停止解除]のところで↑を押した場合,↓のカーソル値にする } if MNI_c > 2{ ;[第一層]これがないと,どんどん↓に行ってしまう MNI_c = 0 ;[最初っからやりなおす]のところで↓を押した場合,↑のカーソル値にする } swbreak ;ブロックが終了 ;第二層メニュー case 1;[はい、いいえ]選択中 HI_IIE_c = HI_IIE_c + kaso_add ;第二層メニューのある場所 + 押したボタンの値 if HI_IIE_c < 0{ ;[第二層]これがないと,どんどん↑に行ってしまう HI_IIE_c = 1 ;[はい]のところで↑を押した場合,一番↓のカーソル値にする } if HI_IIE_c > 1{ ;[第二層]これがないと,どんどん↓に行ってしまう HI_IIE_c = 0 ;[いい家]のところで↓を押した場合,一番↑のカーソル値にする } swbreak ;ブロックが終了 ;Zキーが押された場合はIDに[2]の値が入る, case 2 ;「はい」が選択されたとき Activ_ID = 1 ;「はいorいいえ」選択中に戻す swbreak ;ブロックが終了 swend return



ミント

リンク

2012/3/17(Sat) 11:11:19|NO.45454

・・・・「ヂオン」さんのソース、やっぱ理解できなかったorz
悔しいけど、今の私の実力だと理解するのは無理。
ならばその現状を受け止めて成長すればいい。まぁ、理解するのはきっと遠い未来だけどね(ぁ

そんなわけでいったん「ヂオン」さんのソースを保留させていただきます (´・ω・`)
理解できなくってすまねぇ・・・けどソースありがとうございます!きっと有効活用できる日が来る。
それとさらに詳しい「たんす」さんのソースもありがとうございます!





 〜超・余談〜
「#module」
この「モジュールの開始」だけなんとなく理解。だけど有効活用の仕方がわからない。

 【私なりの解釈の仕方】
いつもの部屋にドアを作る。
そのドアの中の部屋は、いつもの部屋と違う。
違う部屋なので変数名やラベル名は別の物である。

ただし同じ部屋名同士は、変数名やラベル名を共有する。
(例:「A音楽室、A音楽室」は同じ音楽のカテゴリー)
疑問に思うけど、同じ名前ならまとめた方がいいような気がする。
処理手順かなんかで使えるかもしれない?けどよくわからない。


部屋名が違う場合は、変数名やラベル名は違うものとして扱われる。
これは「gosub」のような感覚で多分間違ってない。
(音楽室の中にあるピアノ(変数))
(教室の中にあるピアノ(変数))
は違うもの。



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