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


HSPTV!掲示板


未解決 解決 停止 削除要請

2006
1226
のほほんズミサイルの作成・移動について13解決


のほほんズ

リンク

2006/12/26(Tue) 12:47:42|NO.4405

みなさんこんにちは
自分はタンク(戦車)を操るHGIMG3を使った3Dゲームを作っています
しかし、肝心なミサイルの作成・移動の部分がなかなかできず、困っています。
そこで、みなさんに間違いの指摘をしてもらいたくて
この掲示板に書き込みをしました

具体的にどのようにスクプリト作りたいかというと
モデルを登録>スペースキーを押すとタンクが向いている向きに、
ミサイル作成・移動(連射が可能)>一定時間後に消滅
※とりあえず当たり判定などは考えない

そして自分なりに作成したスクプリトを
投稿しますのでスクプリトの間違えを指摘してください

#include "hgimg3.as" *Main screen 0,600,400,0 hgini texload "Font.bmp" addxfile RBMMODEL,"のほほんズマシーン.x" ;タンク本体の登録 addxfile MISAIRUMODEL,"のほほんズミサイル.x" ;ミサイルモデルの登録 setuv 0,0,512,512 setsizef 120.0,120.0 addmesh FLMODEL,120,120,0 texload "Floor.bmp" gsel 0 regobj FLOBJ,FLMODEL setobjmode FLOBJ,OBJ_TREE,1 selang FLOBJ:objsetf3 0.0,0.0,0.0 selpos FLOBJ:objsetf3 0.0,1.5,0.0 cammode CAM_MODE_LOOKAT selcpos:objsetf3 0.0,-4.0,-11.0 selcint:objsetf3 0.0,0.0f,-3.0 regobj RBOBJ,RBMODEL selpos RBOBJ:objsetf3 0.0,0.0,-60.0 *DRAWLOOP hgdraw hgsync 20 stick KY,15 selpos RBOBJ:objgetfv FV selang RBOBJ if KY&4:addang RBOBJ,0.0,-0.05,0.0 if KY&1:addang RBOBJ,0.0,0.05,0.0 objgetfv FV2 FV2.1=-FV2.1 if KY&2: { fvdir FV2, 0.0, 0.0, 0.3 fvadd FV, FV2.0, FV2.1, FV2.2 } if KY&8: { fvdir FV2, 0.0, 0.0, -0.3 fvadd FV, FV2.0, FV2.1, FV2.2 } if KY&16: { ;ミサイルの作成・移動準備 BMTIME=200 ;時間設定 } if BMTIME>0 :gosub *BOMMOVE objgetfv FV2 FV2.1=-FV2.1 fvmin fv, -58.0,0.0,-58.0 fvmax fv, 58.0,0.0,58.0 selpos RBOBJ:objsetfv FV selcint:objsetfv FV fvdir FV2, 0.0, -4.0, -8.0 fvadd FV, FV2.0, FV2.1, FV2.2 selcpos:objsetfv FV objgetfv FV2 FV2.1=-FV2.1 goto *DRAWLOOP *BOMMOVE if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL ;ミサイルを作成 getpos RBOBJ,x,y,z ;タンク本体の座標を取得 if BMTIME=200:setpos MISAIRUOBJ,x,y,z ;タンク本体の座標をミサイルの作成座標に addpos MISAIRUOBJ,0.0,0.0,0.5 ;これだと正面にしか移動しない BMTIME=BMTIME-1 ;BMTIMEが0になるとストップする hgdraw fprt "TESTTIME:"+BMTIME,10,10 ;BMTIMEの残り表示 hgsync return
上のスクプリトを実行しても
正面にしか(タンクの向きには移動しない)ミサイルが移動せず
しかもミサイルを連射しようとしてスペースキーを
何回も押すと前に発射したミサイルが停止してしまいます

このスクリプトの問題点の指摘をよろしくお願いします



この記事に返信する


ふほ

リンク

2006/12/26(Tue) 19:52:52|NO.4415

単純に、*BOMMOVEを日本語にしてみるとですね。

>if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL ;ミサイルを作成
もしBMTIMEが200だったら、MISAIRUMODELのモデルを登場させ、管理番号をMISAIRUOBJに記憶する。

>getpos RBOBJ,x,y,z ;タンク本体の座標を取得
管理番号RBOBJの、xyz座標を取得する。

>if BMTIME=200:setpos MISAIRUOBJ,x,y,z ;タンク本体の座標をミサイルの作成座標に
もしBMTIMEが200だったら、管理番号MISAIRUOBJに先ほどのxyz座標を登録する。

