ページ 11

進行方向に画像が向くショット

Posted: 2008年11月17日(月) 16:20
by 匿名
シューティングゲームの館とかの「進行方向に画像が向くショット」とかを読んだのですが、よくわかりませんでした。DrawRotaGraph関数の第四引数とかを1フレームあたりの移動距離とかから求めたいのですが、どういう式を書けばいいのでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年11月17日(月) 16:24
by Dixq (管理人)
弾に「進行方向」を持たせておけば、
軌道計算時もそれを使って計算すればいいですし、
描画時もそれを使って描画すればいいだけになります。

Re:進行方向に画像が向くショット

Posted: 2008年11月18日(火) 22:02
by 匿名
うーん、まあそうだとは思うんですけど、具体的にはどういう計算をすれば回転率になるでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年11月19日(水) 02:27
by Dixq (管理人)
例えば弾データの構造体に角度を表す

~.Angle

なる変数があるとします。
弾の発射角度を登録する時に、例えば下に発射する時は

~.Angle = π/2;

ですよね。で、座標を計算する時は

~.x += cos( ~.Angle ) * ~.Speed;
~.y += sin( ~.Angle ) * ~.Speed;

で計算出来ますよね。
描画する時は仰っている関数の第四引数にこの~.Angleを指定すればいいのです。
 

Re:進行方向に画像が向くショット

Posted: 2008年11月20日(木) 16:30
by 匿名
.Angle = π/2;

下ですからπは6.28ですかね? 
ではいろいろな方向に撃つ時は2を変えればいいんですか?
それだったら2の部分に入る数値はどうやって出せばいいんですか?

~.x += cos( ~.Angle ) * ~.Speed;
~.y += sin( ~.Angle ) * ~.Speed;

見た感じcos( ~.Angle )とsin( ~.Angle )が1フレームにどれだけ増えるかを
計算してくれているようですね。
具体的にはどんな数値が出てくるのでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年11月20日(木) 17:14
by Dixq (管理人)
>.Angle = π/2;
>下ですからπは6.28ですかね?

円周率を2で割ったら6.28になりますか?
πとは円周率の事です。円周率がいくつかご存知でしょうか?
もしご存じなければぐぐってみましょう。

>ではいろいろな方向に撃つ時は2を変えればいいんですか?

2を変えるより、計算式を変えたほうがいいですね。
円周率と向きの関係はわかりますか?

問1. 180度は円周率を使うといくらと表せますか?440度はいくらですか?

それがわかればどちらの方向にもセット出来るはずです。

>見た感じcos( ~.Angle )とsin( ~.Angle )が1フレームにどれだけ増えるかを
>計算してくれているようですね。

そうではありません。cosとsinは単位円におけるx成分、y成分を求めているだけです。
実際の長さはスピードをかける必要があります。
サイン、コサインってどういうものかご存知でしょうか?

問2. 斜辺の長さ3の直角二等辺三角形の底辺の長さがいくらかわかりますか?

>具体的にはどんな数値が出てくるのでしょうか?

問1.2.の答えを理解した上で、自分で試してみれば一番良く解るかと思います。
試さなくても、理解していればどんな値が出るかは想像でき、
また、詳しく想像する必要も無い事がわかります。

疑問があるなら、省略せず一つ一つきちんと理解していくことが大事です。

Re:進行方向に画像が向くショット

Posted: 2008年11月20日(木) 18:55
by 匿名
ああπですか、すいません、よく見えませんでした。
π/2が下と言うことは1.57が下ですか?
画像の回転だと3.14が下だった気がするんですが。

>問1. 180度は円周率を使うといくらと表せますか?440度はいくらですか?
調べてみましたが180度はπだと思います。
440度は暗算ではパッと出ないので、電卓を使ってみると・・2.44πですかね・・
πって180度でしたっけ?

cos( ~.Angle )とsin( ~.Angle )ですがもう少し想像力を働かせると
進行方向に1進むとXとYがいくら増えるか・・ですかね?
で、それにスピードをかけるとN進むとXとYがこれだけ増える。
ってことですかね?少しは近づきましたか?

>問2. 斜辺の長さ3の直角二等辺三角形の底辺の長さがいくらかわかりますか?
直角二等辺三角形だから
斜辺は√2に対して残りの二辺は1だから・・
3の二乗で斜辺は9になるから、1辺は二乗して半分の4.5になる数と言うことで・・
底辺は√4.5・・なのかな・・

でセットですがπ/2が下だから
右はπ/4、左は・・π/1.5?、上はπですかね?

では撃つ方向が決まっていなかったらどうすればいいですかね?
少し苦労話をすると

相手の方に撃つ場合どうするか考えた結果が、まず当たり判定の時のように

(相手のY座標-自分のY座標)の2乗 + (相手のX座標-自分のX座標)の2乗
で斜辺の2乗を求めて、関数で平方根を求め斜辺の長さを出した後
相手とのY,X座標の差を斜辺の長さで割った数にスピードをかけて
1フレームでどのぐらい進むかを出して毎回その数を足しています。

自分でも見ていていやになる処理です。正確に相手に飛ばないし・・

角度の計算でこれがきちんとした物になるのなら助かります。
しかし、撃つ方向が決まっていない場合πを何で割るかを
どうやって求めればいいんでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年11月20日(木) 19:34
by Dixq (管理人)
>π/2が下と言うことは1.57が下ですか?
>画像の回転だと3.14が下だった気がするんですが。

使っている画像の初期方向が上なんじゃないでしょうか?
データファイルを確認して下さい。
描画の関係上、xが正の方向が右、yが正の方向が下ですね。
角度0は右ということになります。そして90度はπ/2ですよね。
ですから、プログラムの計算上、下はπ/2になります。
弾の画像が上向きなのなら、描画する時に

~.angle + π/2

してやればいいと思います。

>cos( ~.Angle )とsin( ~.Angle )ですがもう少し想像力を働かせると
>・・・
>ってことですかね?少しは近づきましたか?

そうですね。
斜辺1に対するx,y成分なので、スピードをかけてやれば、その成分もスピード倍され、適切なスピードで指定した方向に飛びます。

>440度は暗算ではパッと出ないので、電卓を使ってみると・・2.44πですかね・・ πって180度でしたっけ?

そうですね。πは180度ですから

(440.0 / 180) * π

と表せますね。「720度はπであらわすと?」のようにフィーリングで答えられそうな問題だと自分がどんな計算式でそれを計算したのかわから無いかと思い、わざときっちり答えの出ない数字にしました。
もし答えを小数でかくなら仰るように2.4444....πですね。
計算は機械がやってくれるので、私達は式さえ作れたらオッケーです。
逆に言えば答えだけ出せたのではプログラムが作れない場合が多いです。

>直角二等辺三角形

この答えは是非サインコサインを使って欲しかったのです。
コサインって斜辺分の底辺ですよね?
って事は「斜辺×コサインθ」で斜辺が相殺されますから底辺が出ますね。
コサインは「√(2)分の1」ですね。斜辺は3なのですから「3/√(2)」になりますね。

