レーザーの計算

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
niconico

レーザーの計算

#1

投稿記事 by niconico » 16年前

龍神録のシューティングを改造してるのですが、それでザコ敵が死んでしばらくしてからレーザーを消したいように設定したいのですが、それがうまくいかないのです。
いまのところ、敵が死んでもレーザーの回転の計算はされるのでが、当たり判定などの計算がされていなくて、困っています(shot.cppのlazer_calc関数)
こんなことってあり得るのですか?

これで説明不足のようだったら関数を載せます。ぜひ言ってください!
足りない脳みそを絞っても答えが出そうにないです……
よろしくお願いします!!

BEMANI

Re:レーザーの計算

#2

投稿記事 by BEMANI » 16年前

>>niconicoさん
>それでザコ敵が死んでしばらくしてからレーザーを消したいように設定したいのですが、
>それがうまくいかないのです。
>いまのところ、敵が死んでもレーザーの回転の計算はされるのでが、
>当たり判定などの計算がされていなくて、困っています
情報が「当たり判定などの計算がされていないので困っている」だけですので答えようがありません。
どういう処理・計算をしていて、コンパイラ、ライブラリ・・・等々を少なくとも載せてほしいです。
一番はソースを載せるのがいいと思います。


>ザコ敵が死んでしばらくしてからレーザーを消したいように設定したいのですが、
これは、当たり判定がうまくいってないからレーザーが消えていないと言う事だったのでしょうか?
それとも、単にレーザーを消すだけの処理なのでしょうか?
実行時のイメージが今一つ掴めなかったです。

ぱっと思いついたので下の二つです。
・ザコが死んでから何フレームかカウントし、あるカウントまで来たらレーザーを消す
・レーザーを出してから何フレームか経ったら消す

niconico

Re:レーザーの計算

#3

投稿記事 by niconico » 16年前

あわててすいません
いろいろ抜けてました
やろうとしているのは、敵が死んでしばらくしたらレーザーが収束し、消えるというものです
自分がとった対策は最後に収束することは決まっているので、最後の収束する時間を早めるというものです
コードは全部載せるととんでもない長さになるので重要なところだけのせます
長くなってしまったので二回に分けます

