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


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0724
buhioモジュールの宣言順序?仕様について4解決


buhio

リンク

2023/7/24(Mon) 17:20:55|NO.99795

みなさんコンニチワ。

質問1
モジュールを使って色々と管理しやすくしようと思っているのですが、
下記のコードでは、(Zキー)モジュールAの中からモジュールBを生成(グローバル変数に追加)すると、エラーが発生します。
一方で、(Xキー)モジュールBの中からモジュールAを生成すると成功します。
回避策→(Cキー)のように、グローバルで命令を作ることで回避している状態です。
回避策→インクルードする順番を入れ替えると大丈夫なので、お互いに生成するようなモジュールは避ける。

このエラーは、モジュールAとBの宣言の順番が影響しているのでしょうか?

(想定していること)
プレイヤーモジュール(A)の中から弾モジュール(B)を生成する場合、先に弾モジュールをincludeしておかないと生成できなかった。

質問2
 そもそも、別のモジュールから、グローバル配列変数に対してnewmodするのは、良くないのかと思いますが、ゲーム制作でモジュール化する場合、どのような管理方法が良いのでしょうか?
プレイヤーモジュールとか、弾モジュールとか、アイテムモジュール、敵モジュールなど、増えてきたのですが、オブジェクト指向とまではいかなくても、ある程度モジュール化することで見やすくなりました。
HSPの仕様上で気を付けることがあれば教えてください。


;モジュールA========================================= #module mod_A val #modfunc add_mod_b newmod var_mod_b@,mod_B;→エラー return #modfunc add_mod_b2 add_mod_b_global;→正常。グローバル命令を呼ぶ。やっていることは同じはず return #global ;モジュールB========================================= #module mod_B val #modfunc add_mod_a newmod var_mod_a@,mod_A;→正常 return #global ;メインプログラム==================================== newmod var_mod_a,mod_A newmod var_mod_b,mod_B *main redraw 0 color 0,0,0:boxf stick keys ;ZキーでモジュールAの中からモジュールBを生成→エラー!! ;#Error 35 in line〇〇(???) ;-->モジュール変数が指定されていません if keys&2048:add_mod_b var_mod_a(0) ;XキーでモジュールBの中からモジュールAを生成→正常に追加可能 if keys&4096:add_mod_a var_mod_b(0) ;CキーでモジュールAの中からグローバル命令でモジュールBを生成→正常に追加可能 if keys&8192:add_mod_b2 var_mod_a(0) ;デバッグ pos 0,0:color 255,255,255 mes "mod_A:"+length(var_mod_a) mes "mod_B:"+length(var_mod_b) await 1000/60:redraw 1 goto *main ;グローバル命令==================================== #deffunc add_mod_b_global newmod var_mod_b,mod_B return



この記事に返信する


usagi

リンク

2023/7/27(Thu) 21:05:15|NO.99802

こんにちわ

■質問1

現状のHSPの仕様だとモジュール変数に関しては順番が影響してますね。
#cmpopt ppout 1 してhsptmp.iをテキストエディタで開くと分かりやすいですが、
mod_Aの段階ではmod_Bをまだ認識していない為、mod_b@mod_aと変数に置き換えられます。(mod_bとなってもらいたい気持ちですが)
ですからmod_A内のただの整数型ローカル変数mod_bと認識され「モジュール変数が指定されていません」とエラーがでます。

※プリプロセス後のスクリプトを一部抜粋

newmod@hsp var_mod_b,mod_b@mod_a // newmod var_mod_b@,mod_B;→エラー newmod@hsp var_mod_a,mod_a // newmod var_mod_a@,mod_A;→正常 newmod@hsp var_mod_b,mod_b // ;グローバル命令

■質問2
>グローバル配列変数に対してnewmodするのは、良くないの
ちょっと私が勘違いしているかもしれませんが、
モジュール内の変数にモジュール変数を作成するとかで無いのであれば、
以下の様な感じで操作用を分けて通常モジュールに記載すれば、
通常モジュール内の変数はスコープを分けられると思います。