コサインθがいくつになるかは知っている必要はありません。
機械が計算してくれます。
自分は「斜辺にコサインθをかければx成分が出るんだな」だけ知っておけばいいのです。
じゃ

問3. 斜辺の長さ5、角度θ=61°の直角三角形の対辺の長さはいくらですか?

>相手のいる方向に撃つ

これはアークタンジェント(逆正弦)を計算する関数で計算出来ます。
atan2 という関数に
atan2( 相手のy座標 - 自分のy座標 , 相手のx座標 - 自分のx座標 );
と渡してやるとその角度が返ります。

これを弾の発射角度にしてやればいいです。

Re:進行方向に画像が向くショット

Posted: 2008年11月20日(木) 19:44
by Dixq (管理人)
問4. この矢印の方向に撃つには

#define PI 3.1415926

という定義を使って

~.angle

にどんな値を代入すればいいですか?
 

Re:進行方向に画像が向くショット

Posted: 2008年11月21日(金) 18:43
by 匿名
>使っている画像の初期方向が上なんじゃないでしょうか?
>データファイルを確認して下さい。

まさにその通りです。

>描画の関係上、xが正の方向が右、yが正の方向が下ですね。
>角度0は右ということになります。そして90度はπ/2ですよね。
>ですから、プログラムの計算上、下はπ/2になります

では画像の初期方向は右のほうがいいんですか?

問3. 斜辺の長さ5、角度θ=61°の直角三角形の対辺の長さはいくらですか?
対辺ですからyですよね、式は5×サイン61°
61°は・・たしか0.57かな、
では対辺は2.85?

問4. この矢印の方向に撃つには・・
うーん、どうやったらいいですかね。
とりあえず矢印のどこかに点をとってyとxの差を出してPIをその割合で割れば出ますかね?

Re:進行方向に画像が向くショット

Posted: 2008年11月22日(土) 06:10
by Dixq (管理人)
>では画像の初期方向は右のほうがいいんですか?

いや、上にも書いたとおり、描画する時に+PI/2すればいいだけです。

>61°は・・たしか0.57かな

覚えてるんですか?
三角関数表はすべて覚えるのは困難だと思います。
http://emath.s40.xrea.com/ydir/Wiki/ind ... F%F4%C9%BD
覚える必要もありませんしね。
式は正解です。答えは違いますが・・。
「答え」を書く必要はないです。「答えにつながる式」がかければいいです。
ですので、お書きになったとおり
5×サイン61°
までで大丈夫です。sin(61°)はプログラムが計算してくれます(中身はホントは弧度法表記)。

問4は今まで説明してきたことを確かめるために言ったことなので、よく今までのことを思い返せばわかると思います。
~.Angle
の役割を考え、何を代入したらいいか考えてみてください。

>矢印のどこかに点をとって

とれますか?

Re:進行方向に画像が向くショット

Posted: 2008年11月22日(土) 15:44
by 匿名
>いや、上にも書いたとおり、描画する時に+PI/2すればいいだけです。
Angle+PI/2の時にAngleにはなにが入っているのか気になりますが
やはり正規の方法の方がしっくりくるので右にしておきます。

>覚えてるんですか?
いえ覚えていたわけではなく、学校で電卓を使って出した後に下校時刻になったので
家に帰って書き込む時に確か0.57だったかなと思い出しただけです。

問4. この矢印の方向に撃つには・・
どうすればいいかなー
矢印の先に敵でもいればアークタンジェントで出せそうだけど
それじゃPIが使えないし・・
見た感じ矢印は上に対して45度ぐらいだから
右が0で下が1.57だったから左が3.14、上は4.71になる・・かな?
では逆算すると.Angle = π/0.625;ぐらいになるかな?

Re:進行方向に画像が向くショット

Posted: 2008年11月23日(日) 01:45
by Dixq (管理人)
>問1. 180度は円周率を使うといくらと表せますか?440度はいくらですか?

でせっかく計算式を作ったのでこれを使って見ましょう。
画像の矢印は特に角度をかかなかったので、はっきりした正解は無いですが、上に60°位のつもりでした。
45°でもいいです。
45°にしておきましょう。
では、この角度ってプログラム上、そして弧度法でいくらでしょうか?
右って0度ですよね。下って90度、左は180度、上は270度、右は360度ですよね。
上と右の間なので、270+45度ですね。
または-45度です。
45度って180度の4分の1ですよね。それならもう答えは出ますよね。

そうやって考えるとどちらの方向にも弾は飛ばせると思います。

Re:進行方向に画像が向くショット

Posted: 2008年11月25日(火) 15:54
by 匿名
だいぶわかってきました
ところで「~.Angle 」ですが角度なので
int型だと小数点以下が切り捨てられるからfloat型とかにすればいいんですか?
そうだとしても座標は整数ですから少しずつずれてくるんじゃないでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年11月25日(火) 19:08
by Dixq (管理人)
もちろん角度や座標のデータはfloatやdoubleにすべきです。doubleでいいと思います。

Re:進行方向に画像が向くショット

Posted: 2008年11月26日(水) 14:56
by 匿名
doubleですか、なるほどなるほど
でも描画系の関数にdouble型をつっこんでもちゃんと動くんですかね?

Re:進行方向に画像が向くショット

Posted: 2008年11月26日(水) 15:17
by Dixq (管理人)
DrawGraph関数に渡す座標は確かにint型ですが、計算はdoubleでやって、描画はintでやればいいのです。

DrawGraph( (int)~.x, (int)~.y, .... );

のように。また、小数点を表現できる描画関数も存在します。

DrawGraphF( (float)~.x, (float)~.y, .... );

関数の後ろにFをつけるとfloat型の座標を渡す事のできる描画関数になります。
ドット絵のRPGなどでは使ってもよく利点がわかりませんが、
シューティングのように細かい弾が大量に色んな方向に飛ぶようなシーンでは重宝します。
 

Re:進行方向に画像が向くショット

Posted: 2008年11月27日(木) 17:44
by 匿名
つまり毎回 int=double とでもしてから渡せばいいんですか?
(int)~.xってどういう意味ですか?

話は変わりますが、今まで「構造体?配列でも同じじゃないの?」
とか言って目をそらしてきましたけど、そろそろ構造体を使ったほうがいいですね。
で、構造体の宣言はどうやるんでしたっけ?

Re:進行方向に画像が向くショット

Posted: 2008年11月27日(木) 21:21
by 通りすがり
プログラムは自分で勉強するものです。
そして構造体やキャストはC言語の基本です。
ウェブの解説などでも十分勉強できるのですからまず自分で勉強しましょう。

Re:進行方向に画像が向くショット

Posted: 2008年11月28日(金) 16:58
by 匿名
と、言われたので一応調べてみました。

struct p {
int a;
char b[5];
double c;
};

で枠を作り

struct p a;

で宣言するようですね。

