ナビ
投稿者 : tava(52.3.112.219.ap.yournet.ne.jp)
- 2007/01/11(Thu) 00:48
No.10751
|
|
|
|
|
こんばんは。 えと、一番近い敵の方向に矢印を向かせるという事をしました。 それで検索で調べて↓のようにプログラムを組みました。
min=999999999; for (t in $chars) { if ((t is e1 || t is e2 || t is e3 )) { d=dist(t.x-x,t.y-y); if (d<min) { min=d; target=t; }}}
muki=angle(target.x-x,target.y-y)+90; drawDxSprite(x,y,$pat_efe+1,0,40,muki,100,1,1);
これで複数の敵オブジェクトがいても、tに代入されている中で一番近いものに矢印が向くようになってくれました。 しかし、敵が全滅した場合は座標0,0の部分に矢印が向き、最初から敵がいないとエラーになってしまいます。 敵が全滅した場合もエラーになると思ってたんですけど違ってましたね。 昔、コレに近い問題を解決させた作品をアップロード板に置いたことがあるんですが消えてしまった(?)ようで・・・。 それより昔に置いたものは残ってたんですけどねぇ。 検索で何度も調べて、一日悩んだんですが解決することはできませんでした・・・。 初歩的かも知れませんがどなたか教えていただければ有難いです。
|
Re: ナビ
投稿者 : ごま太郎(i60-47-201-236.s02.a002.ap.plala.or.jp)
- 2007/01/11(Thu) 01:45
No.10752
|
|
|
|
まず、最初から敵がいないとき、変数targetにはnull値が入っています。 nullは何もデータがないという意味なので、nullのxやyを参照しようとしても、そんな変数は持っていないので参照できなくてエラーが出ます。
次に、全滅させた場合、変数targetは初期化されてないので、最後に参照した敵のグローバル変数名($e1とか、$e11とか)が入っています。なので、こいつらはxやyといった変数を所持しているので参照することができるのですが、die()されてるために変数の値はnull値になっています。 この時、null値は0として処理されて、結果的に、矢印は座標(0,0)を向きます。 ちなみに、全滅させた場合の話は、予想で書いたので確実じゃないです。たぶんこんな感じだと思いますけど、ところどころ間違っているかも^^;
で、これを解決するにはどーしたらいいのか。 if文を使って、変数がnull値かどうかを調べるのが一つの方法です。 または、敵の数を変数に記録しておいて、敵が1体以上いたら矢印は敵のほうを向くようにプログラムしましょう。ちなみにお薦めは二つめの方。
理由はまず簡単だから。それに、一つ目の方法は、私の予想に基づくので確実じゃありません。で、もう一つの理由は、tavaさんの書かれた方法を毎フレーム実行するとめちゃくちゃに重くなる可能性があります。特に、一ページに多量のオブジェクトを配置するようになると鬼です。 なので、配列を自由に使えるようでしたら、次のような方法がいいです。
まず、敵を敵専用の配列に挿入します。 enemy = new Array(); for (t in $chars) { if (t is e1) enemy.add(t); //みたいな感じ }
そして、実際に矢印に一番近い敵を探すときには、for (t in $chars)の代わりに for (t in enemy) { //処理内容 } と書くと、for (t in $chars)よりも無駄なく敵だけに処理を行えます。 敵の数は、enemy.size()で取得することができてお手軽です。 $charsは、実は配列$charsにページ内の全てのオブジェクトを代入したものです。 このfor文の使い方は、配列の0番から要素を一つずつ変数tに代入し、括弧内を実行するというものです。helpにも載っています。
とはいえ、今のは一つの例ですので、ちょっと考えながらお好きな方法をとってみてください。
|
Re: ナビ
投稿者 : tava(247.94.113.221.ap.yournet.ne.jp)
- 2007/01/11(Thu) 10:08
No.10755
|
|
|
|
しっかり動作してくれました。 ごま太郎さんありがとうございます! 今まで配列を使おうとしてなかったので全く分からなかったのですが、ごま太郎さんのプログラムとヘルプを見てたら少しわかってきました。 とりあえず↓のように組んでみました。
min=999999999; enemy = new Array(); for (e in $chars) { if ((e is e1 || e is e2 || e is e3|| e is e4))enemy.add(e); }
for (e in enemy) { if ((e is e2)) {//////////☆ d=dist(e.x-x,e.y-y); if (d<min) { min=d; target=e; muki=angle(target.x-x,target.y-y)+90; } }
} if(enemy.size()==0){muki=0;} drawDxSprite(x,y,$pat_efe+1,0,40,muki,100,1,1);
☆印のところでまた e is e2 e is e3...と入れていくことになってしまうようになったんですが、ホントは一気にenemyとして判断できるんじゃないかな。 とか思ったんですよね・・・↑のじゃもしかして効率が悪いかなとか。 あと、こういう配列は敵が多くなる場合などを考えて率先して使ったほうがいいんでしょうか?
|
Re: ナビ
投稿者 : ごま太郎(i60-47-201-236.s02.a002.ap.plala.or.jp)
- 2007/01/11(Thu) 15:13
No.10756
|
|
|
|
>>一気にenemyとして判断できるんじゃないかな その通りです。 すでに、eがクラスe1、e2、e3、e4のようなものだと判定してから配列enemyに代入しているので、再度判定する必要はありません。
ちなみに、こういうときには、コメント文を活用するとデバッグが楽です。 for (e in enemy) { //if ((e is e2)) {//////////☆ d=dist(e.x-x,e.y-y); if (d<min) { min=d; target=e; muki=angle(target.x-x,target.y-y)+90; } // } } こういう風にして、if文と括弧を「//」でコメント文にして、正常に働くかどうかを調べてみるといいです。
>>こういう配列は敵が多くなる場合などを考えて率先して使ったほうがいいんでしょうか? ゲームの種類にもよるんですが、このような処理を多用するなら作ってみたほうがいいかもしれません。 とはいえ、作りすぎると今度は管理が面倒になるのでうまくバランスをとる必要があります。ついでに、配列の機能は理解するのが少し面倒なので、勉強しながら組み込んでいくと何がなんだか分からなくなることもあるので気をつけてみてください^^;
|
Re: ナビ
投稿者 : tava(52.3.112.219.ap.yournet.ne.jp)
- 2007/01/11(Thu) 19:19
No.10757
|
|
|
|
再度の判定はいらないんですね。 配列をもっと理解していってうまく活用していきたいと思います。 あと、コメント文を使っての動作テストは今まで思いつきませんでした。 ワードパッドに切り取ってやってたものですから・・・; ごま太郎さんありがとうございました。
|
|