ベラボーマンのパンチを知っていますか?

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

ベラボーマンのパンチを知っていますか?

#1

投稿記事 by 土門 » 10年前

お久しぶりです。
自分は数学が出来ないせいもあり、
現在、完成させられないメソッドがあります。
どなたかお知恵をお貸し下さい。

説明図です
http://dl6.getuploader.com/g/zipcodezip ... /punch.jpg

紫のプレイヤーから青の弾がまっすぐに飛び出すのですが、
その青い弾はやがてプレイヤーの位置に戻って来ます。
簡単に言えば、漫画ワンピースのゴムゴムのパンチ?と思って下さい。

ですがプレイヤーと青い弾との間になにも無いのでは寂しいので、
蛇腹?バネ?状に見える様(ベラボーマンのパンチ?みたいな)に
等間隔に関節画像(説明図でいう赤い図形)を表示させたいのです(表示させるだけ)。
ここでさらにややこしくするのは
青い弾は放たれてしばらくはまっすぐ前に飛んでいますが、
やがて今度プレイヤーの位置に戻って来るわけですが
プレイヤーは常に動き続けているので、プレイヤーを自由に追いかけて
戻って来るんです。
もちろん、帰りがどんなルートであろうが、
その青い弾の場所からプレイヤーまでの直線上に等間隔で描画、です。

現在、青い弾がプレイヤーの座標を確認しながら
プレイヤーの位置に戻ってくるのは、誘導弾の応用で実装出来ましたが
その赤い図形の部分を表示させるところで詰まっています。
説明図で言うところの、
黄色い線上の「緑の点」の箇所の座標を常に算出させてるつもりが
赤い図形はあっちこっちと移動してしまうので、緑の点の座標が取れていない様です。

自分の考え方としては、プレイヤーと弾、
それぞれのX座標とY座標から現在の中間距離の長さを出し、
その距離を、必要な関節数で割って、各位置を割り出す、といった感じです。
計算式に自信がありませんし、なによりこの方法で求めることは可能なのかも
わかりません。
赤い関節部分は、当たり判定もなにも無く
ただ、画像を表示させるだけのつもりですが、いい方法ないでしょうか?

以下ソースですが、読みやすくなる様、無関係な箇所は削除したつもりですが
本来は様々な弾の種類を作っていまして
今回使っていない変数や処理が残っているかもしれませんがご了承下さい。

コード:

青い弾は発射後、40フレームの間は前方にまっすぐ飛んで行き、
40フレーム後、プレイヤーのもとに戻る動きになる。

#define BANE_NUM 3//必要な赤い関節の数

struct BANE{//赤い関節の構造体
	double posx, posy;
	double speedy, speedx;
};

struct PLAYER{//プレイヤー
	double posx,posy;
	double speedx,speedy;
}player;

struct SHOT{//青い弾
	double posx,posy;
	double speedx,speedy;
	int state;
	int angle;
	bool upover,downover,rightover,leftover;
	int count;
	BANE bane[BANE_NUM];
}shot;

vector<SHOT> shotvector;//プレイヤーの弾

void Initialize(){
	player.posx=100;
	player.posy=100;
	shot.state=1;
	shot.upover=shot.downover=shot.rightover=shot.leftover=false
}


void PlayerShot(){
		shot.posx=player.posx;
		shot.posy=player.posy;
		shot.speedx=3;
		shot.count=0;
		shot.state=1; //1=行きの処理 2=帰りの処理
		for (int i = 0; i < BANE_NUM; i++){
			shot.bane[i].posx = shot.posx;
			shot.bane[i].posy = shot.posy;
		}
		shotvector.push_back(shot);
}

void Update(){
  if(ショットボタンを押した){
		OptionShot();//青い弾を発射
	}

  switch((*shotit).state){
   case 1://飛び出した状態の青い弾の処理
    (*shotit).speedx=3;
    (*shotit).posx += (*shotit).speedx;
    (*shotit).speedy = 0;
    (*shotit).posx += (*shotit).speedx;
    (*shotit).count++;
    for (int i = 0; i < BANE_NUM; i++){
	   //距離を計り、関節部分の座標を算出
     double n = (sqrt(((*shotit).posx - player.posx)*((*shotit).pox) - player.posx) + ((*shotit).posy - player.posy)*((*shotit).posy - player.posy))/(i+1);
     shot.bane[i].posx = player.posx + (-n) *cos(atan2(-(player.posy - (*shotit).posy), player.posx - (*shotit).posx));
     shot.bane[i].posy = player.posy + (-n) * -sin(atan2(-(player.posy - (*shotit).posy), player.posx - (*shotit).posx));
     DrawBox(shot.bane[i].posx, shot.bane[i].posy, shot.bane[i].posx + 10, shot.bane[i].posy + 10, 0x0000ff, true);//赤い関節表示
     }
     if((*shotit).count>40){//40フレーム後に青い弾が戻る
       (*shotit).state=2;//プレイヤーに戻る処理に変える
       (*shotit).count=0;
     }
		break;
   case 2://プレイヤーまで戻る弾の処理
		(*shotit).speedx=3*cos(atan2(-(player.posy-(*shotit).posy),player.posx-(*shotit).posx));
		(*shotit).speedy=3*-sin(atan2(-(player.posy-(*shotit).posy),player.posx-(*shotit).posx));
		(*shotit).posx+=(*shotit).speedx;
		(*shotit).posy+=(*shotit).speedy;
		for (int i = 0; i < BANE_NUM; i++){
       //距離を計り、関節部分の座標を算出
       double n = (sqrt(((*shotit).posx - player.posx)*((*shotit).posx) - player.posx) + ((*shotit).posy - player.posy)*((*shotit).posy - player.posy)) / (i+1);
			shot.bane[i].posx = player.posx + (-n) *cos(atan2(-(player.posy - (*shotit).posy), player.posx - (*shotit).posx));
			shot.bane[i].posy = player.posy + (-n) * -sin(atan2(-(player.posy - (*shotit).posy), player.posx - (*shotit).posx));
			DrawBox(shot.bane[i].posx, shot.bane[i].posy, shot.bane[i].posx + 10, shot.bane[i].posy + 10, 0x0000ff, true);//赤い関節表示
		}
		if((*shotit).posx<player.posx+5&&(*shotit).posx>player.posx&&(*shotit).posy<player.posy+5&&(*shotit).posy>player.posy){
      shotvector.clear();
      return;
     }
   	break;
  }
}

void Draw(){
  プレイヤー描画
  青い弾描画
}

●結局なにを聞きたいのか?
緑の点の座標を算出する式を教えて下さい。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ベラボーマンのパンチを知っていますか?

#2

投稿記事 by h2so5 » 10年前

こんな感じだと思います。
あと、ちゃんとアロー演算子を使ってください。

コード:

shot.bane[i].posx = player.posx + (shotit->posx - player.posx) * (1.0 / (BANE_NUM + 1) * (i + 1));
shot.bane[i].posy = player.posy + (shotit->posy - player.posy) * (1.0 / (BANE_NUM + 1) * (i + 1));

土門

Re: ベラボーマンのパンチを知っていますか?

#3

投稿記事 by 土門 » 9年前

完璧でした、どうもありがとうございました!

閉鎖

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