struct p = { 0 , "aaa", 00.0 };

が初期化みたいですね。b[5]に全部aaaが入るのかな?

struct p[3] {
int a;
char b[5];
double c;
};

と書くと構造体配列になるようですね。

struct p[3] = {
{ 0 , "aaa", 00.0 }
{ 0 , "aaa", 00.0 }
{ 0 , "aaa", 00.0 }
};

のように初期化するらしい、これまとめられないのかな?

struct p[3] {
  struct s[3] {
     int a;
char b[5];
double c;
  }
};

で構造体の中に構造体、になるのか?

struct p[3] = {0};

とかで全部に0が入らないかな、これ。

p[0].a

のように書いて使うようですね。

p[0].s[0].a

構造体の中に構造体があったらこんな感じかな。

調べた結果はこんな感じ、結論を言うと自分には独学は向いていないらしい。質問したほうが早そうだ・・・

でも構造体の中に構造体と言うのは使えるかもしれない
一度に5個の弾を発射するショットの場合

struct s[10] {
int f;  
struct s[5] {
     int f2;
  }

};

弾一つ一つのフラグをf2に格納し
すべて0になったらfを0にすればいいのだろう
これを10個作っているので5個一組の弾が同時に10個存在できることになると言うわけだ。

では具体的にいくつ変数がいるだろうか?

パッと思いつくのは

フラグ
X,Y座標
角度
カウンタ

になる
画像の種類は処理ごとに決まっているので書く必要はないと判断したがどうなのだろうか?
私はいつも弾の種類ごとに処理と描画を独立させているのだが
普通は一緒にするものだろうか?
だから画像の種類も飛ぶパターンも処理ごとに決まっているから
配列に入れる必要はなかったのだがこれでいいのだろうか?

とりあえず今までにわかったことを総合して構造体を作ってみよう

struct c {//1Pから4Pまで誰が撃っているか

struct p {//ショットの種類

struct t {//何発目か

int mf;//弾一組のフラグ

struct s {//弾一つの構造体

int f;//弾一つ一つのフラグ
double x,y;//X,Y座標
double a;//角度
int k;//カウンタ

};
};
};
};

struct s[10];
struct t[10];
struct p[8];
struct c[4];

今作ろうとしているゲームだとこんな感じになりますね。
ええ、おかしい事は自分でもわかっています。
なにこの四重構造体?ありえないでしょ
さてどうすればいいでしょうかね。
と言うより上に書いた構造体の作り方、あってますかね?
7割がた間違ってると思うんですけど。

Re:進行方向に画像が向くショット

Posted: 2008年11月28日(金) 17:46
by 通りすがり
う~ん、指摘ばかりするのもあれですが

>調べた結果はこんな感じ、結論を言うと自分には独学は向いていないらしい。質問したほうが早そうだ・・・

はっきり言って回答する気が無くなります。
まず、ソースコードはタグを使うなど規約を守るところから始めて下さい。

あと、構造体を階層化したい時は、構造体の定義の中でその構造体を宣言して下さい。
書いて、あってるか聞くんじゃなくて、自分でコンパイルしてみましょう。

Re:進行方向に画像が向くショット

Posted: 2008年11月28日(金) 18:54
by Dixq (管理人)
Cの基本がわからないと、ゲームを作っていてもしょっちゅう聞かないといけないことが出てくるでしょうし、
スムーズに制作出来ないと思います。
まずはコンソール画面を使ってCの基本をマスターしましょう。
いきなり4つにせず、構造体の構造体を作りたいならまず2層から試してみましょう。
コードを作ってみたらとにかくまずコンパイルしましょう。
エラーが出たらそのエラーメッセージからどうやってバグを推測すれば良いか考えるのもまたスキルの一つです。
検索するなり、バグを解決する力もつけましょう。
コンパイルした回数だけ上達します。
逆に言えば紙のうえ、キーボードの上だけじゃ上手になりません。

とりあえずコンソールで構造体を使ってジャンケンゲームを作るなどしてみてはどうですか?

Re:進行方向に画像が向くショット

Posted: 2008年12月01日(月) 17:22
by 匿名
そうですね、では身の丈に合った物を
struct s {//弾一つの構造体

int f;//弾一つ一つのフラグ
double x,y;//X,Y座標
double a;//角度 
int k;//カウンタ 

};

struct s a[10];
こう書くと、まずsと言う型が作られ、次にs型の構造体aを10個作ったことになる・・はず。

で2層ですが
struct s {//弾一つの構造体 

int f;//弾一つ一つのフラグ 
double x,y;//X,Y座標 
double a;//角度 
int k;//カウンタ 

};

struct t {//何発目か 

int mf;//弾一組のフラグ 

struct s a[10];

}

struct t a[10];
これでs型の構造体aが10個が入ったt型の構造体aを10個作ったことになって
弾を10個単位で100個まで飛ばせるようになる・・はず。
s型とt型は違いますから構造体名が同じでもいいんですかね?
ではコンパイルして確認してきます。
しかしタグをつけても特に変化しませんね。何か間違えたかな?

Re:進行方向に画像が向くショット

Posted: 2008年12月01日(月) 21:33
by Dixq (管理人)
もう少し解り易いタグの名前にしたほうがよくないですか?

「弾」の情報をひと纏りにしたBullet_tという型を作ってみます。

typedef struct{
    int flag;
    double x,y;
} Bullet_t;

「弾」を1000個持った、「弾幕」の情報をひとまとまりにした型を作ってみます。

typedef struct{
    int flag;
    int kind;
    Bullet_t Bullet[1000]; 
} Danmaku_t;

Danmaku_t Danmaku[100];

こうすると、フラグと座標データを持った「弾」を更に1000個、そしてフラグと種類情報をもった「弾幕」
データが100個作られます。

こうすれば

Danmaku[n].Bullet[m].flag

のように参照出来ます。

Re:進行方向に画像が向くショット