#cmpopt ppout 1 ;A構造を用意 #module mod_A val #global ;B構造を用意 #module mod_B val #global ;A,B構造操作用 #module #deffunc add_mod_a array v newmod v,mod_A return #deffunc add_mod_b array v newmod v,mod_B return #global newmod var_mod_a,mod_A newmod var_mod_b,mod_B *main redraw 0 : color 0,0,0:boxf stick keys if keys&2048:add_mod_b var_mod_a(0) if keys&4096:add_mod_a var_mod_b(0) pos 0,0:color 255,255,255 mes "mod_A:"+length(var_mod_a) mes "mod_B:"+length(var_mod_b) await 1000/60:redraw 1 goto *main



usagi

リンク

2023/7/28(Fri) 01:28:16|NO.99804

あっ、たびたびすみません。やっぱり勘違いしてたかもです。。。
依存関係にあるモジュールを分けて管理する時のいい感じの書き方って事ですかね。


;モジュールA========================================= #module mod_A val #deffunc local new array mod ; ★モジュールA作成用のローカル関数をA内で作っておく newmod mod,mod_A : return #modfunc add_mod_b new@mod_B var_mod_b@ : return; ★関数は順番に影響されないので呼び出せる #global ;モジュールB========================================= #module mod_B val #deffunc local new array mod; ★モジュールB作成用のローカル関数をB内で作っておく newmod mod,mod_B : return #modfunc add_mod_a new@mod_A var_mod_a@ : return; ★関数は順番に影響されないので呼び出せる #global ;メインプログラム==================================== newmod var_mod_a,mod_A newmod var_mod_b,mod_B *main redraw 0 : color 0,0,0:boxf : stick keys ;ZキーでモジュールAの中からモジュールBを生成 if keys&2048:add_mod_b var_mod_a(0) ;XキーでモジュールBの中からモジュールAを生成 if keys&4096:add_mod_a var_mod_b(0) ;デバッグ pos 0,0:color 255,255,255 mes "mod_A:"+length(var_mod_a) mes "mod_B:"+length(var_mod_b) await 1000/60:redraw 1 goto *main



buhio

リンク

2023/7/28(Fri) 13:10:00|NO.99805

>>usagiさん

 いつも明快な回答ありがとうございます。

 質問1:なるほど、よくわかりました。仕組みが分かったので感謝です。

 質問2:★関数は順番に影響されないので呼び出せる→うーむ、、なるほっど。いい感じです(笑

 よくわかりました。奥が深いです。。。真のモジューラーへの道は長い。。



usagi

リンク

2023/7/29(Sat) 20:18:36|NO.99820

解決した様で良かったです。
皆さんいろいろな書き方されてると思うので正解は無いと思いますが、
私はモジュール変数の場合はこんな感じにしてます。


; モジュール用ユーティリティ(これは共通で使う) #module #defcfunc mod_id var mod mref id, 1 : return id #global ; Actorモジュール #module Actor _id, _name, _hp, _mp ; モジュール変数作成用 ★書き方を統一したい(関数名@モジュール名)と読み込み順番対策 #deffunc local new array mod, str name, int hp, int mp newmod mod, Actor, name, hp, mp : return ; 初期化 #modinit str name, int hp, int mp _id =mod_id(thismod) : _name = name : _hp = hp : _mp = mp return _id; ★インデックスを返しておくと後で便利かも ; 表示 #modfunc local log mes strf("%d[%s HP:%d MP:%d]", _id, _name, _hp, _mp) : return #deffunc local logAll array mod; ★こういうのもあると便利 foreach mod : log mod.cnt : loop : return ; アクセサ (一部) #modcfunc local getName return _name #modfunc local setName str name _name = name : return #global new@Actor hoge, "ほげ",100,50 new@Actor hoge, "ふが",200,20 logAll@Actor hoge setName@Actor hoge, "ぴよ" mes "ゲット:"+getName@Actor(hoge) logAll@Actor hoge



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