ダッシュするキャラを綺麗にカーブさせたい!

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
G.G.
記事: 63
登録日時: 10年前
連絡を取る:

ダッシュするキャラを綺麗にカーブさせたい!

#1

投稿記事 by G.G. » 9年前

ダッシュしているときにスティックの向き変えると、その方向にあわせようと角度を加算、引算するところなんですが、(void Player_Move部分)
ダッシュのボタンを押さずにすれば基本的に大丈夫なんですが、ダッシュ時に上手く曲がりません・・・。
しかも、斜め方向にも進みません。どうすればいいでしょうか?

コード:

#include "DxLib.h"
#include "Keyboard.h"
#include "Player.h"
#include "Plusproglam.h"
#include <math.h>

#define FIELD_R_MAX 400

double pai = 3.14159265358979;

static int m_Image;
static int m_y;

// 初期化をする
void Player_Initialize(Player_t *Player){
        m_Image = LoadGraph("画像/キャラクタ01.png");
        m_y = 0;
		Player->x = 320;
		Player->y = 240;
		Player->cnt = 0;
		Player->sp = 3;
		Player->Dflag = 0;
		Player->img = m_Image;
		Player->side = 0;
}
	


void Player_Calc(Player_t *Player,configpad_t configpad,pad_t pad){
	Player->cnt++;
	if(CheckStatePad(configpad.DA,pad)>0){
		Player->Dflag = 1;
	}
	else
		Player->Dflag = 0;
}

void Player_side(Player_t *Player1,Player_t *Player2){
	if(Player1->x<Player2->x){
		Player1->side = 0;
		Player2->side = 1;
	}
	else{
		Player1->side = 1;
		Player2->side = 0;
	}
}

// 動きを計算する
void Player_Move(Player_t *Player,pad_t pad,configpad_t configpad){
	int Inputpad[5];
	int i,sayu_flag=0,joge_flag=0;
	double x,y,mx,my;
	double ang,nang,dushper=1;
	Inputpad[0]=CheckStatePad(configpad.right,pad);Inputpad[1]=CheckStatePad(configpad.up,pad);
	Inputpad[2]=CheckStatePad(configpad.left,pad);Inputpad[3]=CheckStatePad(configpad.down,pad);
	Inputpad[4]=CheckStatePad(configpad.right,pad);
	//-----------------------------------------
	

	for(i=0;i<4;i++){
		if(Inputpad[i]>0&&Inputpad[i+1]==0)
			ang=0.5*pai*(double)i;
		if(Inputpad[i]>0&&Inputpad[i+1]>0)
			ang=0.5*pai*((double)i+0.5);
	}


	
	//-----------------------------------------
	if(Player->Dflag==1){
		for(i=0;i<4;i++){
			if(Inputpad[i]>0&&Inputpad[i+1]==0)
				nang=0.5*pai*(double)i;
			if(Inputpad[i]>0&&Inputpad[i+1]>0)
				nang=0.5*pai*((double)i+0.5);
			else
				nang=ang;
		}

		if(nang>ang&&pai+ang>nang)
			ang++;
		if(nang>ang&&pai+ang<nang)
			ang--;
		if(nang<ang&&ang-pai<nang)
			ang--;
		if(nang<ang&&ang-pai<nang)
			ang++;
		if(ang>=pai*2)
			ang=0.0;
		if(ang<=0.0)
			ang=pai*2-0.1;
		if(ang==nang)
			ang+=0.0;
		if(nang==ang+pai*2){
			if(Player->side==0)
				ang--;
			if(Player->side==1)
				ang++;
		}
		dushper = 3;
	}
	//----------------------------------------------

	for(i=0;i<4;i++){
		if(Inputpad[i]>0){
			x=Player->x,y=Player->y;
			mx=Player->sp*dushper*cos(ang);
			my=Player->sp*dushper*sin(ang);

			x+=mx,y+=my;
			Player->x=x,Player->y=y;
		}
	}

	DrawFormatString(0,0,GetColor(255,255,255),"ang=%d",ang);

}

// 描画する
void Player_Graph(Player_t Player){
		DrawRotaGraph3D2((float)Player.x,(float)Player.y,1.0f,0.0f,Player.img,TRUE);
}

// 終了処理をする
void Player_Finalize(){
        DeleteGraph( m_Image );
}
一応コードを載せておきます。
添付ファイル
コピー (2) ~ コピー ~ GameProg.zip
(40.3 MiB) ダウンロード数: 17 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 10年前
住所: 東海地方
連絡を取る:

Re: ダッシュするキャラを綺麗にカーブさせたい!

#2

投稿記事 by softya(ソフト屋) » 9年前

申し訳ないけどコメントがないと解析が辛いんで、カーブとダッシュの部分のコメントと意図したアルゴリズムを説明してもらえますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
G.G.
記事: 63
登録日時: 10年前
連絡を取る:

Re: ダッシュするキャラを綺麗にカーブさせたい!

#3

投稿記事 by G.G. » 9年前

相変わらずの遅返信すみません。

自分が考えたやり方は、キーを押した方向に対応した角度をangに入れ、
sin、cosを使って移動速度をx成分、y成分に分けるという方法です。

このとき、右キーが0度になるので、Inputpadの対応は右キーから反時計周りとし、
入力した方向*1/2πをしてやると、ちょうどその方向にangをあわせることができます。
と、ここまではできました。