>addpos MISAIRUOBJ,0.0,0.0,0.5 ;これだと正面にしか移動しない
管理番号MISAIRUOBJのX座標に0を足し、Y座標に0を足し、Z座標に0.5を足す。

>BMTIME=BMTIME-1 ;BMTIMEが0になるとストップする
BMTIMEの値から1を引く。

という動作をしている事が読み取れますが、まず、コレは意図したとおりの動作ですか?



のほほんズ

リンク

2006/12/27(Wed) 10:58:35|NO.4430

ふほさん、回答ありがとうございます。
ふほさんの言うとおり意図したとおりの動作です。

しかし、このスクプリトは
根本的にまちがっている可能性がかなりあります。

このスクプリトの直し方をアドバイスしてください。
よろしくお願いします。



ふほ

リンク

2006/12/27(Wed) 23:21:43|NO.4441

意図どおりという事でいくつか指摘いたします。

問題点は
○正面にしかミサイルが移動しない
○連射の為に何回も押すと前に発射したミサイルが停止する

の2点ですね?

そして、必要なのは、「問題点の指摘」ですね。
了解しました。


まず、ミサイルが正面にしか移動しない件に関しては、

>>addpos MISAIRUOBJ,0.0,0.0,0.5 ;これだと正面にしか移動しない
>管理番号MISAIRUOBJのX座標に0を足し、Y座標に0を足し、Z座標に0.5を足す。

ここで書いてある通り、z座標に0.5足しているだけだからです。
xy座標系でないのは、恐らく、普通の3dモデリングツールで作ったxファイルを、
そのまま御使用の為と思います(いや、悪い訳では有りません。私も面倒なのでそうしています)。

言うまでも無いですが、方向を定めて移動するには、x方向にいくらか、z方向にいくらか、
という指定をしなければなりません。

目的の角度と、一回分の移動距離がわかれば、三角関数で指定するべき数値は出ますが、
自キャラの移動が出来るのであれば、解る事と思われますので、
「ここで進ませる方向を決めてやってください」とだけ指摘します。


次に、連射の件ですが、
基本的にこのプログラムは連射できる仕様になっていません。

1、スペースキーを押すと、BMTIMEが200になる。
2、BMTIMEが200の時、ミサイルを画面につくり、自機の座標と同じ位置に表示する。
3、ミサイルを移動する。

しか、していません。

このままでは、もう一度スペースキーを押すと、今まで管理していたミサイルの存在を放りだして、
あたらしいミサイルの制御を始めてしまいます。

当然、古いミサイルは放置され、画面に残るだけです。

この点は、「複数のミサイルを管理できるよう、配列変数等を利用してください」と指摘させていただきます。


それでは、開発頑張ってくださいね^^
また、まだ解らなければ、このスレッド内で、どんどん聞いてくださいね^^



のほほんズ

リンク

2006/12/28(Thu) 14:06:49|NO.4450

丁寧な回答ありがとうございます
とりあえずタンクの向いている向きにミサイルを
移動させることに挑戦しました
そのスクプリトがこれです

*BOMMOVE BMTIME=BMTIME-1 if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL selang MISAIRUOBJ: objgetfv FV2: FV2.1=-FV2.1 selpos MISAIRUOBJ: objgetfv FV fvdir FV2, 0.0, 0.0, 0.5 fvadd FV, FV2.0, FV2.1, FV2.2 objgetfv FV if BMTIME<1:delobj MISAIRUOBJ hgdraw fprt "TESTTIME:"+BMTIME,10,10 hgsync return
今回は*BOMMOVEだけを変更しました
自キャラの移動のスクプリトをもとに作成しましたが
スペースキーを押した(*BOMMOVE 内に入った)とたん
タンクがすごいスピードでわけわからず回転し、
BMTIMEが0になると、
「Error 3 パラメーターの値が異常です」と出てしまいます。
根本的になにかおかしいのでしょうか?
おかしいならばどこをどのように修正すればいいのでしょうか?
このへんのことについてもう少し詳しく教えてください

何度もすみませんがどうぞよろしくお願いします



KIMU

リンク

2006/12/28(Thu) 18:09:58|NO.4471

Re: NO.4450

うーん
これはスクリプトの流れを追えば分かる問題なんだけど・・・
二つ問題あるだろうって所を書いてみる

>BMTIME=BMTIME-1
>if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL
BMTIMEの初期値が200ならregobj が実行されないので
この後の処理がObjID0(カメラのID)に対してやってる事になる

