ブロック崩し

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Tomo
記事: 16
登録日時: 10年前
住所: 埼玉県

ブロック崩し

#1

投稿記事 by Tomo » 10年前

ブロック崩しを作ってみようと思い、
以下のようなプログラムをかきました(まだ未完成です)
バーに当たった時中心から見て右側なら中心から離れている分だけ右に跳ね返したいのですが真上に跳ね返ってしまいます。
なぜでしょうか?

環境:visualstudio2013,Dxlibrary,C++

.h

コード:

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

//mouse
int mouse_x, mouse_y;//mouseの座標
int mouse_input;//mouseの入力
//ball
double ball_x, ball_y;//ballの座標
double ball_dx, ball_dy;//ballの移動量
//ballの画像の横幅、縦幅
int ball_width[10];
int ball_height[10];
int ball_gh[10];//ballのグラフィックハンドル10個
bool ballflag;//ballの生死
//bar
int bar_x, bar_y;//barの座標
//barの画像の横幅、縦幅
int bar_width[10];
int bar_height[10];
int bar_gh[10];//barのグラフィックハンドル10個
//block
//blockの座標10個
int block_x[10];
int block_y[10];
int block_gh[10];//blockのグラフィックハンドル10個
bool blockflag;//blockの生死

//ball関係の変数に初期値を代入
void ball(){
	ball_gh[0] = LoadGraph("ball_yellow.png");
	ball_width[0] = 20;
	ball_height[0] = 20;
	ball_x = 400;
	ball_y = 300;
	ball_dx = 3;
	ball_dy = 3;
	ballflag = true;
}

void ballmove(){
	//ballの移動
	ball_x += ball_dx;
	ball_y += ball_dy;
	//ballの移動制御
	if (ball_x > 780 || ball_x < 0){
		ball_dx *= -1;
	}
	if (ball_y < 0){
		ball_dy *= -1;
	}
	if (ball_y>600){
		ballflag = false;
	}

}

//ballの描画
void balldraw(){
	DrawGraph(ball_x, ball_y, ball_gh[0], TRUE);
}

//bar関係の変数に初期値を代入
void bar(){
	bar_gh[0] = LoadGraph("bar_red.png");
	bar_width[0] = 80;
	bar_height[0] = 20;
	bar_bound = 0;
	bar_x = 400;
	bar_y = 550;
}

void barmove(){
	bar_x = mouse_x;
	//bar_y = mouse_y;
	//barの移動制御
	if (bar_x > 720){
		bar_x = 720;
	}
	if (bar_x < 0){
		bar_x = 0;
	}
	if (bar_y>580){
		bar_y = 580;
	}
	if (bar_y < 0){
		bar_y = 0;
	}
}

//barの描画
void bardraw(){
	DrawGraph(bar_x, bar_y, bar_gh[0],TRUE);
}

void CollisionDetection(){
	
	if (bar_y - ball_y < 20&&bar_y>ball_y){//bar,ballのy座標の当たり判定
		
		if (bar_x-20<ball_x&&bar_x+bar_width[0]>ball_x){//bar,ballのx座標の当たり判定
			
			if (bar_x + bar_width[0] / 2 < ball_x){
				if (ball_dx < 0){
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10)*-1;
					ball_dx *= -1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
				else{
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10);
					ball_dx *= 1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}

			}
			else{
				if (ball_dx > 0){
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10);
					ball_dx *= -1.1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
				else{
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10)*-1;
					ball_dx *= 1.1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
			}
			
		}


	}

}


.cpp

コード:

#include"Nori.h"

char key[256];

