アニメーションのスピードが速すぎるetc...

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

アニメーションのスピードが速すぎるetc...

#1

投稿記事 by beagle257 » 10年前

初めまして。C言語を基本的な所を勉強し、Dxライブラリを使用して2D横スクロールシューティングゲームを作っています。
今自分が悩んでいることは
1.アニメーションのスピードが速いので自然に描画できるよう改善したい。
2.左クリック長押ししているとアニメーションが止まるので長押し状態でもアニメーションを動かしたい。
3.腕が360°回るので腕の回る上限を決めたい。

1.について
WaitTimer関数を用いて改善しようと思ったのですが、Waitが他の処理にも影響してしまい
描画の挙動がおかしいです。

2.について
今作っているゲームは左クリックで弾を撃ちます。長押しでなければ問題ないのですが長押し状態だと
アニメーションが止まってしまいます。

3.について
今作っているゲームはマウスで狙いを付ける仕様です。その為[身体の画像]と[腕の画像]を組み合わせ、[腕の画像]をマウスカーソルの方向に回転させています。しかし腕が360°回転してしまうので人間の可動範囲に上限を決めたいと思っています。

ソースはこちらです。

コード:

#include "DxLib.h"
#include <math.h>

void Player(void);


//キー取得用配列
char key[256];

//ジャンプしてるかのフラグ。
bool jflag = false;

//プレイヤー用配列
//player[0~6]=左に走るグラフィック [7,8]=左向き停止中グラフィック
//[9~13]=なし [14~20]=右に走るグラフィック [21,22]=右向き停止中グラフィック
//[23~27]=なし [28]=右向きジャンプ中グラフィック [29]=左向きジャンプ中グラフィック [30~34]=なし
int player[35],playerx = 100, playery = 260, playerw, playerh;

//手用配列
//te[0]=左向き用の腕 te[1]=右向き用の腕
int te[2], tex = 100, tey = 240, tew , teh ;

// マウスと中心点との角度格納用変数
float angle=0;

//エイム、弾道用【弾道は使用してないです】
int AIM, Dandou=0;

//弾丸用変数
int Tama, Tamax=0, Tamay=0, Tamaw, Tamah;
//弾丸用計算変数
double sx, sy ,sbx, sby, sb, Tamasx, Tamasy;

//マウス用変数
int mx, my, mxx=0, myy=0;

//ショットフラグ
int ShotFlag = 0;

//身体の向き【0=左向き 1=右向き】
muki = 1;
	
//その他変数
int i = 35, j;


// プレイヤーがジャンプ中か、のフラグ
char JumpFlag = FALSE;
int JumpPower = 0;


// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//Windowモードで起動
	ChangeWindowMode(TRUE);

	// DXライブラリ初期化処理
	if (DxLib_Init() == -1)
	{
		// エラーが起きたら直ちに終了
		return -1;
	}



	/* 画像の読み込みです */

	//歩行グラフィック & 幅と高さを取得
	LoadDivGraph("hokougraph.png", 35, 7, 5, 96, 96, player);
	GetGraphSize( player[0] , &playerw , &playerh ) ;
	
	//手グラフィック
	LoadDivGraph("hand.png", 2, 2, 1, 96, 96, te);

	//エイム(クロスヘア)グラフィック
	AIM = LoadGraph("aim.png");

	  //弾道グラフィック ボツ処理
	  //Dandou = LoadGraph("dandou.png");

	//弾丸グラフィク & 幅と高さを取得
	Tama = LoadGraph("tama.png");
	GetGraphSize( Tama , &Tamaw , &Tamah ) ;

	//マウスカーソルを表示
	SetMouseDispFlag( TRUE ) ;


	/* ここからループ処理の開始です */

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll(key) == 0 || key[KEY_INPUT_ESCAPE] >= 1)
	{
		// 画面を初期化
		ClearDrawScreen();

		// 描画先画面を裏にする
		SetDrawScreen(DX_SCREEN_BACK);

		/* プレイヤー関数へ */
		Player();
	}


	// DXライブラリ使用の終了処理
	DxLib_End();

	// ソフトの終了
	return 0;
}



