ブロック崩し、玉の反射角度がおかしくなってしまうことについて

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

ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#1

投稿記事 by sone » 12年前

C言語はかなりの初心者です この質問も拙いところがあるでしょうが、ご容赦願います
環境はVisual C++ 2010 Express です。それと、Dxライブラリを使用しています

問題は、現在ブロック崩しを作っているのですが、枠に当たった時の玉の反射角度が線対称にならないことです
具体的に言えば、右端の枠と左端の枠、それぞれにぶつかった時の角度が違っていたりする点です
説明がしにくい現象なので、とりあえずコードを貼ってみます。コメントが多くて冗長なのが申し訳ないです
おそらく角度計算の部分が間違えてるのだと思います

コード:

[code]
#include "DxLib.h"
#include <math.h>

#define PI 3.1415926f //PIを円周率と定義

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
	//ウィンドウ設定
	ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
	if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
	SetGraphMode( 640 , 480 , 16 ) ;// 画面モードの設定
	SetDrawScreen( DX_SCREEN_BACK ) ;// グラフィックの描画先を裏画面にセット
	

	int Bbar, Rbar, barX, barY, barW, barH; //バー(状態、座標、縦横の幅)
	int ballX , ballY , Bball, Rball, ballW ,ballH; //ボール(座標、状態、縦横の幅)
	int start =0; //発射前か後か
	double len = 5;//移動する距離
	double deg; //角度(360度)

	//グラフィックをロード、表示座標セット
	//バー
	Bbar = LoadGraph("画像/B BAR.png");
	barX = 270 ; barY = 440 ;
	// ボール 
	Bball = LoadGraph( "画像/B BALL.png" ) ;
	ballX = 320 ; ballY = 420 ;

	//グラフィックのサイズを得る
	GetGraphSize( Bbar , &barW , &barH ) ; // バー
	GetGraphSize( Bball , &ballW , &ballH ) ; // ボール 

	// メインルーチン
	while( 1 )
	{
		// 画面を初期化(真っ黒にする)
		ClearDrawScreen() ;

		// バーの操作ルーチン
		{
			// ←キーを押していたらバーを左に移動させる
			if( CheckHitKey( KEY_INPUT_LEFT ) == 1 ) barX -= 5 ;
			// →キーを押していたらバーを右に移動させる
			if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 ) barX += 5 ;

			// バーが画面両端からはみ出すのを禁止
			if( barX < 0 ) barX = 0 ;
			if( barX > 640 - 98 ) barX = 640 - 98  ;

			
			DrawGraph( barX , barY , Bbar , TRUE ) ;
		}

		//ボールの移動ルーチン
		{
			//スタート時のバー追随ボール
			if(start == 0)
			{
				//Zキーで発射
				if( CheckHitKey( KEY_INPUT_Z ) )
					{
						ballX = barX +42;
						ballY = barY -14;
						start = 1;

						//75度の方向に発射
						deg =75; 
					}

				//追随ボールを描画する
				DrawGraph( barX +42 , barY -14, Bball, TRUE);

			}
			//発射後のボール動作
			else
			{
				//枠との衝突判定(向きを逆にする)
				if( ballX + ballW >= 640 || ballX <= 0) 
				{
					deg = 180 - deg  ;
				}
				
				if( ballY <= 0 ) 
				{
					 deg = - deg ;
				}
			
				if( ballY + ballH >= 500 ) //game over
				{
					break; 
				}
				//バーとの衝突判定
				if( ( ( ballX > barX && ballX < barX + barW ) ||( barX > ballX && barX < ballX + ballW ) ) 
				&&
				( ( ballY > barY && ballY < barY + barH ) ||( barY > ballY && barY < ballY + ballH ) ) )
				{
					// 接触している
					deg = - deg;
                                                    }

				//ボールの動作
				
				double rad = deg * PI/ 180.0;

				ballX -= len * cos( rad );
				ballY += len * sin( rad );
				
				//数値を表示
				DrawFormatString( 0,0,GetColor(255,255,255), "deg=%f, rad=%f\n", deg, rad );

				// 画面にボールを描画する
				DrawGraph( ballX, ballY, Bball, TRUE ) ;
			}
		}
		// 裏画面の内容を表画面にコピーする
		ScreenFlip() ;
		
		//事後処理
		// Windows 特有の面倒な処理をDXライブラリにやらせる
		// -1 が返ってきたらループを抜ける
		if( ProcessMessage() < 0 ) break ;
		// もしESCキーが押されていたらループから抜ける
		if( CheckHitKey( KEY_INPUT_ESCAPE ) )  break;
	}
        DxLib_End() ;           // DXライブラリ使用の終了処理
        return 0 ;              // ソフトの終了
 }
ビルドはできますがコンパイルエラーのようなものが出ていますのでそれも書いておきます

br.cpp(105): warning C4244: '-=' : 'double' から 'int' への変換です。データが失われる可能性があります。
br.cpp(106): warning C4244: '+=' : 'double' から 'int' への変換です。データが失われる可能性があります。

使用した画像データです B BALL ,B BAR の順です
画像
画像

きちんと反射させるにはどうしたら良いか、ご教示願います

sone

Re: ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#2

投稿記事 by sone » 12年前

すみません書き忘れてました、OSはWindows7 64bitです。

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

Re: ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#3

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

反射の計算に無理があると思います。
例えば、180度の角度で落下してくる玉をバーで-180度に反射しても同じ方向で下です。つまり反射されません。
ベクトルで反射を管理してはどうでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

sone

Re: ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#4

投稿記事 by sone » 12年前

アドバイスありがとうございます。ベクトルを調べてやってみます。

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

Re: ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#5

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

補足しておくと、Xベクトルを+-反転すると移動方向を横方向のみ逆転できます。yベクトルを+-反転すると移動方向を上下方向のみ逆転できるので反射を表現しやすいのです。
【補足の補足】
ただ、バーの角に当たった時の挙動とか、バーの移動とボールの移動が同時に起こって刺さり衝突した時の挙動とか、ブロックとブロックの隙間で反射の挙動は難しいのでブロック崩しは初心者いじめなテーマでは有ると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

sone

Re: ブロック崩し、玉の反射角度がおかしくなってしまうことについて

#6

投稿記事 by sone » 12年前

意外とブロック崩しは初心者には敷居が高かったのですね。それでも、とりあえずこれをある程度の形にして完成させることを考えようと思います。
度々ありがとうございました。

閉鎖

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