レーザーの計算
void lazer_calc(){
	int i;
for(i=0;i<LAZER_MAX;i++){
			//表示位置を設定
			lazer.disppt[0].x=lazer.startpt.x+cos(lazer.angle+PI/2)*lazer.haba;
			lazer.disppt[0].y=lazer.startpt.y+sin(lazer.angle+PI/2)*lazer.haba;
			lazer.disppt[1].x=lazer.startpt.x+cos(lazer[i].angle-PI/2)*lazer[i].haba;
			lazer[i].disppt[1].y=lazer[i].startpt.y+sin(lazer[i].angle-PI/2)*lazer[i].haba;
			lazer[i].disppt[2].x=lazer[i].startpt.x+cos(lazer[i].angle-PI/2)*lazer[i].haba+cos(lazer[i].angle)*lazer[i].length;
			lazer[i].disppt[2].y=lazer[i].startpt.y+sin(lazer[i].angle-PI/2)*lazer[i].haba+sin(lazer[i].angle)*lazer[i].length;
			lazer[i].disppt[3].x=lazer[i].startpt.x+cos(lazer[i].angle+PI/2)*lazer[i].haba+cos(lazer[i].angle)*lazer[i].length;
			lazer[i].disppt[3].y=lazer[i].startpt.y+sin(lazer[i].angle+PI/2)*lazer[i].haba+sin(lazer[i].angle)*lazer[i].length;
			//あたり範囲を設定
			lazer[i].outpt[0].x=lazer[i].startpt.x+cos(lazer[i].angle+PI/2)*(lazer[i].haba*lazer[i].hantei)+cos(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[0].y=lazer[i].startpt.y+sin(lazer[i].angle+PI/2)*(lazer[i].haba*lazer[i].hantei)+sin(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[1].x=lazer[i].startpt.x+cos(lazer[i].angle-PI/2)*(lazer[i].haba*lazer[i].hantei)+cos(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[1].y=lazer[i].startpt.y+sin(lazer[i].angle-PI/2)*(lazer[i].haba*lazer[i].hantei)+sin(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[2].x=lazer[i].startpt.x+cos(lazer[i].angle-PI/2)*(lazer[i].haba*lazer[i].hantei)+cos(lazer[i].angle)*lazer[i].length*lazer[i].hantei+cos(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[2].y=lazer[i].startpt.y+sin(lazer[i].angle-PI/2)*(lazer[i].haba*lazer[i].hantei)+sin(lazer[i].angle)*lazer[i].length*lazer[i].hantei+sin(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[3].x=lazer[i].startpt.x+cos(lazer[i].angle+PI/2)*(lazer[i].haba*lazer[i].hantei)+cos(lazer[i].angle)*lazer[i].length*lazer[i].hantei+cos(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			lazer[i].outpt[3].y=lazer[i].startpt.y+sin(lazer[i].angle+PI/2)*(lazer[i].haba*lazer[i].hantei)+sin(lazer[i].angle)*lazer[i].length*lazer[i].hantei+sin(lazer[i].angle)*lazer[i].length*((1-lazer[i].hantei)/2);
			
			double ymax=lazer[i].lphy.angle,ty=lazer[i].lphy.time,t=lazer[i].cnt;
			double delt=(2*ymax*t/ty - ymax*t*t/(ty*ty));
			if(lazer[i].lphy.time!=0)//回転移動時間内なら
				lazer[i].angle=lazer[i].lphy.base_ang+delt;//回転する
			if(lazer[i].lphy.conv_flag==1){//座標変換をするか
				conv_pos0(&lazer[i].startpt.x,&lazer[i].startpt.y,
					lazer[i].lphy.conv_x,lazer[i].lphy.conv_y,
					lazer[i].lphy.conv_base_x,lazer[i].lphy.conv_base_y,
					-delt);
			}
			if(lazer[i].cnt>lazer[i].lphy.time){//回転時間を過ぎるとやめる
				lazer[i].lphy.time=0;
				lazer[i].lphy.conv_flag=0;
			}
	lazer[i].cnt++;
	}
}

niconicp

Re:レーザーの計算

#4

投稿記事 by niconicp » 16年前

//敵が死ぬかどうかの決定
void enemy_death_judge(int s){
    int i;
	se_flag[8]=1;//敵に当たった音
    if(enemy.hp<0){//敵のHPが0未満になったら
        enemy.flag=0;//敵を消滅させる
		se_flag[1]=1;//敵のピチュリ音
        enter_del_effect(s);
		for(i=0;i<LAZER_MAX;i++){
			if(lazer.flag==1){//もし、敵が死んでいるが、レーザーが撃っているのならば
			lazer.flag=2;
			}
		}
		enter_enemy_item(s);//敵sのアイテムを出現させる(39章)
        for(i=0;i<SHOT_MAX;i++){//敵総数分
            if(shot.flag!=0){//登録されている弾幕データがあれば
                if(s==shot.num){//その敵が登録した弾幕があれば
                    shot.flag=2;//それ以上弾幕を続けないフラグを立てる
                    break;
                }
            }
        }
}
}



レーザーの動き
//レーザーの計算っていうコメントのところ、あでは無視してもいいと思いますが、一応のせることにします
void shot_bullet_H009(int n){
#define TM008 420
#define DIST 60
    int i,j,k,t=shot[n].cnt%TM008,t2=shot[n].cnt,h=0;
    static int num;
    if(t2==0)num=4;
    if(t==0){
        for(j=0;j<2;j++){
            for(i=0;i<num;i++){
                int plmn=(j ? -1 : 1);
                if((k=search_lazer())!=-1){
                    lazer[k].col      = j;//弾の色
                    lazer[k].knd      = 0;//弾の種類
                    lazer[k].angle    = PI2/num*i+PI2/(num*2)*j+PI2/(num*4)*((num+1)%2);//角度
                    lazer[k].startpt.x= enemy[shot[n].num].x+cos(lazer[k].angle)*DIST;//座標
                    lazer[k].startpt.y= enemy[shot[n].num].y+sin(lazer[k].angle)*DIST;
                    lazer[k].flag     = 1;
                    lazer[k].cnt      = 0;
                    lazer[k].haba     = 2;//幅
                    lazer[k].state    = j;//ステータス
                    lazer[k].length   = 600;//レーザーの長さ
                    lazer[k].hantei      = 0;
                    lazer[k].lphy.conv_flag=1;//回転フラグ
                    lazer[k].lphy.conv_base_x=enemy[shot[n].num].x;//回転基準位置
                    lazer[k].lphy.conv_base_y=enemy[shot[n].num].y;
                    lazer[k].lphy.conv_x=lazer[k].startpt.x;//回転元の位置
                    lazer[k].lphy.conv_y=lazer[k].startpt.y;
                    input_lphy(&lazer[k],80,PI/num*plmn);//代入
                }
            }
        }
        se_flag[33]=1;
    }
    //レーザー計算
    for(i=0;i<LAZER_MAX;i++){
        if(lazer.flag>0){
			if(lazer.flag==2){
			h=100;
			}
            int cnt=lazer.cnt;
			int state=lazer.state;
            if(state==0 || state==1){
                if(cnt==80){
                    lazer.haba=30;//幅を30に
                    lazer[i].hantei=0.7;//表示幅の半分を判定範囲に
                }
				if(cnt>=260-h && cnt<=320-h){
                    if(cnt==280-h)
                    lazer[i].hantei=0;
                    lazer[i].haba=10*(60-(cnt-260+h))/60.0;
                    if(cnt==320-h)
                        lazer[i].flag=0;
                }
            }
        }
    }
    if(t==TM008-1)
        num=(++num);
}


グラフィックについてはレーザーの幅が0以上ならば描写するようにしてあるので、問題ないと思います



よろしくお願いします

BEMANI

Re:レーザーの計算

#5

投稿記事 by BEMANI » 16年前

自分はざっと見るだけなので、的外れなことを言ってたら申し訳ございません。

デバッガを使い、当たり判定に関わる関数・変数の中身をトレスしてみて下さい。
作った本人で見た方が間違いに気づくかなぁ~と思います。


自分が気になったのは以下の二点。
enemy_death_judgeですが、
当たり判定の計算がされていないのではなく、単に関数が呼ばれていないせいで敵が消えず
当たり判定が行われていないように見えている(実際は当たっているが敵が消えていないだけ)
・・・ということはないですか?


また、lazer_calc の中にある 「//あたり範囲を設定」 のレーザの当たり判定設定部分ですが、
設定だけして当たり判定の関数を呼んでいないことはないですか?
検索したところ何処にも書いてなかったので、もしかしたら呼び忘れなのかなぁ~と思いました。

niconico

Re:レーザーの計算

#6

投稿記事 by niconico » 16年前

enemy_death_judgeが引き金になって音を出したり、敵が消えたりするのでそれは間違いないと思います

あと、実はlazer_calcはレーザーの計算するだけで、当たり判定は別のところで呼び出しているので大丈夫です
今、確認しました

あと、さっき気がついたのですが、このプログラムだとlazer.flag=2になるときにすべての敵に対してやっちゃって、最終的にENEMY_MAXの番号の一番最後の敵のレーザー調べてるだけで、別にレーザー出してる敵のことを調べてるわけじゃないんですよね、これ


デバッカですか……
いままで使ったことないのですが、使ってみたいと思います!

BEMANI

Re:レーザーの計算

#7

投稿記事 by BEMANI » 16年前

>enemy_death_judgeが引き金になって音を出したり、敵が消えたりするのでそれは間違いないと思います
親記事には「当たり判定などの計算がされていなくて」と書かれていますが、
敵が消えると言う事は当たり判定の計算は出来てるのではないですか?

何が出来ていて、何が出来ていないか混乱してきました;



>あと、さっき気がついたのですが、
>このプログラムだとlazer.flag=2になるときにすべての敵に対してやっちゃって、
>最終的にENEMY_MAXの番号の一番最後の敵のレーザー調べてるだけで、
ENEMY_MAX が入った処理は、提示されたソースにはなかったので何とも言えません・・・
もし、それが間違いなら発射している敵に対して調べるコードに直して下さい。


>別にレーザー出してる敵のことを調べてるわけじゃないんですよね、これ
レーザーを発射している敵を調べるのでしたら、
敵がレーザーを発射した時にフラグを立て、検索すればいいと思います。

例えば、敵Aがレーザーを発射したと仮定すると、
敵Aが出現していて、かつ敵Aのレーザー発射フラグが立っているなら、
敵Aがレーザーを発射していることになります。
敵Aが死んだ時や、レーザーを打ち終わった後にレーザー発射フラグを初期化する必要があります。


デバッガは非常に重宝しますので是非使ってみて下さい。

niconico

Re:レーザーの計算

#8

投稿記事 by niconico » 16年前

すいません
説明不足でした

レーザーと自機の当たり判定はできているのですが、レーザーの当たり判定の変化(レーザーの縮小)ができてないんですね

BEMANI

Re:レーザーの計算

#9

投稿記事 by BEMANI » 16年前

shot_bullet_H009 関数について気になった所を書いておきます。
なお、この関数についても、中でどうしているのかという細かい解析まではしていません。
見当はずれな回答になっている可能性もありますが予め御了承下さい。


shot_bullet_H009 関数の中で

>int i,j,k,t=shot[n].cnt%TM008,t2=shot[n].cnt,h=0


まず、この変数はローカルで宣言(ブロック内で宣言・定義)されているので、
shot_bullet_H009 を抜けた時点で値はなくなります。
つまり、関数が呼ばれる毎にこの変数が作られ、設定した値で初期化されます。

もし、関数を抜けても値を保持したいのであれば static int i 等、こんな感じで宣言・定義するか、
またはグローバル変数にしてください。
static とは関数を抜けても値を保持してくれます。



そして、次はここの部分です。

if(lazer.flag==2){
	h=100;
}

中略

if(cnt==280-h)
	lazer.hantei=0;
lazer.haba=10*(60-(cnt-260+h))/60.0;

if(cnt==320-h)
	lazer.flag=0;



h の役割が良く解りませんが、
もし、lazer.flag==2 でない時、この h はどういう動きであればいいのでしょうか?

320-h などで計算していますが、今のままだと、初期化した時の 0か、
lazer.flag==2 の条件が成立した時に代入される 100 という値のどちらかです。
これは niconicoさんが望む h の値でしょうか?



最後はこの部分です。

if(cnt==280-h)
	lazer.hantei=0;
lazer.haba=10*(60-(cnt-260+h))/60.0;



lazer.haba=10*(60-(cnt-260+h))/60.0; この代入は、
(cnt == 280-h)の時に行うものではないですか?

つまり、


if(cnt==280-h){
	lazer.hantei=0;
	lazer[i].haba=10*(60-(cnt-260+h))/60.0;
}

ではないかということです。

niconico

Re:レーザーの計算

#10

投稿記事 by niconico » 16年前

すいません
返信遅れました!

グローバル変数ですか
そうですね、試してみる価値はありそうですね
ありがとうございます

hは敵が死んだときに100、生きてるときに0が入ってくれるようにしてほしいですね
最初はcnt+100としていたんですが、うまくいかなかったので、このような形にしました。
敵が死んだときにlazer.flag=2になるので、これでいいと思ってます


幅は徐々にすっとなくすようにしてほしいのでそれでいいです



ホントに遅れてすいませんでした

BEMANI

Re:レーザーの計算

#11

投稿記事 by BEMANI » 16年前

現状、レーザーが消える時はどうなっていますか?
正直うまくいってないと書かれているだけなので、どう消えていくのかが解りません。
(例えば、幅が徐々に狭くならず突然消えるとか、消えることすらしない等)


>ホントに遅れてすいませんでした
最近忙しいので、自分も返信できない可能性があります。
またしばらく見れないかもしれないので・・・



ライブラリはDxLibを使っているのでしょうか?
自分は DxLib 使ってないのでこの関数で実現できるかはなんとも言えませんが、
DxLib のリファレンスページを見に行った所「グラフィックデータ制御関数」と言う部分がありました。
レーザーを縮小したいようなので「DrawExtendGraph」や「DrawModiGraph」辺りを試してみては如何でしょうか?

niconico

Re:レーザーの計算

#12

投稿記事 by niconico » 16年前

グローバル変数を使ったらなんとかできました
しかし!
レーザーが止まりません
ビデオも見てもらったらわかりますが、ひどいです
なんか違うもんだいになってきたので新しくした方がいいんですかね?

BEMANI

Re:レーザーの計算

#13

投稿記事 by BEMANI » 16年前

>>niconicoさん
すいません・・・質問する時は出来る限り情報を詳しく載せて頂けるとありがたいです。

>グローバル変数を使ったらなんとかできました
「レーザーの幅を小さくする」というのが出来たという事ですよね?


>レーザーが止まりません
どう止まらないのですか?
グローバル変数に変えた時点でおかしくなったのなら、その変数の中身やレーザーのメンバをトレスしてみて下さい。
何がグローバル変数か解りませんが、そうしたため全ての弾がその変数を参照し、値を書き変えているという可能性があります。
値を見ていけばどのタイミングでレーザーの挙動がおかしくなるか調べられると思います。


>ビデオも見てもらったらわかりますが、ひどいです
ビデオと言うのは何を指しているのでしょうか?


>なんか違うもんだいになってきたので新しくした方がいいんですかね?
記事名である「レーザーの計算」という範囲から逸れていると判断されるのなら新しい記事がいいと思いますが
レーザーの挙動がおかしいみたいなので、多分新記事でなくてもいいと思います。

niconico

Re:レーザーの計算

#14

投稿記事 by niconico » 16年前

今日問題がレーザーに関しては全て完成しました
ホントお世話になりました
完成したのはほとんどBEMANIさんのおかげです


添付していたつもりなんですが、できていなかったようで申し訳なかったです
完成したのを見てもらいかったのですが、重すぎてのせることができないようです


次の問題はレーザーを出す敵を複数同時にだした場合、一体死んだだけなのに、すべての敵のレーザーが収束してしまうことです
本当にありがとうございました
次の問題にもお付き合いしていただけたらありがたいです

BEMANI

Re:レーザーの計算

#15

投稿記事 by BEMANI » 16年前

>>niconicoさん
お、ついにいけましたか・・・。
自分がソースを提示した訳でもないので、出来るかどうか不安でした;
もし差し支えがないようであれば、「どういう風に直したら成功した」
というのを載せて頂けると嬉しいかもです。
(他の方が同じような問題で検索した時、直し方が書いてあると質問しなくていい場合がありますので・・・)

提案しといてなんですが、グローバル変数でその症状が直ったのなら、
ローカル変数で動かせるように変更しといたほうがいいですよ;
グローバル変数はどこからでも変数の中身を触れるので、
値を参照しあって書き変えられるというバグが発生する可能性があります。
(管理できるから大丈夫!というのであれば特に問題はないです。)



>次の問題はレーザーを出す敵を複数同時にだした場合、
>一体死んだだけなのに、すべての敵のレーザーが収束してしまうことです
これは上のソースを見ていて思いました。
敵が二体以上出ればどうなるのだろうなぁ~と・・・。

恐らく原因は、レーザーの配列を敵全てが共有している所にあると思われます。
for文でレーザーの最大数分ループし、その中でレーザーの幅を変更していますが、
これが二匹・・・三匹になっても for文はレーザーの最大数分ループします。


一つ解決策として、敵の構造体を作り、その中にレーザーの配列を入れればいいです。
ざっくりとソースを提示してみます。

[color=339933]// 敵構造体[/color]
typedef struct _enemy_data
{
	LASER	Laser[LASER_MAX];		[color=339933]// レーザー構造体(LASER型の構造体があると想定しています)[/color]
	bool	LaserFlag;			[color=339933]// レーザー発射フラグ(true:発射中)[/color]
	bool	DeadFlag;			[color=339933]// 生きているか死んでいるか(true:死んでいる)[/color]
	[color=ff0000][ 敵に必要そうな情報を随時追加して下さい ][/color]
}ENEMY_DATA;


ENEMY_DATA Enemy[ENEMY_MAX];	[color=339933]// 敵を作成する[/color]


[color=339933]
// 指定した敵番号のレーザー幅を小さくする関数
// 第一引数	:	敵構造体(参照渡し)[/color]
void LaserShrink(ENEMY_DATA& Enemy)
{
	for(int i=0; i<LASER_MAX; i++)
	{
		Enemy.Laser.haba を小さくする処理
	}
}


[color=339933]// 使う時[/color]
敵がレーザーを発射したら、Enemy[レーザーを発射した敵の番号].LaserFlag = true にし、

[color=339933]// こんな感じで、小さくする関数を呼ぶかどうかを判断します[/color]
for(int i=0; i<ENEMY_MAX; i++)
{
	[color=339933]// 敵がレーザーを発射していて、かつ敵が死んでいる場合幅を小さくする関数を呼ぶ[/color]
	if(Enemy.LaserFlag && Enemy.DeadFlag)
	{
		LaserShrink(Enemy);
	}
}


このサンプルは、敵がレーザー発射後に死んだ場合のみ幅を小さくしていきます。
幅が0以下の時の処理やその他諸々は省いています。
多分これで、少なくとも敵全部のレーザーが消えていくという症状は防げると思います。
(ぱっと思いつきで作ったので何か間違ってるかもしれませんが・・・)

niconico

Re:レーザーの計算

#16

投稿記事 by niconico » 16年前

>提案しといてなんですが、グローバル変数でその症状が直ったのなら、
>ローカル変数で動かせるように変更しといたほうがいいですよ;
>グローバル変数はどこからでも変数の中身を触れるので、
>値を参照しあって書き変えられるというバグが発生する可能性があります。
>(管理できるから大丈夫!というのであれば特に問題はないです。)

グローバル関数にしたというよりも、lazerの構造体にdeath_cntというのを加えました



BEMANIさんのおかげで敵のレーザーを分別することができました
まさかここまでやってくれるとは……
本当にありがとうございます
BEMANIさんがいなければできなかったと思います


では、自分の方法を載せたいと思います

まず、BEMANIさんのいったようにenemyの構造体にlazerの構造体をいれます
ついでにlazerの構造体と同じ構造のlazer2を作ります
これがボスのレーザーになります
で、レーザーに関する関数をコピーして片方をenemy[n].lazer.……、もう片方をlazer2.……という風に作っていきます
ついでにこのとき
graph_lazerの関数if文をlazer.haba>0 ||lazer.flag!=0という風にわけておきます
if(enemy[h].lazer.haba<=0 || enemy[h].lazer.flag==0){
		enemy[h].lazer.flag=0;
		enemy[h].lazer.cnt=0;
		enemy[h].lazer.haba=0;
		enemy[h].lazer.death=0;
		}

もいっしょにつけておきます
もしかしたらいらない子かもしれません

最後に問題のshotH.cppの関数
実はこのとき気づいたのですが、lazerはshotに依存しているということ
つまり、shot[n].flag=0にしたら、lazerが消えるということです
よって、このようになりました
ボスのレーザーのサンプルがザコ敵に実装するとこのようになります
//レーザーのサンプル
void shot_bullet_H009(int n){
#define DIST 60
    int i,j,k,t=shot[n].cnt,cnt_ctrl=0;
	static int num=4;
    if(t==0){
		 for(j=0;j<2;j++){
			    for(i=0;i<4;i++){
				    int plmn=(j ? -1 : 1);
					if((k=search_lazer(n))!=-1){
                    enemy[shot[n].num].lazer[k].col      = 1;//弾の色
                    enemy[shot[n].num].lazer[k].knd      = 0;//弾の種類
                    enemy[shot[n].num].lazer[k].angle    = PI2/num*i+PI2/(num*2)*j+PI2/(num*4)*((num+1)%2);//角度
                    enemy[shot[n].num].lazer[k].startpt.x= enemy[shot[n].num].x+cos(enemy[shot[n].num].lazer[k].angle)*DIST;//座標
                    enemy[shot[n].num].lazer[k].startpt.y= enemy[shot[n].num].y+sin(enemy[shot[n].num].lazer[k].angle)*DIST;
                    enemy[shot[n].num].lazer[k].flag     = 1;
                    enemy[shot[n].num].lazer[k].cnt      = 0;
                    enemy[shot[n].num].lazer[k].haba     = 2;//幅
                    enemy[shot[n].num].lazer[k].state    = 1;//ステータス
                    enemy[shot[n].num].lazer[k].length   = 600;//レーザーの長さ
                    enemy[shot[n].num].lazer[k].hantei      = 0;
                    enemy[shot[n].num].lazer[k].lphy.conv_flag=1;//回転フラグ
                    enemy[shot[n].num].lazer[k].lphy.conv_base_x=enemy[shot[n].num].x;//回転基準位置
                    enemy[shot[n].num].lazer[k].lphy.conv_base_y=enemy[shot[n].num].y;
                    enemy[shot[n].num].lazer[k].lphy.conv_x=enemy[shot[n].num].lazer[k].startpt.x;//回転元の位置
                    enemy[shot[n].num].lazer[k].lphy.conv_y=enemy[shot[n].num].lazer[k].startpt.y;
                    input_lphy(&enemy[shot[n].num].lazer[k],80,PI/num*plmn);//代入
                }

			}
		 }
		  
        se_flag[33]=1;
	}
	if(t<=170 && t>=80){
	cnt_ctrl=180;
	}
	if(t<=260 && t>170){
	cnt_ctrl=80;
	}
	if(t>260){
	cnt_ctrl=0;
	}
    //レーザー計算
    for(i=0;i<LAZER_MAX;i++){
        if(enemy[shot[n].num].lazer[i].flag>0){
            int cnt=enemy[shot[n].num].lazer[i].cnt;
			if(enemy[shot[n].num].lazer[i].flag==2 || enemy[shot[n].num].flag!=1){
			enemy[shot[n].num].lazer[i].death=cnt_ctrl;
			enemy[shot[n].num].lazer[i].flag=2;
			shot[n].flag=1;
			}
			int state=enemy[shot[n].num].lazer[i].state;
            if(state==0 || state==1){
                if(cnt==80){
                    enemy[shot[n].num].lazer[i].haba=30;//幅を30に
                    enemy[shot[n].num].lazer[i].hantei=0.9;//表示幅の半分を判定範囲に
                }
				if(cnt>=260-enemy[shot[n].num].lazer[i].death && cnt<=320-enemy[shot[n].num].lazer[i].death){
					if(cnt==280-enemy[shot[n].num].lazer[i].death){
                    enemy[shot[n].num].lazer[i].hantei=0;
					}
                    enemy[shot[n].num].lazer[i].haba=10*(60-(cnt-260+enemy[shot[n].num].lazer[i].death))/60.0;
				}
					if(enemy[shot[n].num].lazer[i].haba<=0 || t>320){
                    enemy[shot[n].num].lazer[i].flag=0;
					enemy[shot[n].num].lazer[i].haba=0;
					shot[n].flag=0;
				}
		     }
	     }
    }
}


cnt_ctrlが敵のレーザーの収束あいつ消えるか調整しています
関数にしようとしたのですが、よくわからなかったのでちょっと無理やりです
ちなみに、cnt_ctrlのif文のtは収束する時間よりも長くしてください
自分がやったのはこれぐらいですね

yskey

マウス操作実装

#17

投稿記事 by yskey » 16年前

どうもこんにちは。
戦略ゲームを作ろうとしているのですが、快適なプレイにはマウス操作が必須...
なのですが、どのように実装すればよいんでしょうか?

たとえばスタートメニューなどで操作する場合は
マウスの座標が特定の範囲で、クリックされたらスタート
などのようにしていくしかないのでしょうか?
良い方法があればご伝授くださいm(_ _)m

アプリ

Re:マウス操作実装

#18

投稿記事 by アプリ » 16年前

開発しているライブラリはなんでしょうか?
DXならマウスの座標をとってくる命令がありますし
APIでもマウス座標は取れます。

それを画像のあたり判定のようにかけばできませんか?

yskey

Re:マウス操作実装

#19

投稿記事 by yskey » 16年前

DxLibです。
座標習得はわかります。
やっぱり「画像の当たり判定のように」ということは「画像のある座標内でクリックしたらボタンが押された」,,,
というように書くしかないんでしょうか?

初心者さんです

Re:マウス操作実装

#20

投稿記事 by 初心者さんです » 16年前

私も初心者ですので、正しいのかはわかりませんが思い付く方法を2つ書いてみました。

①一定範囲の座標でクリックした場合に動作する
これがyskeyさんが想像されているものだと思ぃます。

クリックした時のマウスの座標が一定範囲内か判定して動作させます。
メニュー画面のスタートなど場所が固定の場合や四角形の範囲の場合判定がし易ぃ方法です。


ですが複雑な形の画像をクリックする場合や、状況によってクリック範囲の変化する画像の場合
上記の方法では対応が難しぃのではなぃかと感じます。


②メモリ上のイメージからクリック座標の色を取りだし、その色で分岐させ動作させる

通常のグラフィックを作ると共に、クリック判定用の「アルファブレンド用のマスク画像のようなグラフィック」を作成する
画面と同じサイズのソフトウェアイメージを作成する
グラフィックを描画すると同時に、ソフトウェアイメージ上にもクリック判定用の画像を重ねて行く
クリックされた座標の色をソフトウェアイメージ上から取りだし、その色によって分岐&動作させる


このような方法でしたら戦略ゲームで一部分重なってしまっているユニットをクリックして動作させるようなことも可能ですし、複雑な形のボタンの場合にも対応出来ます。

DxLibでしたらリファレンスの「ドット単位で画像にアクセスしたい関係」を使うと簡単に実装出来るかもしれません。
ttp://homepage2.nifty.com/natupaji/DxLib/dxfunc.html

説明が下手ですので、これでわからなぃ場合は他の方よろしくお願ぃします…。

閉鎖

“C言語何でも質問掲示板” へ戻る