次に、斜め方向では、Inputpadをn番だけでなく、n+1番も観測させます。
そのためInputpad[4]は[0]と同じく右キーとなっています。
もし、両方とも押されているなら、1/2パイ*(n+0.5)で、
n番と、n+1番を間の、斜め方向に向かせます。

プログラム内にもコメントを追加しました。
お願いします。
添付ファイル
コピー (2) ~ コピー ~ GameProg.zip
(40.26 MiB) ダウンロード数: 12 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 10年前
住所: 東海地方
連絡を取る:

Re: ダッシュするキャラを綺麗にカーブさせたい!

#4

投稿記事 by softya(ソフト屋) » 9年前

とりあえず変な角度には動かないようにしましたが、ダッシュするキャラを綺麗にカーブさせたいならベクトルの合成で元の移動方向ベクトルと新たな角度のベクトルを合成したほうが思うような動きになると思います。

コード:

// 動きを計算する
void Player_Move(Player_t *Player,pad_t pad,configpad_t configpad){
	int Inputpad[5];
	int i,sayu_flag=0,joge_flag=0;
	double x,y,mx,my;
	double ang,nang,dushper=1;

	//angはプレイヤーの現在向いている方向。nangはプレイヤーが向こうとしている方向。

	Inputpad[0]=CheckStatePad(configpad.right,pad);
	Inputpad[1]=CheckStatePad(configpad.up,pad);
	Inputpad[2]=CheckStatePad(configpad.left,pad);
	Inputpad[3]=CheckStatePad(configpad.down,pad);
	Inputpad[4]=CheckStatePad(configpad.right,pad);//i+1用
	
	//	角度テーブル
	#define INDEX_UP	(0x08)	//1000
	#define INDEX_DOWN	(0x04)	//0100
	#define INDEX_LEFT	(0x02)	//0010
	#define INDEX_RIGHT	(0x01)	//0001
	double KeyAngle[] =
	{
		-1,			//0000	押されていない
		0.0,		//0001	RIGHT
		pai,		//0010	LEFT
		-1,			//0011	うごけない
		pai*1.5,	//0100	DOWN
		pai*1.75,	//0101	DOWN + RIGHT
		pai*1.25,	//0110	DOWN + LEFT
		pai*1.5,	//0111	DOWN
		pai*0.5,	//1000	UP
		pai*0.25,	//1001	UP + RIGHT
		pai*0.75,	//1010	UP + LEFT
		pai*0.5,	//1011	UP
		-1,			//1100	うごけない
		0.0,		//1101	RIGHT
		pai,		//1110	LEFT
		-1,			//1111	うごけない
	};
	//	アングルを求めるためにテーブル参照index化
	
	int index = 	(Inputpad[1]>0 ? INDEX_UP : 0 )
				+	(Inputpad[3]>0 ? INDEX_DOWN : 0 )
				+	(Inputpad[2]>0 ? INDEX_LEFT : 0 )
				+	(Inputpad[0]>0 ? INDEX_RIGHT : 0 );
	
	
	/*
	ボタン配置説明
	Inputpad[i]
			1

		2		0(4)
			
			3

	*/
	//-----------------------------------------
	
	//通常移動用の角度算出。ダッシュ前のアングルも求めます。
	if(Player->Dflag==0){
		if( 0 <= KeyAngle[index] ) {
			ang = KeyAngle[index];
		}
	}
	
	//-----------------------------------------
	//ダッシュをしているときのアングル計算。
	if(Player->Dflag==1){
		if( 0 <= KeyAngle[index] ) {
			nang = KeyAngle[index];
		} else {
			nang=ang;//もし何も方向キーをおしていないなら、今向いている方向に向かいます。
		}

		//ここからは今の方向と向かおうとしている方向から
		//時計回りが早いのか、反時計が早いのか計算し、
		//今向いている方向を、向かおうとしている方向に近づけさせます。
		if(nang>ang){
			if(pai+ang>nang)
				ang++;
			if(pai+ang<nang)
				ang--;
		}
		if(nang<ang){
			if(ang-pai<nang)
				ang--;
			if(ang-pai<nang)
				ang++;
		}
		
		if(ang>=pai*2)//360度より大きくなってしまったら
			ang=0.0;
		if(ang<=0.0)//0度より小さくなってしまったら
			ang=pai*2-0.1;
		if(ang==nang)//向かおうとしている方向にむいたら
			ang+=0.0;//アングル計算ストップ
		if(nang==ang+pai*2){//180度の方向転換をするとき
			if(Player->side==0)
				ang--;//敵の左がわだったら
			if(Player->side==1)
				ang++;//敵の右側だったら
		}
		dushper = 3;//ダッシュ倍速を3倍に
	}
	//----------------------------------------------


	if( 0 <= KeyAngle[index] ) {
		x=Player->x,y=Player->y;//一旦x,yに代入
		mx=Player->sp*dushper*cos(ang);//x方向の移動距離計算
		my=Player->sp*dushper*sin(ang);//y方向の移動距離計算
		x+=mx,y+=my;//x,yに加算
		//本来ここにステージの接触を観測させます。
		Player->x=x,Player->y=y;//代入
	}

	DrawFormatString(0,0,GetColor(255,255,255),"ang=%f",ang);
	//角度の表示をする、テスト用
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
G.G.
記事: 63
登録日時: 10年前
連絡を取る:

Re: ダッシュするキャラを綺麗にカーブさせたい!

#5

投稿記事 by G.G. » 9年前

なるほど、ベクトル合成をすればいいんですね。
ヒントになりました!ありがとうございます!

閉鎖

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