二つ目
>selpos MISAIRUOBJ: objgetfv FV
ミサイルの移動でミサイルオブジェに対してMOC設定命令を使ってるのに
ミサイルの処理が終わった後にそのまま
>objgetfv FV2
で、MOCに設定されている情報を収得してる
ミサイルが無い時には selang RBOBJ が直前のMOC設定命令になるので普通に動く

理由が分かれば解決方法は分かるよね?

>今回は*BOMMOVEだけを変更しました
ミサイル発生とミサイル移動を別けてみたら?
(問題の切り分けが、やり易くなるから)

>if KY&16: { ;ミサイルの作成・移動準備
> BMTIME=200 ;時間設定
>}
ここで、ミサイルオブジェを作って自機の座標と角度をミサイルに設定しておけばいい


後、質問の内容には直接関係無いけど
>hgdraw
>fprt "TESTTIME:"+BMTIME,10,10
>hgsync
これは必要ないだろう(後々問題になる可能性あるし・・・)

*DRAWLOOP hgdraw if BMTIME{fprt "TESTTIME:"+BMTIME,10,10} hgsync 20
こっちに入れとけば良いと思う



ふほ

リンク

2006/12/28(Thu) 19:24:36|NO.4474

こんばんは。

えーとですね、指摘されていますが、少し説明が少ないかなと思ったので、
補足させて頂きます。

*BOMMOVE
BMTIME=BMTIME-1
if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL

ココなんですが。

折角スペースキーを押してBMTIME=200にしていても、
if BMTIME=200が実行される前にBMTIME=BMTIME-1が実行されているわけです。

if命令を実行したときのBMTIMEの値は、いくら?

199になっていますヨ。

よって、ミサイル登場部分は実行されません。


それ以降は、ミサイルの管理番号が存在しないのに、「なにか」に対して命令を発し続け、
存在しないミサイルの管理番号を削除しようとした為に、エラーになった物と思われます。

まあ、この「なにか」はカメラIDにあたるのでしょうか。

こんなトコロでしょうか。

あとはKIMUさんの提案されている方法をとって見ると、プログラムが整理されて
良いと思います^^

頑張ってくださいね^^



ふほ

リンク

2006/12/28(Thu) 19:40:22|NO.4475

ところで、私、一番最初の書き込みの最後の一言、

>このスクリプトの問題点の指摘をよろしくお願いします

に大変、「漢気」を感じ、

これはもう、敢えて、
「サンプルスクリプト等は提示しない方向で進めたい・・・!」
「最後まで、自力での解決を望もう!自分は問題点の指摘だけ・・・!」

等と、俄然一人で萌えておりますがw

皆さん如何な物でしょうか。
いや、いぢめっこ気質ってワケでなく、純粋にデスね・・・^^;



のほほんズ

リンク

2006/12/31(Sun) 16:40:15|NO.4562

みなさん回答ありがとうございます
そして、返事が遅くなって申し訳ございません
返事が遅くなったのはまだ解決できず、いろいろと試行錯誤していたからです
不快な思いをさせてしまったならば大変申し訳ございません

早速本題なのですが
ミサイルを移動させたいのに下のスクプリトでは
なぜかタンク本体が移動してしまいます。
※ミサイルからタンク本体が発射される感じになります

*DRAWLOOP if KY&16: { BMTIME=200 ;タイマーセット if BMTIME=200:regobj MISAIRUOBJ,MISAIRUMODEL ;BMTIME=200ならばミサイルを作成 selpos RBOBJ:objgetfv FV ;タンク本体の座標を取得 selpos MISAIRUOBJ: objsetfv FV ;タンク本体の座標をミサイルの座標に selang RBOBJ:objgetfv FV2 ;タンク本体の角度を取得 selang MISAIRUOBJ:objsetfv FV2 ;タンク本体の角度をミサイルの角度に } goto *DRAWLOOP *BOMMOVE BMTIME=BMTIME-1 ;タイマーを減らす fvdir FV2, 0.0, 0.0, 0.5 ;移動処理 fvadd FV, FV2.0, FV2.1, FV2.2 ;移動処理 if BMTIME<1:delobj MISAIRUOBJ ;BMTIME(タイマー)が1以下ならばミサイル消滅 return
どこが問題なのでしょうか
何度も申し訳ありませんがスクプリトの改善をお願いします

あとふほさんのNO.4475の記事についてですが
>このスクリプトの問題点の指摘をよろしくお願いします
というのは
単に自分は文章で表現するのが苦手なためこのような文になってしまいました
実際チョットスクプリトの提示を望んでいたのですが
それを文面にあらわすのは失礼なことだと思い込み
誤解を招くこととなってしまいました
今度からは気をつけるようにします。



