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


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0609
popdeffuncで定義した命令の中の変数17解決


pop

リンク

2010/6/9(Wed) 22:43:42|NO.33167

ゲームのセレクト画面でおなじみの
選択しているものが、ボタンを押したらカッと動く、
長く押し続けたらカッカッカッとうごくあれをつくりたいと思って
getkeyを中心にいろいろやってみました。

でもどうせだったらmodule〜deffunc〜globalで新しく命令を
作ってしまおうと想ったんですが、

ボタンを押している時間を変数にして、
それが20で割り切れるならなどと条件をつけて
カッカッカッとやろうとしても
時間変数はその命令内でしか使われないローカルな変数なので
一度グローバル空間に戻ると、初期化されてしまいますよね?
ということは時間変数は0のままなので、おかしくなりますよね。

じゃあその時間変数をグローバル空間でも保持し続けるには
どうすればよいのでしょうか。というより、皆さんはどうやってあのカッカッカッの動きを
作っていますか?


よろしくお願いします。



この記事に返信する


backdrop

リンク

2010/6/9(Wed) 22:51:29|NO.33169

引数のvarを参照してインクリメントする

;popさんはこれがやりたいんでしょうか? #module #deffunc countPlus var p1 p1++ return #global b=0 repeat getkey kk,1 if kk=1:countPlus b await 10 loop



backdrop

リンク

2010/6/9(Wed) 22:54:01|NO.33170

上の例は引数を使用する例
保持させるなら#define globalで割り当ててしまえ

;例 #module a=5 #define global a2 a #global mes a;ここは正しく表示されないが… mes a2;これなら5と、正しく表示される



pop

リンク

2010/6/10(Thu) 00:05:56|NO.33173

backdropさん
返信ありがとうございます。

簡単にいってしまえば

#module
#deffunc meirei int P1

t ++
mes t

return
#global

*main
meirei 100
await 16
goto *main


携帯からなので見にくくなってしまい申し訳ありません。
今回パラメータは飾りです。
メインはtになります。
tとパラメータは無関係だということを言いたかったんです。
上記のようにすると実行結果は1
1
1
1



となると思います。
これを
1
2
3
4



とするにはどうすればよいのでしょうかということです。

やはりこの場合
tをグローバル変数にするしかないのでしょうか。



backdrop

リンク

2010/6/10(Thu) 00:40:39|NO.33176

パラメータに変数を指定し、それをインクリメント…するしかない



pop

リンク

2010/6/10(Thu) 01:04:53|NO.33177

backdropさん
夜遅くに返信してくださって本当にありがとうございます。

結論としてはtをパラメータに含めるしかなさそうですね。
(誰かここらへんのことを書いた書籍をだしてもいいと思うんですけどね。
ゲーム業界の人はセレクト画面をどうつくってるんでしょうか。)

まぁ、自分の考え方はあまり良いものでは無かったとわかっただけでも大した収穫です。

何かひらめいたときはその時に質問させていただきます。

本当にありがとうございました。



info

リンク

2010/6/10(Thu) 03:31:03|NO.33179

 stick 命令で検索してみてください。
 キーの押しっぱなしが無効になるため、
 キーを押した瞬間だけ取得することが出来ます。


//エンターキーを押してみてください repeat stick key if key & 32 { mes strf("エンター 0x%02x キーが押されている。" , key ) } wait 1 loop



pop

リンク

2010/6/10(Thu) 08:05:34|NO.33183

infoさん
返信ありがとうございます。

確かにstickをつかえば、矢印やエンターやスペースを押した瞬間だけ
調べることができますね。

でもstickだと、押したら離す、押したら離すと
しないとうまくできないんです。

私がやりたいのは、長い間押しっぱなしならば、断続的にキーを押したと結論を返すことなんです。

あともうひとつ。
これからゲーム本編を作るときに、ABCなどでも
同じ判定をしたいなと思っているんです。
そうなるとgetkeyのほうがいいんです。

答えてもらっておいて失礼ですが、少し違うんです。
でもわざわざこんな質問を読んで回答してくださって
本当にありがとうございます。



あり

リンク

2010/6/10(Thu) 14:28:31|NO.33190

NO.33173のスクリプトを実際に起動させたのなら分かると思いますが
HSPのモジュール内ではlocal指定にしない限り変数の中身は維持されます。
(詳しくはHSPプログラミングマニュアルのモジュールの項を参照)

また、目的の動作をさせるには
キーを押し続けている時だけカウンタを増やして
一回目にキーを押した時と一定数に達している時だけ
セレクターを移動させる様にすれば実現できます。

