|
|
|
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 パラメーターの値が異常です」と出てしまいます。
根本的になにかおかしいのでしょうか?
おかしいならばどこをどのように修正すればいいのでしょうか?
このへんのことについてもう少し詳しく教えてください
何度もすみませんがどうぞよろしくお願いします
|
|
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 帰る
だから、現在のスクプリトはまさにこのような
構造になっています。
ミサイルに命令を送るにはどうすればいいのでしょうか?
忙しく無いときでいいのでその辺を詳しく教えてください
よろしくお願いします
|
|
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
混乱させてたらゴメンナサイ^^;
|
|