ふほ

リンク

2006/12/31(Sun) 17:46:03|NO.4565

こんばんは、出かける直前に気づいたので、細かくかけませんが、ぱっと見て気づいた事だけ書いてみます。



ミサイルでなく、タンクが動いてしまうのは、(全体がどうなっているのかよく分かりませんが恐らく)
*BOMMOVEの中で、何に対して移動させるかを、具体的に指定していないためだと思います。

メインのループの中でタンクの移動をさせる為に、タンクを移動させる設定をしていると思いますが、
ソレが終わったあと、ミサイルを動かす師弟をしていないため、そのままタンクに、ミサイルの移動処理が
かけられているのだと思います。


つまり、こんな感じになっていないかな?ということです。

1 タンクの数値を変更する設定をする
2 タンクの向きや移動処理を行う
3 スペースキーが押された
    タイマーを設定し、ミサイルを登場させ
    ミサイルの数値を変更する設定にし、
    位置や向きを指定する
4 サブルーチンAへ
5 1にもどる

サブルーチンA
1 タイマーを減らす
2 移動させる
3 タイマーがなくなッたらミサイルを消す
4 帰る


このサブルーチンの中で、「ミサイルの数値を変更する」指定が無いので、
スペースが押されなかったときは、戦車のほうが動いてしまうのだと思われます。


>実際チョットスクプリトの提示を望んでいたのですが
>それを文面にあらわすのは失礼なことだと思い込み

ああ、なるほど^^;了解しました。

必要が有れば書くようにします^^;
が、今はちょっと忙しいので^^;

それでは、頑張ってみてください^^



のほほんズ

リンク

2006/12/31(Sun) 19:48:27|NO.4566

忙しい中、回答ありがとうございます
自分でもふほさんのいうとおり
ミサイルに対して命令を実行させるという命令が
欠けているということにうすうす気づいていましたが
どのようにミサイルに命令を出すのかがわからない上に
スクプリトに問題があるのかもしれないと思ったので
とりあえず修正したスクプリトを投稿しました

>1 タンクの数値を変更する設定をする
>2 タンクの向きや移動処理を行う
>3 スペースキーが押された
>    タイマーを設定し、ミサイルを登場させ
>    ミサイルの数値を変更する設定にし、
>    位置や向きを指定する
>4 サブルーチンAへ
>5 1にもどる
>
>サブルーチンA
>1 タイマーを減らす
>2 移動させる
>3 タイマーがなくなッたらミサイルを消す
>4 帰る

だから、現在のスクプリトはまさにこのような
構造になっています。

ミサイルに命令を送るにはどうすればいいのでしょうか?
忙しく無いときでいいのでその辺を詳しく教えてください

よろしくお願いします



KIMU

リンク

2007/1/2(Tue) 04:18:01|NO.4621

>だから、現在のスクプリトはまさにこのような
>構造になっています。
コメントの付け方が原因で問題が見えなくなってるのかな・・・
NO.4562の
>fvdir FV2, 0.0, 0.0, 0.5 ;移動処理
>fvadd FV, FV2.0, FV2.1, FV2.2 ;移動処理
は、移動処理と言えば移動処理だけど、座標計算してるだけで、ミサイルオブジェには何もしてない
後、ミサイルを発射した直後しか FV、FV2 には、ミサイルの座標角度が入っていない
(本当は自力で解決して欲しかった・・・)