以上を踏まえるとこんな感じになります。

#define global selx 74 ;セレクタX位置 #define global cntmax 6 ;カウント最大値(連続移動の開始値) #module #deffunc seldraw int _sely color 255 , 255 , 255 : boxf color 0 pos 0 , 0 mes "SLEECT 1" mes "SLEECT 2" mes "SLEECT 3" mes "SLEECT 4" mes "SLEECT 5" pos selx , _sely * 18 + 1 : mes "○" return #deffunc keycheck getkey key , 40 ;カーソルキーの↓でセレクタ移動 if key = 1 { kstack = limit(kstack + 1 , 0 , cntmax) if (kstack = 1) or (kstack = cntmax) { sely = (sely + 1) \ 5 ;セレクタの位置 seldraw sely ;セレクタの移動中のみ描画する } } else { kstack = 0 ;キーを離したらカウンタをリセット } return kstack #global ////////// メインループ ////////// seldraw 0 *main redraw 0 keycheck title "キー状態=" + key@m0 + " キーのカウント=" + stat redraw 1 wait 10 goto *main



pop

リンク

2010/6/10(Thu) 19:28:14|NO.33193

ありさん
返信ありがとうございます。

実は今わけあってパソコン使えないんですよ...
備忘録として今は紙にまとめています。

ところで質問を新しくしなおしたほうがいいのでしょうか。
モジュール空間内なら保持されるというところがよくわかりません。

私の解釈を書きます。
ありさんのスクリプトの中にあるkstackという変数が、
私が質問した、パラメータに依存しない変数であり
その変数は、定義した命令をメインループから呼び出すとき
呼び出すたびに初期化されるのではなく
その命令内の変数として保持され続けるということで
いいのでしょうか。

そうなると、パラメータに異なる値をいれたものを
二つ以上つかったらどうなってしまうのでしょうか。

本当に何度も申し訳ないです。



info

リンク

2010/6/10(Thu) 19:56:20|NO.33194

>>その命令内の変数として保持され続けるということで
>>いいのでしょうか。

命令内では無く、モジュール内の変数として保持されます。
下のスクリプトを実行してみてください。

モジュール内の変数には、モジュール内で定義された全ての命令で
アクセスすることが出来ます。

モジュール関連の機能には


#module モジュール1 #deffunc myfunc str a_ 変数1 = a_ return #deffunc myprint mes "変数1の内容["+変数1+"]" return #global myprint myfunc "myfunc命令により、文字列を代入済み" myprint



pop

リンク

2010/6/10(Thu) 20:38:22|NO.33195

infoさん
二度目の返信ありがとうございます。

なんだか今少し前進した気がします。
同じモジュール空間内にあれば変数はそのモジュール空間内で保持される。
それはつまり定義された命令が
"どこで呼び出されようと"、
同じモジュール空間内で定義された命令ならば他の命令も
そのモジュール空間内で作った変数を保持(共有)できる
ということですよね?

当たってますか?

ここまで皆さんに迷惑をかけておいて
結局分かりませんでしたなんて言ったら、
皆さんの貴重な時間を無駄にしただけになってしまうので
なんとしてでも理解しなくてはいけないんです。

最後にあっているか違っているかだけでも教えて頂けませんか。
間違っているなら改めて調べなおしてから質問します。
解決になっているのに本当に申し訳ないですが
どうかよろしくお願いします。



info

リンク

2010/6/10(Thu) 21:31:03|NO.33202

>>同じモジュール空間内で定義された命令ならば他の命令も
>>そのモジュール空間内で作った変数を保持(共有)できる
>>ということですよね?

その通りです

 

 



テック

リンク

2010/6/10(Thu) 21:41:13|NO.33203

>同じモジュール空間内で定義された命令ならば他の命令も
>そのモジュール空間内で作った変数を保持(共有)できる

そのとおりです。
下記スクリプトを参考にしていただきたいのですが、
モジュール内で宣言された変数m_nTimeは、
同じモジュール内の命令内ならば、0で初期化されず、
内容を保持し続けます(共有できます)。

またどうしてもグローバル変数にしなければいけない場合は、
変数名に@を付けるか、
引数のパラメータタイプをvarにして、命令内での引数の変更内容を
呼び出し元にも反映するかだと思われます。

以上、回答が質問内容に沿っていない場合は、すみません。