/* プレイヤー関数 */
void Player(void)
{
	/* ここからプレイヤーのジャンプ処理です */

		//ジャンプキーが押されている かつ 地面に接地している場合
		if (key[KEY_INPUT_UP] >= 1 && playery == 260)
		{
			//ジャンプフラグのON
			JumpFlag = TRUE;
			JumpPower = 12;
		}
		//ジャンプフラグがONの場合
		if (JumpFlag == TRUE)
		{
			if (muki == 1)
			{
				i = 28;
			}
			if (muki == 0)
			{
				i = 29;
			}

			if (key[KEY_INPUT_RIGHT] >= 1)
			{
				muki = 1;
				playerx += 10;
			}
			if (key[KEY_INPUT_LEFT] >= 1)
			{
				muki = 0;
				playerx -= 10;
			}

			playery -= JumpPower;

			// 落下加速度を加える
			JumpPower -= 1;

			// もし地面についていたら止まる
			if (playery > 260)
			{
				playery = 260;
				JumpPower = 0;
				JumpFlag = FALSE;
			}
		}

	/* ここからプレイヤーの移動処理です */

	//移動キーが押された場合
	if (key[KEY_INPUT_RIGHT] >= 1 || key[KEY_INPUT_LEFT] >= 1)
	{
		//右キーが押されている かつ ジャンプしていない 場合
		if (key[KEY_INPUT_RIGHT] >= 1 && JumpFlag == FALSE)
		{
			playerx += 10;
			muki = 1;
			if (i >= 0 && i <= 13 || i >= 20)
			{
				i = 14;
			}

			else if (i >= 14 && i <= 19)
			{
				i++;
			}
		}
		//左キーが押されている かつ ジャンプしていない 場合
		if (key[KEY_INPUT_LEFT] >= 1 && JumpFlag == FALSE)
		{
			playerx -= 10;
			muki = 0;

			if (i >= 6)
			{
				i = 0;
			}
			else if (i >= 0)
			{
				i++;
			}
		}
		WaitTimer(0);
	}

	//何もしていない場合(キーが何も押されていない かつ ジャンプしていない)
	if (CheckHitKeyAll() == 0 && JumpFlag == FALSE)
	{
		if (muki == 0)
		{
			if (i != 7)
			{
				i = 7;
			}
			else if (i != 8)
			{
				i = 8;
			}
		}
		if (muki == 1)
		{
			if (i != 21)
			{
				i = 21;
			}
			else if (i != 22)
			{
				i = 22;
			}
		}
		WaitTimer(0);
	}


	/* ここからマウス処理です */

	// マウスの座標を取得(mx,my)
	GetMousePoint(&mx, &my); 
	if (muki == 1)
	{
		// 中心点とマウスの座標から角度を計算( 動かしたい画像(手)の中心座標 と マウス座標 を使用している)
		angle = (float)atan2(my - (float)playery-48, mx - (float)playerx-48); 
	}
	else if (muki == 0)
	{
		// 中心点とマウスの座標から角度を計算(〃)
		angle = (float)atan2((float)playery+48 - my, (float)playerx+48 - mx); 
	}

	//マウス左クリックのボタンが押された場合
	if ((GetMouseInput() & MOUSE_INPUT_LEFT) != 0)
	{
		//マウス座標を新たに取得(mxx,myy)
		GetMousePoint(&mxx, &myy);
		if(muki == 1)
		{
			Tamax = tex;
			Tamay = tey;
			//腕の反動
			angle = (-90);
		}
		else if(muki == 0)
		{
			Tamax = tex;
			Tamay = tey;
			// 〃
			angle = (90);
		}
		//ショットフラグON
		ShotFlag = 1;
	}

	if(muki == 1)
	{
		//新たに取得したマウス座標(mxx,myy)のxより Tamax が大きい場合
		if(Tamax > mxx-5 )
		{
			//ショットフラグOFF
			ShotFlag =  0;
		}
	}
	else if(muki == 0)
	{
		//新たに取得したマウス座標(mxx,myy)のxより Tamax が小さい場合
		if(Tamax < mxx+5)
		{
			//ショットフラグOFF
			ShotFlag =  0;
		}
	}

	/* ここからTama(弾)の移動処理です */

	// Tama が (mxx,myy) へ移動するときの計算
	sx = Tamax + Tamaw / 8;
	sy = Tamay + Tamah / 8;
		
	sbx = mxx - sx;
	sby = myy - sy;

	sb = sqrt(sbx * sbx + sby * sby);

	Tamasx = sbx / sb * 80;
	Tamasy = sby / sb * 80;

	//ショットフラグがONの場合
	if (ShotFlag == 1)
	{
		Tamax += Tamasx;
		Tamay += Tamasy;
		DrawGraph(Tamax, Tamay, Tama, TRUE);
	}


		//if(ShotFlag == 1) ボツ処理 もしかしたら使うかも
		//{
		//		DrawRotaGraph3( tex, tey, 0, 0, 300, 1.0, angle, Dandou, TRUE ) ;
		//		ShotFlag = 0;
		//}

	//手の画像をプレイヤーにくっつけるための処理
	tex = playerx+48;
	tey = playery+46;

	//描画します
	DrawGraph(mx-15, my-15, AIM, TRUE);
	DrawGraph(playerx, playery, player[i], TRUE);
	DrawRotaGraph(tex, tey, 1.0, angle, te[muki], TRUE);

	// 裏画面の内容を表画面に反映します
	ScreenFlip();
}
C言語については勉強を始めて間もないので至らない点はご指摘ください。
質問ではありませんが今後のためにも、見やすいプログラムの書き方・無駄な処理・こういう処理の仕方もあるなど是非アドバイスもよろしくお願いします。

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

Re: アニメーションのスピードが速すぎるetc...

#2

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

ここのコンテンツである、「ゲームプログラミングの館」と「龍神録の館」を合わせて理解していただけば大抵のヒントは載っていると思います。

コード:

1.について
WaitTimer関数を用いて改善しようと思ったのですが、Waitが他の処理にも影響してしまい
描画の挙動がおかしいです。
WaitTimerは全体に影響するので普通使いません。
個々のオブジェクトごとにタイミングを制御する変数を使います。

コード:

2.について
今作っているゲームは左クリックで弾を撃ちます。長押しでなければ問題ないのですが長押し状態だと
アニメーションが止まってしまいます。
何処かでアニメーションを初期化しているものと思われます。

コード:

3.について
今作っているゲームはマウスで狙いを付ける仕様です。その為[身体の画像]と[腕の画像]を組み合わせ、[腕の画像]をマウスカーソルの方向に回転させています。しかし腕が360°回転してしまうので人間の可動範囲に上限を決めたいと思っています。
絵がないのでイメージが伝わらないですが、角度を制限すれば良いだけだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beagle257

Re: アニメーションのスピードが速すぎるetc...

#3

投稿記事 by beagle257 » 10年前

的確なご指摘ありがとうございます!
さっそく試してみます!

閉鎖

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