ページ 11

コンピュータが操作するキャラクターが動きません。

Posted: 2011年8月21日(日) 04:54
by LisetteLander
コンピューターのキャラクターの行動パターンでの質問です。
先ほどまでは、しっかり敵の方向を向いて撃っていたのですが
敵が一定の範囲内に迫ってきたら元々の行動パターンで攻撃し、
範囲外にいた場合プレイヤーについてくる、ということをしたくてコードを変えていたら
動かなくなりました。。
しかし、自分の頭の中でルーチンをたどっていくと正常に動かないとおかしいです。
もしよかったら悪い部分を指摘してもらえないでしょうか?

コード:

void com_angle_left(int i){
	player[i].angle -=player[i].angle_rps;
}

コード:

void com_angle_right(int i){
	player[i].angle +=player[i].angle_rps;
}

コード:

void com_move_left(int i,double *l_x){
	*l_x=player[i].angle_slide;
}

コード:

void com_move_right(int i,double *l_x){
	*l_x=-player[i].angle_slide;
}

コード:

void com_angle_change(int i){
	player[i].angle_inertia = player[i].angle;
}

コード:

void com_move_up(int i){
	if(player[i].speed_max > player[i].speed_inertia){//最高速度の設定
			player[i].speed_inertia += player[i].axel;
	}
}

コード:

void com_move_nup(int i){//Wキーを押していないときの処理と同等
			if(player[i].axel < player[i].speed_inertia){//-防止、orで0以上、にするのもアリ
				player[i].speed_inertia -= player[i].axel;//摩擦、加速度減少
			}
			if(player[i].speed_inertia<=player[i].axel){
				player[i].speed_inertia=0;
			}//減速度より慣性速度が低い場合とまる
}

コード:

void com_moveing(double *l_tmpx,double *l_tmpy,int i,double l_x){//移動先をテンプレートに代入。加速度が微塵もついてなかったらもちろん進行先座標に0を代入
	if(player[i].speed_inertia>0){
		*l_tmpx = cos(player[i].angle_inertia + l_x) * (player[i].speed + player[i].speed_inertia);//構造体にすべし。(多人数対策)
		*l_tmpy = sin(player[i].angle_inertia + l_x) * (player[i].speed + player[i].speed_inertia);//と思ったけどtmpに入れてるのがすでに構造体なわけでいいんだった
	}else{
		*l_tmpx=0;
		*l_tmpy=0;
	}
}

コード:

void com_check_move(double *l_tmpx,double *l_tmpy,int i){//先に判定して可能なら移動する。l_p_x,yはcharacterの座標のtmp、そこにmove関数から来る数値を足して可能かどうか判断する。
	if(1<=field_check((int)(player[i].x + *l_tmpx),(int)(player[i].y),0,i)){//x座標、y座標、敵1か味方0か、その番号
		player[i].x+=*l_tmpx;
	}
	if(1<=field_check((int)(player[i].x),(int)(player[i].y + *l_tmpy),0,i)){//x座標、y座標、敵1か味方0か、その番号
		player[i].y+=*l_tmpy;
	}
	if(2==field_check((int)(player[i].x + *l_tmpx),(int)(player[i].y),0,i)){//敵にぶつかってたら
		player[i].life-=0.1;			//ダメージ計算は別にすべき
	}
	if(2==field_check((int)(player[i].x),(int)(player[i].y + *l_tmpy),0,i)){
		player[i].life-=0.1;//ダメージ計算は別にすべき
	}
}

コード:

void com_compact_angles(int i){
		if(player[i].angle>1*PI){
			player[i].angle -= 2*PI;
		}
		if(player[i].angle<-1*PI){
			player[i].angle += 2*PI;
		}
		if(player[i].angle_inertia>1*PI){
			player[i].angle_inertia -= 2*PI;
		}
		if(player[i].angle_inertia<-1*PI){
			player[i].angle_inertia += 2*PI;
		}
}

コード:

double com_range_target(int i,int z){//敵zとの距離を測る。
			double com_range;
			double com_target_x;
			double com_target_y;
			
			com_target_x = player[i].x - enemy[z].x;					//代入するお//準備
			com_target_y = player[i].y - enemy[z].y;					//
			com_range = com_target_x*com_target_x+com_target_y*com_target_y;
			return com_range;
}

コード:

void com_ai_base_main(){
	for(int i=1;i<PLAYER_NUMBER_MAX;i++){//仲間を全員動かすためのループ
		if(player[i].life>0){//仲間が死んでたり居なかったりしたときの分岐
			double l_tmpx=0,l_tmpy=0;
			double enemy_com_angle;
			double player0_com_angle;
			double enemy_com_angle_inertia;
			double l_x = 0;
			int z =player[i].target;					//代入しないと利用できない・・・

			player0_com_angle = atan2(player[0].y-player[i].y,player[0].x-player[i].x)-player[i].angle;//playerへの角度
			enemy_com_angle = atan2(enemy[z].y-player[i].y,enemy[z].x-player[i].x)-player[i].angle;//敵への角度-機体の角度,正面にくれば来るほど絶対値は小さくなる。
			enemy_com_angle_inertia = atan2(enemy[z].y-player[i].y,enemy[z].x-player[i].x)-player[i].angle_inertia;//敵への角度-機体の慣性方向

			switch (player[i].ai_number){
				case 0:

					if(player[i].targeting_flag==1){//誰かをtargetしてたら

						if(sin(-player[i].angle_rps)>sin(enemy_com_angle)){
							com_angle_left(i);									//関数部分
							if(0>cos(enemy_com_angle)){//後方180度内にいる場合(cosの関数は↑1,↓-1,←→0になってる)
								com_move_left(i,&l_x);
							}
						}
						if(sin(player[i].angle_rps)<sin(enemy_com_angle)){			//このangle_rpsは誤差修正//1フレームで曲がれる数より高い角度にいたら
							com_angle_right(i);									//関数部分
							if(0>cos(enemy_com_angle)){
								com_move_right(i, &l_x);
							}
						}

						if(enemy[z].life>0){										//敵の通し番号iをtargetしている時、ライフがあるならば
							if(0.5<cos(enemy_com_angle)){//前方180度内にいるなら
								com_move_up(i);										//関数部分
								com_angle_change(i);
							}else{						//後ろに居る時
								if(100<com_range_target(i,z)){
									com_move_nup(i);
									com_angle_change(i);
								}else{
								com_move_up(i);
								}
							}
						}else{														//ターゲット中の敵のライフが無いならば
							player[i].targeting_flag=0;
						}

						if(sin(player[i].angle_rps)>sin(enemy_com_angle)&&sin(-player[i].angle_rps)<sin(enemy_com_angle)){//正面に敵が居るとき撃つ(sin(θ)でangle_rpsより小さければ撃つ)
							shot_search_shot(i,player[i].gun_knd,0);				//関数部分//第三引数は撃主
						}


					}else{//誰もターゲットしていない時
						for(int t=0;t<ENEMY_NUMBER_MAX;t++){
							if((10000>com_range_target(i,t))&&(enemy[t].life>0)){
								player[i].target=t;
								player[i].targeting_flag=1;
							}
						}
					}







				break;
			default:
				break;
			}//switch終わり	

			com_moveing(&l_tmpx,&l_tmpy,i,l_x);						//関数部分	//壁判定その他諸々のための一時保存
			com_check_move(&l_tmpx,&l_tmpy,i);						//関数部分	//壁判定
			com_compact_angles(i);												//角度最小化
		}
	}
}

Re: コンピュータが操作するキャラクターが動きません。

Posted: 2011年8月21日(日) 11:54
by softya(ソフト屋)
動かないとはどういう状況でしょうか?
もう一つのトピックも書きましたが流れを実際にデバッグ法で確認してみてください。
あとは実際に動くプロジェクトをいただかないとこちらで確認することも難しいです。