#module sample // モジュール変数 m_nTime = 0 #deffunc meirei_up1 int P1 m_nTime-- return #deffunc meirei_up2 mes "モジュール:" + m_nTime return // 引数のパラメータタイプをvarにし、 // 命令内の変更内容を呼び出し元にも反映させる #deffunc meirei_up3 var nTime nTime-- return #deffunc meirei_down1 int P1 m_nTime++ return #deffunc meirei_down2 mes "モジュール:" + m_nTime return #deffunc meirei_down3 // 変数名に@を付加して、モジュール内から // グローバル変数を参照する g_nTime@++ return #global // グローバル変数 g_nTime = 0 g_nKeyArrowUp = 0 g_nKeyArrowDown = 0 *main // 画面をクリアする cls // キーボードの↑キーの入力チェックをする getkey g_nKeyArrowUp, 38 // キーボードの↓キーの入力チェックをする getkey g_nKeyArrowDown, 40 // キーボードの↑キーが押された場合 または // 押され続けている場合 if(g_nKeyArrowUp) { meirei_up1 100 meirei_up2 meirei_up3 g_nTime mes "グローバル:" + g_nTime } // キーボードの↓キーが押された場合 または // 押され続けている場合 if(g_nKeyArrowDown) { meirei_down1 100 meirei_down2 meirei_down3 mes "グローバル:" + g_nTime } // 一時中断する await 16 goto *main



ANTARES

リンク

2010/6/11(Fri) 02:28:09|NO.33206

 NO.33190のありさんのスクリプトの動作がヘンなので調べてみたら、
非トリガータイプのstickの動作がおかしいようです。
以下のスクリプトを実行して、↓キーを押し続けても
いったん離したかのようにダイアログが表示されます。
WindowsXP Pro SP2, HSP2.5, 2.61, 3.2, 3.21

repeat: wait 1 stick c,255 if c==8 { f=1 } else { if f: dialog "c="+c: end } loop

 さらに調べてみると、getkeyでも同様ですが、
Windows95ではこのようなことはありません(HSP2.5, 2.61)
ということは、Windowsのバグ?



ANTARES

リンク

2010/6/11(Fri) 03:34:38|NO.33207

 上の問題を解消してみましたが、
今度は同じキーを素早く二度以上押した場合、無視されることがあります。

#module #include "user32.as" #deffunc boxnot int bx, int by, int wid, int heit mref bm,67 dim rect,4 rect.0=bx, by, bx+wid-1, by+heit-1 InvertRect hdc,varptr(rect) return #defcfunc selitem int idx, int num, int px, int py, int wid, int heit ilimit=300 climit=50 cur=idx boxnot px,py+cur*heit,wid,heit: redraw ;反転する start=gettime(7): curlimit=0: bug=0 repeat: wait 1 stick c,255,1 if c==32: break ;Enterキー if c==2 | c==8 { ;↑キー,↓キー now=gettime(7) if (now+1000-start)\1000>curlimit { if curlimit>0 { curlimit=climit } else { curlimit=ilimit } start=now boxnot px,py+cur*heit,wid,heit ;反転を戻す if c==2 { ;↑キー cur=(cur+4)\num } else { ;↓キー cur=(cur+1)\num } boxnot px,py+cur*heit,wid,heit ;反転する redraw } bug=0 } else { bug++ if bug>6 { curlimit=0 } } loop boxnot px,py+cur*heit,wid,heit: redraw ;反転を戻す return cur #global num=5 gyokan=4 fsize=16 maxchar=4 sdim busho,40,num busho="織田信長","羽柴秀吉","松平元康","今川義元","斎藤道三" px=(640-fsize*maxchar)/2 py=(480-fsize*num-gyokan*(num-1))/2 y=py repeat num pos px,y mes busho.cnt y+=fsize+gyokan loop i=3 repeat i=selitem(i, num,px,py,fsize*maxchar,fsize+gyokan) dialog busho.i loop



pop

リンク

2010/6/11(Fri) 08:27:21|NO.33210

backdropさん infoさん ありさん
テックさん ANTARESさん
私の質問したに回答してくださって本当にありがとうございます。

みなさんのおかげでモジュール空間についての理解が進み、
私の夢物語も確信を持てたことで、実現できそうです。

皆さんには本当に感謝してもしきれないほどです。
今回はほんとうにありがとうございました!



ANTARES

リンク

2010/7/14(Wed) 02:57:48|NO.33657

> NO.33190のありさんのスクリプトの動作がヘンなので調べてみたら、
>非トリガータイプのstickの動作がおかしいようです。
 私の環境の特殊事情が原因でした。(^_^;;
NO.33207の「if bug>6 {」と対応する「}」は削除してください。
(「curlimit=0」は必要)



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