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


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0125
jiggerモジュールの受け渡し4解決


jigger

リンク

2010/1/25(Mon) 22:46:50|NO.30157

最近モジュール機能のよさが分かり、積極的に使おうと思っているのですが、
モジュール間でのモジュール変数の受け渡しが上手くいかず困っています。

例えばシューティングで、mod_AirCraftというモジュール型のACというモジュール変数を10個作り、
その中のdrawと言う命令(#modfunc)を使って敵機を描画するとき、
foreach AC
draw AC(cnt)
loop
とすると、グローバル空間からは当然上手く行きますが、
仮にmod_Enemyと言うモジュールを作って、そこからdrawを呼び出す場合、
#module mod_Enemy array AC

#modinit array p1 (他省略)
AC = p1
return
#modfunc 〜〜〜
(省略)
foreach AC
   draw AC(cnt)
loop
のようにしても、ACの最初の要素しか描画されません。

HSPで、モジュール型の配列変数を異なるモジュール間で共有(と言うかコピー)する方法
はあるのでしょうか。

ちなみにこれが不可能でも作れますが、非常にスクリプトがややこしくなります。



この記事に返信する


レノス

リンク

2010/1/25(Mon) 23:44:12|NO.30160

#( さらに使っていくとモジュール変数機能の中途半端さがわかt(ry)。 )


#module mod_Enemy array AC

ここには、「array」などを付けられません
( なぜかエラーにしてくれないようですが )。


#modinit array p1 (他省略) AC = p1

この代入は、実際には「AC(0) = p1(0)」のことです。
そのため、1つめの要素しかコピーされていないのです。
配列変数 p1 のすべての内容を AC にコピーする、という意味ではありません。

もしそうしたければ、foreach や length を用いて、
すべての要素を代入するようにする必要があります。

( たぶん、これが答えになるのではないかと )


> HSPで、モジュール型の配列変数を異なるモジュール間で共有(と言うかコピー)する方法はあるのでしょうか。

「共有」と「コピー」は全くの別物なので、どっちを聞いているのでしょうか……?

共有する方法:
その配列変数がグローバルにあり、なおかつ要素数が途中で変化しないならば、dupptr でその配列丸ごとのクローンを作って、共有ができます。

そうでなければ、まともな方法は、思いつきません。

※かなり面倒ですが、配列変数をモジュール変数でラップすると可能です。

コピーする方法:( ↑ )

( 〜共有(する方法)、いや、なんならコピー(する方法)でもかまわないが、〜 という意味かも。 )



窓口

リンク

2010/1/26(Tue) 02:42:34|NO.30161

下の方法で複製可能です。
モジュール内変数 (#module で指定する変数名) を増減するたびに modmax の値を適切な値に変える必要があります。
少し不安定な感じですので、もしかしたら思わぬバグが有るかもしれません。



#define modmax 6 ; module内変数の総数に等しい ;********************************************* #module x a,b,c,d,e,f ; module内変数を六つ定義 ;--------------------------------------- #modinit int x_ ; 適当に値を代入 a = x_ b = str(x_) c = x_*2 b = double( x_) e = -x_ f = vartype(a) return ;--------------------------------------- #modfunc pf ; a をプリント。 mes a return #global ;********************************************* #module y modvar_ ;--------------------------------------- ;modinit array modvar , int modmax ; 1 module変数の配列 ; 2 module内変数の総数 ; 3 配列の総数 : length( modvar ) の値に等しい。 #modinit array x_ , int max_ ; module変数をコピー repeat length( x_ ) newmod modvar_ , x ; コピー先のmodule変数作成 memcpy modvar_(cnt) ,x_(cnt) , 48*max_ ; 見たところ module内変数一つの変数名につき 48byte確保しているようである為 loop return ;--------------------------------------- #modfunc printf ; 試しにプリントしてみる。 foreach modvar_ pf modvar_(cnt) loop return #global ;********************************************* newmod hoge , x , 1 newmod hoge , x , 100 newmod xx , y , hoge , modmax printf xx



木村

リンク

2010/1/26(Tue) 02:48:08|NO.30162

 こうすればAirCraft内の全データをEnemyに移行できると思います。

#module mod_AirCraft date ;mod_AirCraftは単純化して名称データのみ #modinit str s1 ;名称定義用のイニシャライズ命令 date=s1 return #modfunc draw ;名称を表示する命令 mes date return #modcfunc mdc_date ;名称データを引き出す関数 return date #global #module mod_Enemy AC #modinit array a1 if vartype(AC)=5 { ;既にモジュール変数としてACが定義されていた場合、 foreach AC ;要素全てを delmod AC.cnt ;消去する。 loop } ;そしてACを改めて白紙にしてから、 foreach a1 ;代入要素a1の数だけ logmes mdc_date(a1.cnt) newmod AC,mod_AirCraft,mdc_date(a1.cnt) loop ;ACに要素を新規代入していく。 return #modfunc all_draw ;ACの全要素をdrawする命令 foreach AC draw AC.cnt loop return #global repeat 20 ;20個のmod_AirCraftデータをfactorとして作成 newmod factor,mod_AirCraft,str(cnt+1)+"番目" loop newmod allfactor,mod_Enemy,factor ;それを一括してallfactorに代入 all_draw allfactor
 ポイントは、mod_Enemy内で使用するmod_AirCraftモジュールはmod_Enemyモジュールより
先に書いておく事。mod_Enemyへの#modinitをする為にモジュールデータを返す専用の関数
(今回の場合はmdc_date)を作っておく事でしょうか。

―――――――――――――――

 以下は余談です。
 今回のお題ではミサイルや敵機、障害物を含む全てのユニットデータをmod_AirCraftで、
その内の敵機データのみを抽出したデータをmod_Enemyという別のモジュールで表現している
ようでしたが、そのやり方は少々まどろっこしいと思います。

 敵機集団全体を表現するのであれば、普通にmod_AirCraftのモジュール変数だけで十分な
はずです。自機をAC_mine、自ミサイルをAC_minemsl、敵機をAC_enemy、敵ミサイルをAC_enemymsl
とでも表現しておけば十分でしょう。何よりこうして同じモジュールの次元にする事で、
敵機と自ミサイル、自機と敵ミサイル、自機と敵機、それぞれの衝突判定を同じ命令で
処理する事ができます。

[例α]
 例えば、mod_AirCraftモジュールの変数Aと変数Bとのヒットチェックを行う関数
hitcheck(A,B)   ※AとBが接触していれば1、そうでなければ0を返す
 を定義できたとすれば、上の3判定は以下のソースで処理できます。

#module hitcheck_module #deffunc all_hitcheck array a1,array a2 foreach a1 A=cnt foreach a2 B=cnt if hitcheck(A,B)=1 : delmod a1.A : delmod a2.B loop loop return #global repeat all_hitcheck AC_enemy,AC_minemsl all_hitcheck AC_mine,AC_enemy all_hitcheck AC_mine,AC_enemymsl await 17 loop

[例β]
 一方、敵機集団をmod_Enemy、敵ミサイル集団をmod_EnemyMsl、自機体をmod_Mine、
自ミサイル集団をmod_MineMslというように各集団毎にモジュールを変えてしまうと、
互いのヒットチェックをするスクリプトをそれぞれ作らなくてはいけなくなり、
労力が3倍になってしまいます。

(具体的にいえば[例α]のhitcheck_moduleと似た構造のスクリプトを2つ作らなくては
なりません。敵機と障害物、自機と障害物、等の新たなヒットチェックの必要が生まれた際も、
[例α]であれば

all_hitcheck AC_enemy,AC_hurdle all_hitcheck AC_mine,AC_hurdle
 と、追記するだけで良いものが、後者だとhitcheck_moduleを更にもう2つ作らなければ
なりません。)

 長文になりましたが、シューティングゲームを作るのであれば、敵機集団専用モジュール
を作るより、飛行体総合モジュールで一括処理した方が楽ではないのかなという提案です。
 長々と書いてしまいましたが、jiggerさんの参考になれば幸いです。



jigger

リンク

2010/1/26(Tue) 09:50:45|NO.30167

jiggerです。
回答ありがとうございます。
#module mod_Enemy array AC
の部分ですが、
#module mod_Enemy AC
の間違いでした。
本当はこのあと
#modinit array AC
で引数指定しています。

共有とコピーもまぎらわしくてすみません。
やりたかったのはコピーです。



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