Posted: 2008年12月02日(火) 16:30
by 匿名
まあ本番ではタグの名前もちゃんとしたほうがいいですね・・
ところで調べたんですが
typedef struct{
    int flag;
    double x,y;
} Bullet_t;
のBullet_t;はtypedefを使ってBullet_t;型を作ることでstructをつけなくても宣言できるようにしているようですが、typedef struct{の所に構造体名というか型名が無いのはBullet_t;が代わりになってるから必要ないからですか?

あと話が変わりますけど、私は今まで弾の種類ごとに違う配列を使っていましたけど
シューティングゲームの館などを見ると、使っていない構造体を探してパターンを渡すことで
1つの配列ですんでいるようですね。
このようにすれば前に書いたような四重構造体なども必要なさそうですね。
ためしに今の知識で作ってみると
typedef struct {//弾一つの構造体 

int flag;//フラグ 
double x,y;//X,Y座標 
double Angle;//角度 
int Count;//カウンタ 
int Pattern;//パターン 

} Shot_t ;

Shot_t Shot[4][100];
二次元配列になっているのは、どのプレイヤーが撃った弾かぐらいは分けたほうがわかりやすいかな、と思ったからです。
これで弾を撃つ時に[4]の方に自分が何番のプレイヤーかを入れて[100]の方でfor文を使って使われていない構造体を探せばOKですね。
で、描画する時は[4]を0から3まで変化させて[100]を0から99まで変化させればいいという事になる。
パターンで処理を分ける時に[4]に入っている数を引数として渡せば敵味方も付きそうだからOKですね。
一度に何発撃つかは技ごとに違いますから、発射処理は分ける必要がありますね。
角度がしっかりしていればちゃんと一まとまりに飛んでくれると思うし[100]の所で一回区切って
Player.Shot.flagのように二重にしてもいいですね。
しかし配列1つで弾の処理が全部できるとは・・構造体ってすごいですね。

Re:進行方向に画像が向くショット

Posted: 2008年12月02日(火) 18:23
by Dixq (管理人)
typedefは作った構造体の型に新しい名前を付ける効果があります。

#define

と似たようなものですね。解釈は違いますが。

あと、どのような敵から撃ったかわかるように二次元配列にすると仰っていますが、

弾幕情報にどの敵から撃ったか収めたほうがすっきりしませんか?

typedef struct{

    int flag;

    int EnemyID;

    Bullet_t Bullet[1000]; 

} Danmaku_t;

こんな感じで、どの敵が発射している弾幕か記憶する必要があります。

そうでないと、EnemyIDのいる座標から弾を出す事も、

敵が倒された時それ以上弾を登録しなくする事もできなくなってしまいます。

しかしこのように構造体の中にいれることでこれらが可能になり、同時に二次元配列にする必要がなくなります。

二次元や三次元配列にするより、必要なデータはメンバに入れてやったほうが解り易いと思います。

しかしプレイヤーの弾情報と敵の弾情報を一緒にするのは適切かどうかわかりません。

必要な変数も違うでしょうし、当たり判定の計算や行いたい処理・効果も違うと思います。
 

Re:進行方向に画像が向くショット

Posted: 2008年12月03日(水) 19:24
by 匿名
確かにそうですね。
イメージで言うと四人対戦の格ゲーですから、敵もプレイヤーの場合がほとんどだと思いますけど、大量のザコ敵と戦う場合などを考えるとプレイヤーの数しか配列がないと大変な事になりますからね。

ところで
>計算はdoubleでやって、描画はintでやればいいのです。
とはどういう事でしょうか?

あと東方緋想天とかだと、相手の弾と自分の弾が相殺したりしてますけど、それっていちいち全部の敵弾との距離を測るしか方法が無いですかね?

Re:進行方向に画像が向くショット

Posted: 2008年12月03日(水) 20:16
by Dixq (管理人)
上にも同じことかきましたが、

DrawGraph関数に渡す座標は確かにint型ですが、計算はdoubleでやって、描画はintでやればいいのです。

DrawGraph( (int)~.x, (int)~.y, .... );

のように。キャストして書けばいいのです。
キャストの意味がわからないときはググって下さい。
しかしintでの描画はシューティングでは使わない方がいいです。
小数点を表現できる描画関数

DrawGraphF( (float)~.x, (float)~.y, .... );

が存在するのでそちらをお使い下さい。

相手の弾と自分の弾がある一定の距離にある時消すような処理をする為には、一般的には一つ一つ距離をはかるしか無いと思います。
自分より相対的に正の方向にある弾、負の方向にある為、などで条件わけしてデータを保存しておくなど、
効率化する方法はいくつかあるかもしれませんが、
全部判定してしまった方が管理がらくだと思います。

Re:進行方向に画像が向くショット

Posted: 2008年12月04日(木) 18:07
by 匿名
ググって見ましたが、(float)とかを変数名とかの頭につければ、その時だけfloat型あつかいになるようですね。
そういえばどこかで見たような気がします。
構造体とかだと(float)Shot.x;見たいな感じですかね。

DrawGraphFのようにfをつけると小数点が表現できるようになるようですが、DrawRotaGraphとかDrawStringとかでも可能ですか?

ところで小数点にしても1ドットは1ピクセルで表現すると思うから変化が無いようにも見えますが・・まあフルスクリーンとかなら細かくなるかもしれませんが。

まあシューティングはまだ実力不足という事で今回は格ゲーですからそこまで正確でなくてもいいんですが、小数点も表現できたほうが何かと便利ですね。

Re:進行方向に画像が向くショット

Posted: 2008年12月04日(木) 20:12
by Dixq (管理人)
色は1か0で表現されているわけではありません。
「中間」も表現出来ます。例えば座標1.5なら2ピクセル目の色の濃度を50%にして描画すれば1.5ピクセル目に見えます。

ゲームプログラミングの館のコードを元にサンプルを作りましたので、実行して確認して下さい。
エンターを押しっぱなしにして、左右の列で違いをよく確認するとその意味がわかります。
どちらがスムーズに進んでいるように見えますか?

なお、どんな関数があるかは、ヘッダファイルを見るとわかります。
Ctrl + Fで探すとよいでしょう。
#include "DxLib.h"

struct shot{
    double x,y;
    int flag;
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode( TRUE ) ;     // ウインドウモードに変更
    if( DxLib_Init() == -1 ) return -1; //DXライブラリ初期化 エラーが起きたら終了 

    int image[16],i,counter=0; //counter=発射してからのカウントをする変数。
    char Key[256];
    struct shot tama[10];        //tamaを10個作る。

    for(i=0;i<10;i++){         //初期化処理
        tama.x=640/2; tama.y=480; //座標代入
        tama.flag=0;         //飛んでいない事を示すフラグ=0
    }
    SetDrawMode( DX_DRAWMODE_BILINEAR );
    SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定
 
    LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
                
    while(1){
        ClearDrawScreen();          //裏画面のデータを全て削除
        GetHitKeyStateAll( Key ) ;      // すべてのキーの状態を得る

        if( ProcessMessage() == -1 ) break ; //異常がおきたら終了

        if(counter<10)            //前にエンターを押してから5カウント未満なら
            counter++;            //カウントアップ

        else if( Key[ KEY_INPUT_RETURN ] == 1 ){//5カウント以上たっていたら
            counter=0;            //カウンターを戻す
            for(i=0;i<10;i++){       
                if(tama.flag==0){   //発射していない玉を探し、
                    tama.flag=1; //発射フラグを立てる
                    break;
                }
            }
        }
        for(i=0;i<10;i++){
            if(tama.flag==1){       //発射している玉なら
                tama.y-=3;       //座標を8減らす
                tama.x-=0.1;       //座標を8減らす
                DrawRotaGraph ( (int) (tama.x+100) , (int) (tama.y) ,4.0,0.0,image[1],TRUE );
                DrawRotaGraphF( (float)(tama[i].x-100) , (float)(tama[i].y) ,4.0,0.0,image[1],TRUE );
                if(tama[i].y < -32){   //もし画面外まで来たら
                    tama[i].y=480;  //初期値に戻し、
                    tama[i].flag=0;  //発射フラグを戻す
                }
            }
        }
        
        if( Key[ KEY_INPUT_ESCAPE ] == 1 ) break;//Escボタンが押されたらブレイク

        ScreenFlip() ;//裏画面データを表画面へ反映
    }
    DxLib_End() ;// DXライブラリ使用の終了処理
    return 0 ;// ソフトの終了
}
 

Re:進行方向に画像が向くショット

Posted: 2008年12月05日(金) 19:53
by 匿名
ああ、なるほどグラデーションですか。確かにグラデーションを付けてくれれば滑らかに動いているように見えますね。早速試してみます。

ところで
else if( Key[ KEY_INPUT_RETURN ] == 1 ){//5カウント以上たっていたら
            counter=0;            //カウンターを戻す
            for(i=0;i<10;i++){       
                if(tama.flag==0){   //発射していない玉を探し、
                    tama.flag=1; //発射フラグを立てる
                    break;
                }
            }
        }

のbreak;は、何をブレイクしているのでしょうか?
for文でしょうかね?以前学校の先輩にfor文はbreak;で抜けることができないと言われたのですが・・

あと、龍神録プログラミングの館に「敵の消滅エフェクトを作ってみよう」と言う項目がありますが、自機のショットに命中した時のエフェクトをつけたい場合はどうすればいいでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年12月05日(金) 20:30
by Dixq (管理人)
プログラムは演習でみにつきます。
疑問があるときはかたっぱしからコンパイルしてみてください。
今回あえて答えませんので、自分で確かめてみてください。
自分では解決できないことなら仕方ないですが、
今回for文からbreakで抜けられるかどうかは自分で試すか調べるかすれば解決できますよね。

いじわるしているわけではないです。「自力で解決すること」「調べること」もプログラミングスキルの一つですので、まずは自分で解決を試みてみてください。

>のbreak;は、何をブレイクしているのでしょうか?

あいている格納庫を見つけて登録しているわけですが、breakしなかったらどうなるでしょうか?

また、敵の消滅エフェクトの方法がわかれば自機にも応用できると思います。
とりあえずどの辺までわかって、どの辺の応用の仕方がわかりませんか?

Re:進行方向に画像が向くショット

Posted: 2008年12月06日(土) 17:09
by 匿名
まあ、確かに自分でも調べられるんなら自分で調べたほうがいいですね。

で、エフェクトですが。注釈を集中して見ればだいたいの流れは分かるんですが、弾の消滅エフェクトの場合はどんな方法が効率がいいのか、と言う事で悩んでいます。
私に思いつく方法といえば、龍神録のようにエフェクトを登録してから一括して処理を行う方法と、弾自体にエフェクトを組み込む方法です。
弾自体にエフェクトを組み込むと言うのは、弾のフラグとカウンタを使いまわす方法です。新たに変数を作ってもいいんですが、それはまあ後回しにして。
弾が敵に当たったらフラグを1から2にしてカウンタを0に戻します。フラグが2になっていたら弾の変わりにエフェクトを描画して、そのまま一定時間が経ったらフラグを0にする。と言うような物です。
弾とエフェクトでどっちが手前に来るかは統一したほうが綺麗なのでこの方法は使いたく無いんですが、一度頭に浮かんでしまうと、頭から離れなくなってしまうんですよね・・処理がかなり増えてしまうし・・

Re:進行方向に画像が向くショット

Posted: 2008年12月06日(土) 17:55
by 匿名
すいません日曜日はパソコンが使えないのでまとめて質問させていただきます。
上の画像の大きな弾がいい例ですが、普通透けてる感じを出すにはaブレンドを使いますけど、あの弾は白い部分ははっきりしていますが、赤い部分は透けてますよね。ああ言う表現はどうすればいいでしょうか?
まさか、赤い部分と白い部分を別々に描画してたり・・してませんよね・・

Re:進行方向に画像が向くショット

Posted: 2008年12月07日(日) 23:42
by Dixq (管理人)
どちらが効率良いかは、実際に両方実装してみて、考えてもいいのではないでしょうか。
明らかに非効率ではない限り、最初のうちはとにかく「トライアンドエラー」です。
試行錯誤することは非常に勉強になります。
2つ思いつく方法があるなら2つともやってみる。わからないことがあるなら調べまくる。わかりにくい使い方がある時は可能な限り自分で沢山実装してみる。
そうしているうちに自分のものになっていくと思います。

未熟ですから今でもそうですが、私も昔から非効率なプログラムはずっと書いてきました。
非効率なプログラムを書いているうちに、「あ、こうすれば効率的だな」とわかってきます。
そのたびに効率的にしていきます。
自分が思いついた方法は、人に聞いた方法の100倍身に付きます。
また、人から聞いた方法は応用が困難ですが、自分で思いついた方法はいくらでも応用できます。

もし館を参考に作っていただけるなら「登録」>「計算」>「描画」の3本柱で作っているプログラムですから、
まずエフェクトを登録する入れ物を作り、登録出来る格納庫を探して登録し、登録されているものを計算し、描画する、というシステムを作るのがいいのではないでしょうか。
敵の消滅エフェクトを登録・計算・描画するシステムがあるのですから、それと同じように作ればよさそうですね。

>一度頭に浮かんでしまうと、頭から離れなくなってしまうんですよね・・

このようなことが大事だと思います。私が勧める方法より、まず自分がやりたい実装方法を実装することの方が大事です。
自分で実装したみたあとで、人から聞いた方法を実装して、どう違うのか、どっちが効率的なのか比べれば大変勉強になると思います。


弾のアルファブレンドの件ですが、これは予め画像自体にアルファ値を設定しているのです。
私の用意した画像にもアルファ値が設定してあります。
PNG画像はRPGの色情報の他に透過が設定できます。
つまり「赤」「青」「緑」「透明」の4色で表現しているとでもいいますか、
「どれくらい透明か」という情報が設定できます。
ペイントでは無理ですが、少し高機能な画像編集ソフトなら透過色のあるPNGが編集できます。
PictBearやGIMPをインストールして開いてみて下さい。
img/bulletフォルダにある特にレーザーの画像なんかは解り易いと思います。
その画像を使うとどうなるか、レーザーを実装する章のプログラムを実行してみるとわかります。

Re:進行方向に画像が向くショット

Posted: 2008年12月08日(月) 15:54
by 匿名
よくわかりました、間違えたっていいんですよね。

館のソースはなかなか役に立ちそうですが、確かに自分で作らないと頭に入らないんですよね、なのでアルゴリズムを参考にさせてもらって自分で新しく作ってみます。

予めアルファ値を設定するんですか、なるほどなるほど、ではどのくらい透過するか決まっているものは予めアルファ値を設定しておけば、いちいちブレンドしなくてもいいんですね。
でも、そうじゃなかったら、やっぱりいちいちブレンドしなくてはいけないのでしょうか?ブレンドする時としない時がある場合は何か効率のいい方法はありませんか?

ところで前に見せていただいたサンプルですが、私の目が衰えているのでしょうか?どちらが滑らかか判別が付きませんでしたが、まあ使い方はよく分かりました。

あと緋想天の霊夢の亜空穴などがいい例ですが、キャラが縦に引き伸ばされる場合などは・・DrawModiGraph関数ですかね、でも普段はだいたいDrawRotaGraphですよね、使い分けるには・・もう1つフラグを増やすとか?もしくは本体は画面外に飛ばして弾として描画するとか、さてどうすればいいかな・・
そういえば永夜抄の現世斬みたいに本体を強制的に移動させる技なんかはどうすればいいでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年12月08日(月) 21:55
by Dixq (管理人)
>予めアルファ値を設定しておけば、いちいちブレンドしなくてもいいんですね。
>でも、そうじゃなかったら、やっぱりいちいちブレンドしなくてはいけないのでしょうか?

そうですね。アルファ値を設定していない画像を透過させるためにはプログラムで透過させてやらないといけません。
ブレンドする時としない時というのはどういうときでしょう?
例えば弾を透過させたいなら、弾情報に「透過」なる変数をもたせておき、
0~255の値をセットしてやればいいのではないでしょうか。
この値は通常255になっていて、255以外の値がセットされた時は、描画部でアルファブレンドするようにすればいいと思います。
また、ブレンド形式を指定させるためには「BlendKind」とでも名づけたブレンドの種類を指定する変数を持たせてもいいかもしれません。

サンプルの方は、右側はよく見たらギザギザの軌跡を描いているようになっていると思います。
左側は少しぼやけたような描画になっているとは思いますが、スムーズに進んでいるようになっていると思います。

後、描画する関数を任意に変えたいと言う事ですが、これも先ほどと同じようにそれを表現する構造体に
描画関数を制御する変数を用意したらいいと思います。
それが面倒なら大きさなどを設定する変数を用意し、全部Modiで描画したらいいのではないでしょうか。

Re:進行方向に画像が向くショット

Posted: 2008年12月09日(火) 16:41
by 匿名
えーと、ブレンドしない時と言うよりは描画するたびに ブレンド→描画→ブレンド解除 の三度手間なんとかならないかなーって事です。確かに透過用の変数を用意すれば透過しないものもセットしないといけなくなりますが、描画した後ブレンドをいちいち解除する必要がないのでいいかもしれませんね。

ところで・・弾の描画ってどこでやるんですかね?弾にパターンを渡して処理を分けますから、パターンの中にそれぞれ描画する所があるんでしょうかね?それとも描画するのは同じなんだからパターンの外で描画してるんでしょうかね?

そもそも弾の種類や数が途中で変化する場合、パターンの中にパターンを作ればいいんですかね?
極端な例が永夜抄のフジヤマヴォルケイノですが、ああ言うのはパターンの中で弾を登録しているんでしょうか?

Re:進行方向に画像が向くショット

Posted: 2008年12月09日(火) 17:23
by Dixq (管理人)
>ブレンド→描画→ブレンド解除 の三度手間なんとかならないかなーって事です。

ブレンドするときは、ブレンドモードにして、必要なくなったらもとに戻す処理が必要です。

>確かに透過用の変数を用意すれば透過しないものもセットしないといけなくなりますが、描画した後ブレンドをいちいち解除する必要がないのでいいかもしれませんね。

そうではなく、必要な時だけブレンドモードにすればいいです。
上で

>>0~255の値をセットしてやればいいのではないでしょうか。
>>この値は通常255になっていて、255以外の値がセットされた時は、
>>描画部でアルファブレンドするようにすればいいと思います。

と言った様に、255がセットされている時はブレンドの必要がないのですから、ブレンドモードをセットする必要はありません。
もし加算ブレンドなどをセットする場合は必要ですが。

>ところで・・弾の描画ってどこでやるんですかね

サンプルはご覧になっていますか?
もしプロジェクトをダウンロードされているならその中をご覧下さい。
描画関係はgraph.cppで行っています。

Re:進行方向に画像が向くショット

Posted: 2008年12月10日(水) 17:41
by 匿名
ブレンドする場合は描画する前に
SetDrawBlendMode( DX_BLENDMODE_ALPHA , 128 ) ;
とでもして
ブレンドしない場合は描画の前に
SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
とでも書いておけばいちいちブレンド解除しなくてもブレンドのONとOFFができるということですか?

サンプルを見ましたが弾を動かす所と描画する所がどうつながっているのかがよく分かりませんでした。

ところで今一番分からない部分なんですが
描画する物の前後関係です。今作ろうとしているゲームは上視点なのですが、キャラの描画を1P→2P→3P→4Pの順番でやっているので、2Pが1Pの少し上に来たりすると2Pの足が1Pの顔にかかったりして目も当てられない状況に・・こういう時は・・マスク画面かな?

Re:進行方向に画像が向くショット

Posted: 2008年12月12日(金) 18:18
by 匿名
ところで、龍神録の画像を見てみましたが初期方向が上ですね。では描画する時に+π/2しているのですか?

Re:進行方向に画像が向くショット

Posted: 2008年12月12日(金) 18:28
by Dixq (管理人)
>とでも書いておけばいちいちブレンド解除しなくてもブレンドのONとOFFができるということですか?

いや、ブレンドしおわった時には常にノーブレンドにしておけば、必要ない時はブレンドモードをセットしなければいいだけですよね、ということです。
必要な時だけブレンドモードをセットしてやればいいです。

>キャラの描画を1P→2P→3P→4Pの順番でやっているので、2Pが1Pの少し上に来たりすると2Pの足が1Pの顔にかかったりして目も当てられない状況に

格ゲー作ってるんですよね?格ゲーで上視点ってどんな感じかイメージがわかないのですが、
奥にあるものを常に奥に表示したいのなら「奥行き」なる変数を用意し、その奥行きの順番で描画してやればいいと思います。
常に4P分の奥行きデータをソートし、その順番で描画してはどうでしょう。

>龍神録の画像を見てみましたが初期方向が上ですね。では描画する時に+π/2しているのですか?

弾の画像のことですか?graph.cppの弾を描画を見ていただいたら解ると思いますが、π/2ほど方向を変えて描画しています。

Re:進行方向に画像が向くショット

Posted: 2008年12月13日(土) 15:09
by 匿名
イメージで言うと↑こんな感じです。右上のような状況にならないようにするにはどうするべきか?
キャラのグラフィックは後で差し替える必要がありますね。
まあ、こんな感じの視点ですからY座標がそのまま奥行きになりそうですけど。
とりあえずキャラの描画だけなら画面の上にいるキャラから描画していけば問題はないんですが、これに弾が入ってくると話がややこしくなるんですよね・・小さい弾なら問題はないんですけど、例えば画面を横にレーザーが横切っている時に(画面の下の方)頭だけ切れたりするとすごく不自然になるんですよね・・

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 03:08
by Justy

>右上のような状況にならないようにするにはどうするべきか?

 どうなれば正解なのか今ひとつ判っていないのですが、
管理人さんが書かれているとおり、奥行きの順番でソートして描画すればいいと思います。

 それがレーザーであっても同じで、キャラとレーザーの位置をみてどっちが奥にあるかで
描画順を変えれば済みます。

 このタイプのゲームであれば、確実に順番が固定されるもの、背景やメニュー、ゲージなどを
除いたマップの上に載っているものは全てソートして描画した方がいいかもしれません。



>描画する時に+π/2しているのですか

[color=sans-serif]~.x += cos( ~.Angle ) * ~.Speed;
~.y += sin( ~.Angle ) * ~.Speed;

[/color]
なところを

[color=sans-serif]~.x += sin( ~.Angle ) * ~.Speed;
~.y -= cos( ~.Angle ) * ~.Speed;
[/color]

とすれば、描画時の +π/2は要らなくなるような・・・。



>もちろん角度や座標のデータはfloatやdoubleにすべきです。doubleでいいと思います

 floatでも doubleでもどちらでもいいのですが、現状 DXライブラリでゲームを作るので有れば、
DrawGraphF()などの引数が floatであることや、計算精度が制限されていることを考えると、
doubleを使う意味があまりないので floatで十分かな、と思います。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 03:45
by Dixq (管理人)
右上がどういう状態になっているのかよくわからないですね;
まぁ仰るようにy座標順に描画してやればオッケーです。

>~.x += sin( ~.Angle ) * ~.Speed;
>~.y -= cos( ~.Angle ) * ~.Speed;
>とすれば、描画時の +π/2は要らなくなるような・・・。

あれ、こうすると移動方向自体が上下逆になりませんっけ?
試してないので違うかもしれませんが・・。

>double型ではなくfloat型

そうですね。
絵弾幕などの座標データは-1~1で表現しており、原点からの角度や距離もその中で正確に計算する必要が龍神録であること、
そして「スピードデータ*0.9」を100回行い「スピードデータ/0.9」を100回行ってもとのスピードに戻すような処理があったので、
doubleの方がいいのかなと思いましたが、floatでも十分でしたね。
floatだといちいちキャストしないでいいので、多重定義もいりませんし、そちらの方がいいかもしれません。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 04:16
by Justy

>試してないので違うかもしれませんが・・。

 実は私も試してないんですけど、y側の符号を +から -にしているんで
多分大丈夫じゃないかなぁ、と・・・。



>doubleの方がいいのかなと思いましたが、floatでも十分でしたね

 そもそもあれなんですよ。
 DXライブラリを使うと、計算精度が悪くなるんですよね。

 知っている人は知っている話なのですが
[color=#e0f0ff" size="-1" face="monospace]
#define PI 3.141592653589793
volatile double add = 0;
double value1 = PI + add;

ChangeWindowMode(TRUE);
DxLib_Init();

double value2 = PI + add;[/color]

とすると value1と value2の値が微妙に異なるんですよ。

 本来、addは 0なので value1も value2も PIの値になるはずなのですが、
value2は 3.1415927410...と小数点以下6桁目までしか一致しません。

 そうなる理由はDXライブラリ、というか内部で使っている DirectXが
高速化の為に単精度まで精度を下げている為なのですが、こういうこともあるので
doubleを使うなら、精度を元に戻さないとあまり意味はないかな、と思うわけです。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 05:30
by Dixq (管理人)
>実は私も試してないんですけど、y側の符号を +から -にしているんで多分大丈夫じゃないかなぁ、と・・・。

あぁ、sinとcos逆なんですね。なるほど、90度変わるわけですね。
しかし、確かに90度回転するんですが、進む方向自体が変わってしまいませんっけ・・?
移動する方向と画像の方向は一致するんですが、
例えばatan2で敵と自機との角度計算してangleに格納しても自機にむかって飛んでこなくなりません?

>知っている人は知っている話なのですが

えぇ・・そうなんですか・・。
勉強になります。
やってみましたが、特にaddの値が変化しているとか、そういうことではないんですね。
純粋に下6桁までしか信用できないと・・。
そしてvolatileってはじめて見ました^^;
最適化を防ぐための物なんですね。
今回これが使われているのは、最適化されてないのに、値がおかしくなるぞということを明示的にされているという事ですか?

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 10:44
by Justy

>例えばatan2で敵と自機との角度計算してangleに格納しても自機にむかって飛んでこなくなりません?

 あー、そっか atan2を使うのですね。
 そうなると、たしかに調整が必要になりますね。

 いつもそういう場合 atan2ではなくて上向きのベクトルと対象のベクトルの内積と外積から
角度を求めていたのですっかり失念していました。



>純粋に下6桁までしか信用できないと・・。

 ただの定値の代入だと問題はないのですが。加算などの演算が入ると DxLib_Init()前なら
普通の double(倍精度)で計算されるので正しく PIになるけど、
後だと float(単精度)しかないので、値が微妙に変化する、というわけです。。



>今回これが使われているのは、最適化されてないのに、値がおかしくなるぞと
>いうことを明示的にされているという事ですか?

 すみません。ちょっと混乱させてしまったかもしれません。
 
 volatileは addが最適化されて、加算という計算そのものが省略されることを防ぐために付けました。
 最適化無しでビルドすれば、volatileなしでも同様の結果になると思います。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 13:18
by Dixq (管理人)
>内積と外積

調べてみると、atan2使うのってあまりメジャーじゃないんですね;
http://www7.plala.or.jp/kfb/program/stg2dvec.html

一般的には使われないんですか?atan2の方が圧倒的に計算スピードが遅そうですね・・。

>あー、そっか atan2を使うのですね。

atan2を使っていなくても、他にも例えば真下は

~.angle = PI/2;

とかにセットしていますが、sin,cos逆、そしてy方向反転だと、左に飛んでしまうのではないでしょうか?
もしかして私は普通やらないような計算を行ってるんでしょうか;

>最適化

あぁ、なるほど。0の足し算は確かに無意味に思われますね。そういうことだったのですか。わかりました。
ありがとうございます。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 15:07
by Justy

>一般的には使われないんですか?

 使われない、ってことはないと思いますけどね。
 少なくとも内積・外積で説明されるより、atan2の方が直感的にわかりやすいので
それはそれでいいと思います。



>例えば真下は~ .angle = PI/2; とかにセットしていますが
>sin,cos逆、そしてy方向反転だと、左に飛んでしまうのではないでしょうか?

 左、ですか。

 多分どこかで齟齬が生じているようですが、この考え方では
(描画時の回転オフセットが不要にする為)画像と同じく真上を 0度の回転と
しています。

 なので、真下であれば 180度、つまり angle=PIに設定することになるので
sin(PI)は 0、-cos(PI)は 1となり [0, 1]で真下を向きます。

 (時計回りで)右方向の PI/2であれば sin(PI/2)は 1、-cos(PI/2)は 0に
なりますので、向きは [1, 0]となり、一応画面的には右方向を指します。


 とこんな感じなのですが、どこかおかしいでしょうか。



>atan2の方が圧倒的に計算スピードが遅そうですね

 どっちが速いか、というのはいくらでも高速化の余地があるので
ちょっとわかりません。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 15:16
by Dixq (管理人)
>少なくとも内積・外積で説明されるより、atan2の方が直感的にわかりやすいので

そうですね、「理論はわからないけど、関数は使える」という事もある意味重要ですよね。
小学生とかも館見ているようですし。
ごく初心者を対象にしている解説ですし、ベクトルの話が出てくると数学苦手な人は敬遠してしまう可能性もありますし、
とりあえず館はこのままにしておこうと思います。

>多分どこかで齟齬が生じているようですが、この考え方では画像と同じく真上を 0度の回転としています。

あぁ、なるほど、そうでしたか。
既存の弾幕計算式はそのままに、90度方向の異なる画像を扱う時には、
弾の軌道計算式の方を変えればいいのではという考え方だと誤解していました。
仰る事理解出来ました。くどくどと申し訳ないですm(_ _;)m

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 16:44
by 匿名
なんだかレベルの高そうな話でよく分かりませんが、とりあえず角度や座標はfloatでもよさそうですね。

>調べてみると、atan2使うのってあまりメジャーじゃないんですね;
チラッと見てみましたが、なんだかatan2を覚える前に私が考えた方法と同じみたいですね。まあatan2の方が式が短そうなのでatan2でいいかな。

弾とキャラの奥行きだけならともかく、大きな弾だと弾と弾の奥行きも入ってくるので大変そうですね。今の段階で一度に5000発近くの弾が飛ぶ可能性もあるんですよね。そこにもうすぐ使い魔とかも入ってくるので、私の実力でそれらをすべて画面の上にある順番に描画するのは無理がある気がしますね。とりあえず弾の奥行きはあきらめて、レーザーがキャラにかかる場合は、そこまで当たり判定を広げてエフェクトを表示したりキャラを吹き飛ばしたりしてごまかすしかなさそうですね。

描画する時のPI/2をするかどうかは難しくてよく分かりませんが、まあ結果は同じだからいいかな。

Re:進行方向に画像が向くショット

Posted: 2008年12月15日(月) 17:54
by Dixq (管理人)
どこを基準にするかの違いです。
私の理論は右を0度としています。Justyさんが仰った方法は上を0度とする方法です。

>弾とキャラの奥行きだけならともかく、大きな弾だと弾と弾の奥行きも入ってくるので大変そうですね。

大きな弾の奥行きって何ですか?
後、y座標だけでソートしてはいけない理由って何ですか?
y座標でソートして表示するサンプル作ってみました。

http://www1.axfc.net/uploader/He/so/170258
DLKey : [1111]

実行結果一部
画像

しばらくみているとわかると思いますが、ソートして弾を表示するとチラチラして見にくいですね。

それから5000個も弾を描画すると処理に時間がかかってしまうと思いますし、弾で埋め尽くされてしまう気がします。
サンプル内の
#define BULLET_MAX 2000
を5000にしてみて下さい。

Re:進行方向に画像が向くショット

Posted: 2008年12月16日(火) 14:51
by 匿名
まあ、奥行きというより画面の上にいる順番ですが、それはもういいでしょう。

5000個と言うのは最大数で実際には100個ぐらいしか飛びません、スペルのひとつに撃った弾が一定間隔で残像を置いて行き、スペル終了と同時に残像がすべて実体化する。と言う効果の物があるのですが、それを4人同時に出すと一度に弾が5000個ぐらい画面に出る可能性があるので弾を5000個用意しているだけです。

Re:進行方向に画像が向くショット

Posted: 2008年12月16日(火) 16:02
by 匿名
あの説明じゃわかりにくいですね。絵が粗いので見にくいと思いますけど上の画像の左側のような状態にならずに右側のような順番で描画してほしいのですよ、プレイヤー4人と弾5000個と使い魔50匹が・・

それはともかく、弾にホーミング機能をつけたいなら毎回atan2を使えばいいことですが、弾がいきなり向きを変えるのは格ゲーだと結構不自然なんですよね、カーブを描いてホーミングさせるにはどうしたらいいでしょうか?

あと原作でどうなっていたかは知りませんが、緋想天のアリスのアーティフルサクリファイスなどを作る時に着弾までの時間を一定にしたいんです。つまり敵が遠くにいれば早く、近くに入れば遅く飛ばしたいんですが・・そういえば山なりの軌道はどうしたらいいんだろう?

Re:進行方向に画像が向くショット

Posted: 2008年12月16日(火) 21:23
by 木霊
>匿名さん

 質問されることは問題無いと思いますが、もはや表題と関係無い内容になっているので
改めて質問トピを立てられた方が良いと思います。
 1トピにつき1つの問題に抑えていた方が後日訪れた人にとって参考にしやすい(検索しやすい)です。


>あの説明じゃわかりにくいですね。絵が粗いので見にくいと思いますけど上の画像の左側のような状態に
>ならずに右側のような順番で描画してほしいのですよ、プレイヤー4人と弾5000個と使い魔50匹が・・

 管理人さんの言う通りY座標を奥行きに見立てて並び替えるのが一番だと思います。
 力業でも出来ないことは無いですが、当然処理速度が犠牲になります。
 DXライブラリのマスク機能も重いので、マスクを使うのなら自力で実装する必要があります。

Re:進行方向に画像が向くショット

Posted: 2008年12月16日(火) 21:29
by レッツ
1から10まで聞かずに少しは自分で考えないとキリがないですよ。
それに自分なりに考えてみないと身に付きませんよ。

あと、何度言ってもピンと来ない様子に見かねて折角管理人さんがサンプル作ってくれてるのに
それはもういいですとか言ってる人はじめて見ました。

Re:進行方向に画像が向くショット

Posted: 2008年12月16日(火) 23:33
by Dixq (管理人)
前に書いたことと被りますが、描画の順番について、私が説明した理論でダメな理由は何でしょうか?
y座標順で描画したのではだめなんでしょうか?
もしまたご質問される時はその辺を明確にして下さい。

ホーミングについては物理の力学を学べば計算式が思い浮かぶと思います。
高校の教科書があればそれを見たらいいと思いますし、なければ書店で高校の参考書を買ってくればいいと思います。
加速度a,速度v,時間t,距離xこれらの関係がわかれば計算出来るようになると思います。

次質問される時は新しいトピをたてて下さい。

Re:進行方向に画像が向くショット

Posted: 2008年12月18日(木) 10:26
by 匿名
そういえばいつの間にか表題と関係ない話題になっていましたね、すいません。
一応自分でも考えてはいるのですが混乱させてしまうと思い書くのを控えていました。
いろいろ教えていただいたおかげで作業効率が10倍程に上がりました、どうもありがとうございます。