#include "hgimg3.as" hgini setfont 16,16,10,1 :texload dir_exe+"\\sample\\hgimg3\\fontchr.bmp" setuv 0,0,127,127 :setsizef 2,2 :addbox RBMMODEL setsizef 0.5,0.5 :addbox MISAIRUMODEL setuv 0,0,127,127 :setsizef 120.0,120.0 :addmesh FLMODEL,1,1,0 :texload dir_exe+"\\sample\\hgimg3\\btex.bmp" regobj FLOBJ,FLMODEL :setobjmode FLOBJ,OBJ_TREE,1 :selang FLOBJ:objsetf3 0.0,0.0,0.0 :selpos FLOBJ:objsetf3 0.0,1.5,0.0 cammode CAM_MODE_LOOKAT :selcpos:objsetf3 0.0,-4.0,-11.0 :selcint:objsetf3 0.0,0.0f,-3.0 regobj RBOBJ,RBMODEL :selpos RBOBJ:objsetf3 0.0,0.0,-60.0 //ここより上は、コピペしてそのまま実行できるように変えただけ hggetreq MAXOBJ,SYSREQ_MAXOBJ //オブジェクトを作れる最大数を収得 MISACOLID=2 //ミサイルのコリジョンID MISACNT=0 //現在のミサイル発射数 MISAMAX=25 //ミサイル最大発射数 dim BMTIME,MAXOBJ //タイマーをオブジェクトが作れる最大数まで確保(ミサイルだけに使うと無駄があるけど他にも使えるので気にしない) *DRAWLOOP hgdraw fprt "MISACNT "+MISACNT,0,0 // findobj 0,MISACOLID //ミサイルオブジェID検索準備 repeat MISACNT // nextobj MISAIRUOBJ //ミサイルオブジェID検索 fprt "ID="+str(MISAIRUOBJ)+" ["+BMTIME(MISAIRUOBJ)+"]",0,16*cnt+20 // loop // hgsync 15 // stick KY,15 selpos RBOBJ:objgetfv FV selang RBOBJ if KY&4:addang RBOBJ,0.0,-0.05,0.0 if KY&1:addang RBOBJ,0.0,0.05,0.0 objgetfv FV2 FV2.1=-FV2.1 if KY&2: { fvdir FV2, 0.0, 0.0, 0.3 fvadd FV, FV2.0, FV2.1, FV2.2 } if KY&8: { fvdir FV2, 0.0, 0.0, -0.3 fvadd FV, FV2.0, FV2.1, FV2.2 } objgetfv FV2 FV2.1=-FV2.1 fvmin fv, -58.0,0.0,-58.0 fvmax fv, 58.0,0.0,58.0 selpos RBOBJ:objsetfv FV selcint:objsetfv FV fvdir FV2, 0.0, -4.0, -8.0 fvadd FV, FV2.0,FV2.1,FV2.2 selcpos:objsetfv FV if ((KY&16)>0) and (MISACNT<MISAMAX){;ミサイルの作成・移動準備 //自機の座標が決定する前にミサイルを撃つと位置がずれるから移動した //(他にもselangや同じ変数名を使っている事で起こる不都合を回避する為) MISACNT++ //ミサイル発射数+1 regobj MISAIRUOBJ,MISAIRUMODEL //ミサイルを作成 selpos RBOBJ:objgetfv FV ;タンク本体の座標を取得 selpos MISAIRUOBJ: objsetfv FV ;タンク本体の座標をミサイルの座標に selang RBOBJ:objgetfv FV2 ;タンク本体の角度を取得 selang MISAIRUOBJ:objsetfv FV2 ;タンク本体の角度をミサイルの角度に setcoli MISAIRUOBJ,MISACOLID //コリジョンID設定 BMTIME(MISAIRUOBJ)=200 //MISAIRUOBJ内のIDに対応した変数要素にタイマーセット } if MISACNT>0 :gosub *BOMMOVE //1個以上ミサイルが発射されていたら移動処理 goto *DRAWLOOP *BOMMOVE findobj 0,MISACOLID //ミサイルオブジェID検索準備 repeat MISACNT //発射数分繰り返し nextobj MISAIRUOBJ //ミサイルオブジェID検索 BMTIME(MISAIRUOBJ)-1 //IDに対応した変数要素のタイマーを減らす if BMTIME(MISAIRUOBJ)<1 {//BMTIME(タイマー)が1以下ならばミサイル消滅、 delobj MISAIRUOBJ MISACNT-- //発射数-1 }else{ selang MISAIRUOBJ:objgetfv FV2 :FV2(1)=-FV2(1) //ミサイルの角度収得してY反転 fvdir FV2, 0.0, 0.0, 0.5 ;移動処理 addpos MISAIRUOBJ, FV2(0),FV2(1),FV2(2) //ミサイルに移動量加算 } loop // return
"//"の付いてる所が新しく追加や変更した所

弾を実現する方法は色々あるので、これが正しいとか言うのはありません。
毎フレーム自分で移動させなくても setdir等でオブジェのdirに自動移動量を設定する事や
event_系命令で移動から消滅まで自動で行う事もできます。

複数撃てるようにする方法も一つじゃありません。



のほほんズ

リンク

2007/1/2(Tue) 14:32:28|NO.4625

KIMUさん回答ありがとうございます
投稿してくださったスクプリトを少し
改造し、自分のスクプリトにあててみたら、
解決しました

KIMUさん、ふほさん最後までありがとうございました



ふほ

リンク

2007/1/3(Wed) 11:50:33|NO.4630

ただいまー。ってw
遅かったかw


あ、出かける前の自分、勘違いしてたw
混乱させてたらゴメンナサイ^^;



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