//ループで必ず行う3大処理
int ProcessLoop(){
	if (ProcessMessage() != 0)return -1;//プロセス処理がエラーなら-1を返す
	if (ClearDrawScreen() != 0)return -1;//画面クリア処理がエラーなら-1を返す
	if(GetHitKeyStateAll(key)!=0)return -1;//現在のキー入力処理を行う
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if (DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;//初期化と裏画面化
	SetGraphMode(800, 600, 16);
	SetWindowText("ブロック崩し");


	SetMouseDispFlag(TRUE);//mouseを表示状態にする
	mouse_input = GetMouseInput();//mouseの入力待ち
	ball();//ball関係の変数に初期値を代入
	bar();//bar関係の変数に初期値を代入

	while (ProcessLoop() == 0){

		GetMousePoint(&mouse_x, &mouse_y);//mouseの位置の取得

		ballmove();//ballの移動
		barmove();//barの移動
		CollisionDetection();//barとballの当たり判定

		balldraw();//ballの描画
		bardraw();//barの描画

		mouse_input = GetMouseInput();//mouseの入力待ち

		if (key[KEY_INPUT_ESCAPE] == 1)break;//エスケープが入力されたら終了
		ScreenFlip();//裏画面反映
	}

	DxLib_End();//DXライブラリ終了処理
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ブロック崩し

#2

投稿記事 by みけCAT » 10年前

蜜柑 さんが書きました:

コード:

			if (bar_x + bar_width[0] / 2 < ball_x){
				if (ball_dx < 0){
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10)*-1;
					ball_dx *= -1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
				else{
					ball_dx = (bar_width[0] / 100)*(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10);
					ball_dx *= 1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}

			}
int型のbar_width[0]の値は80なので、(bar_width[0] / 100)の値は0です。
0に(abs((bar_x + (bar_width[0] / 2)) - ball_x) / 10)を掛けても0なので、ball_dxに0が代入され、ボールが真上に跳ね返るように見えるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Tomo
記事: 16
登録日時: 10年前
住所: 埼玉県

Re: ブロック崩し

#3

投稿記事 by Tomo » 10年前

ありがとうございます。
int 型では計算結果が小数になってくれないんですね。
アドバイスを元にbar_widthをdouble 型のbar_boundにいれてから計算させるように変更しました。
確かにはね方が変わってはくれるのですが右と左で違和感をを覚えます
中心からの距離の絶対値で計算しているのですが
どこが問題なのでしょうか?

コード:

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

//mouse
int mouse_x, mouse_y;//mouseの座標
int mouse_input;//mouseの入力
//ball
double ball_x, ball_y;//ballの座標
double ball_dx, ball_dy;//ballの移動量
//ballの画像の横幅、縦幅
int ball_width[10];
int ball_height[10];
int ball_gh[10];//ballのグラフィックハンドル10個
bool ballflag;//ballの生死
//bar
int bar_x, bar_y;//barの座標
//barの画像の横幅、縦幅
int bar_width[10];
int bar_height[10];
double bar_bound;//計算時に使用
int bar_gh[10];//barのグラフィックハンドル10個
//block
//blockの座標10個
int block_x[10];
int block_y[10];
int block_gh[10];//blockのグラフィックハンドル10個
bool blockflag;//blockの生死

//ball関係の変数に初期値を代入
void ball(){
	ball_gh[0] = LoadGraph("ball_yellow.png");
	ball_width[0] = 20;
	ball_height[0] = 20;
	ball_x = 400;
	ball_y = 300;
	ball_dx = 3;
	ball_dy = 3;
	ballflag = true;
}

void ballmove(){
	//ballの移動
	ball_x += ball_dx;
	ball_y += ball_dy;
	//ballの移動制御
	if (ball_x > 780 || ball_x < 0){
		ball_dx *= -1;
	}
	if (ball_y < 0){
		ball_dy *= -1;
	}
	if (ball_y>600){
		ballflag = false;
	}

}

//ballの描画
void balldraw(){
	DrawGraph(ball_x, ball_y, ball_gh[0], TRUE);
}

//bar関係の変数に初期値を代入
void bar(){
	bar_gh[0] = LoadGraph("bar_red.png");
	bar_width[0] = 80;
	bar_height[0] = 20;
	bar_bound = bar_width[0];
	bar_x = 400;
	bar_y = 550;
}

void barmove(){
	bar_x = mouse_x;
	//bar_y = mouse_y;
	//barの移動制御
	if (bar_x > 720){
		bar_x = 720;
	}
	if (bar_x < 0){
		bar_x = 0;
	}
	if (bar_y>580){
		bar_y = 580;
	}
	if (bar_y < 0){
		bar_y = 0;
	}
}

//barの描画
void bardraw(){
	DrawGraph(bar_x, bar_y, bar_gh[0],TRUE);
}

void CollisionDetection(){
	
	if (bar_y - ball_y < 20&&bar_y>ball_y){//bar,ballのy座標の当たり判定
		
		if (bar_x-20<ball_x&&bar_x+bar_width[0]>ball_x){//bar,ballのx座標の当たり判定
			
			if (bar_x + bar_width[0] / 2 < ball_x){
				if (ball_dx < 0){
					ball_dx = (bar_bound / 100)*(abs((bar_x + (bar_bound / 2)) - ball_x) / 10)*-1.5;
					ball_dx *= -1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
				else{
					ball_dx = (bar_bound / 100)*(abs((bar_x + (bar_bound / 2)) - ball_x) / 10)*1.5;
					ball_dx *= 1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}

			}
			else{
				if (ball_dx > 0){
					ball_dx = (bar_bound / 100)*(abs((bar_x + (bar_bound / 2)) - ball_x) / 10)*1.5;
					ball_dx *= -1.1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
				else{
					ball_dx = (bar_bound / 100)*(abs((bar_x + (bar_bound / 2)) - ball_x) / 10)*-1.5;
					ball_dx *= 1.1;
					if (fabs(ball_dy)>15){
						ball_dy = 15;
					}
					ball_dy *= -1.1;
					
				}
			}
			
		}


	}

}



閉鎖

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