C語言進階版的反彈球消方塊

一 . 首先搭建好小球

要求小球半徑爲20 ,並且初速度爲1 , 撞牆後能夠進行反彈.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <graphics.h>

#define high 480  // 遊戲畫面尺寸
#define width 640

// 全局變量
int ball_x, ball_y; // 小球的座標
int ball_vx, ball_vy; // 小球的速度
int ball_radius; //小球半徑

void gotoxy(int x, int y)  //光標移動到(x,y)位置
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void HideCursor() // 用於隱藏光標
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };  // 第二個值爲0表示隱藏光標
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void startup()  // 數據初始化
{
	HideCursor(); // 隱藏光標
	// 小球屬性 
	ball_x = width / 2;
	ball_y = high / 2;
	ball_vx = 1;
	ball_vy = 1;
	ball_radius = 20; 

	//初始化畫筆
	initgraph(width , high);
	BeginBatchDraw(); // 開始批量繪畫
}

void clear()
{
	//清除小球
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_x, ball_y, ball_radius);
}

void show()  // 顯示畫面
{
	gotoxy(0, 0);    // 光標移動到原點位置,以下重畫清屏
	//畫球
	setcolor(GREEN); //綠線
	setfillcolor(YELLOW);//黃邊
	fillcircle(ball_x, ball_y, ball_radius);

	// 執行未完成的繪製任務
	FlushBatchDraw();
	Sleep(5);

}

void updateWithoutInput()  // 更新小球和減少方塊
{
	//更新小球的位置
	ball_x += ball_vx;
	ball_y += ball_vy;
	//撞牆調整球的方向
	if ((ball_x - ball_radius) < 0 || (ball_x + ball_radius) > width)
		ball_vx = -ball_vx;
	if ((ball_y - ball_radius) < 0 || (ball_y + ball_radius) > high)
		ball_vy = -ball_vy;
}

void updateWithInput()  // 與用戶輸入有關的更新
{
	
}

void gameOver() // 遊戲結束處理
{
	// 關閉羣刷
	EndBatchDraw();
	// 關閉畫筆
	closegraph();
}

int main()
{
	startup();  // 數據初始化	
	while (1)  //  遊戲循環執行
	{
		clear(); // 清屏
		updateWithoutInput();  // 與用戶輸入無關的更新
		updateWithInput();     // 與用戶輸入有關的更新
		show();  // 顯示畫面
	}
	gameOver(); //遊戲結束處理
	return 0;
}

運行以上代碼可以實現該功能.

 

二 . 繪製出擋板的效果 

1. 先繪製出擋板

2.給擋板添加移動功能

3.給擋板添加限制功能

4.給擋板添加反彈球功能

5.要求擋板接到球可以反彈 ,沒接到則遊戲停止.

以上功能可以邊調試邊實現功能

 

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <graphics.h>

#define high 480  // 遊戲畫面尺寸
#define width 640

// 全局變量
int ball_x, ball_y; // 小球的座標
int ball_vx, ball_vy; // 小球的速度
int ball_radius; //小球半徑
int bar_x, bar_y; // 擋板的中心座標
int bar_width, bar_high; // 擋板的高寬
int bar_top, bar_bottom, bar_left, bar_right; // 擋板的上下左右


void gotoxy(int x, int y)  //光標移動到(x,y)位置
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void HideCursor() // 用於隱藏光標
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };  // 第二個值爲0表示隱藏光標
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void startup()  // 數據初始化
{
	HideCursor(); // 隱藏光標
	// 小球屬性 
	ball_x = width / 2;
	ball_y = high / 2;
	ball_vx = 1;
	ball_vy = 1;
	ball_radius = 20; 
	//擋板的屬性
	bar_width = width / 6; 
	bar_high = high / 20;
	bar_x = width / 2;
	bar_y = high - bar_high;
	bar_top = bar_y - bar_high / 2;
	bar_bottom = bar_y + bar_high / 2;
	bar_left = bar_x - bar_width / 2;
	bar_right = bar_x + bar_width / 2;

	//初始化畫筆
	initgraph(width , high);
	BeginBatchDraw(); // 開始批量繪畫
}

void clear()
{
	//清除小球
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_x, ball_y, ball_radius);

	//擦除擋板移動的痕跡
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillrectangle(bar_left, bar_top, bar_right, bar_bottom);
}

void show()  // 顯示畫面
{
	gotoxy(0, 0);    // 光標移動到原點位置,以下重畫清屏
	//畫球
	setcolor(GREEN); //綠線
	setfillcolor(YELLOW);//黃邊
	fillcircle(ball_x, ball_y, ball_radius);

	// 畫 擋板
	setcolor(BLUE); 
	setfillcolor(RED);
	fillrectangle(bar_left, bar_top, bar_right, bar_bottom);

	// 執行未完成的繪製任務
	FlushBatchDraw();
	Sleep(5);

}

void updateWithoutInput()  // 更新小球和減少方塊
{
	//更新小球的位置
	ball_x += ball_vx;
	ball_y += ball_vy;

	//擋板接球
	if ( ((ball_y + ball_radius) >= bar_top && ball_x >= bar_left && ball_x <= bar_right )  )
		ball_vy = -ball_vy;

	//撞牆調整球的方向
	if ((ball_x - ball_radius) < 0 || (ball_x + ball_radius) > width)
		ball_vx = -ball_vx;
	if ((ball_y - ball_radius) < 0 || (ball_y + ball_radius) > high)
		ball_vy = -ball_vy;
}

void updateWithInput()  // 與用戶輸入有關的更新
{
	//獲取鍵位輸入
	char input;
	if (_kbhit())
	{
		input = _getch();
		if (input == 'a' && bar_left >= 0)
		{
			bar_x -= 15;
			bar_left = bar_x - bar_width / 2;
			bar_right = bar_x + bar_width / 2;
		}
		if (input == 'w' && bar_top >= 0)
		{
			bar_y -= 15;
			bar_top = bar_y - bar_high / 2;
			bar_bottom = bar_y + bar_high / 2;
		}
		if (input == 'd' && bar_right <= width)
		{
			bar_x += 15;
			bar_left = bar_x - bar_width / 2;
			bar_right = bar_x + bar_width / 2;
		}
		if (input == 's' && bar_bottom <= high)
		{
			bar_y += 15;
			bar_top = bar_y - bar_high / 2;
			bar_bottom = bar_y + bar_high / 2;
		}
	}
}

void gameOver() // 遊戲結束處理
{
	// 關閉羣刷
	EndBatchDraw();
	// 關閉畫筆
	closegraph();
}

int main()
{
	startup();  // 數據初始化	
	while (1)  //  遊戲循環執行
	{
		clear(); // 清屏
		updateWithoutInput();  // 與用戶輸入無關的更新
		updateWithInput();     // 與用戶輸入有關的更新
		show();  // 顯示畫面
	}
	gameOver(); //遊戲結束處理
	return 0;
}

第三步:實現小方塊功能

1. 現實小方塊

2.撞擊則消失

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <graphics.h>

#define high 480  // 遊戲畫面尺寸
#define width 640
#define block_num 16 //磚塊數量16
// 全局變量
int ball_x, ball_y; // 小球的座標
int ball_vx, ball_vy; // 小球的速度
int ball_radius; //小球半徑
int bar_x, bar_y; // 擋板的中心座標
int bar_width, bar_high; // 擋板的高寬
int bar_top, bar_bottom, bar_left, bar_right; // 擋板的上下左右
int block_width, block_high;  // 寬高
int isBlockExist[block_num]; // 判斷磚塊是否存在 , 1 爲存在 , 0 爲被撞擊消失了


void gotoxy(int x, int y)  //光標移動到(x,y)位置
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void HideCursor() // 用於隱藏光標
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };  // 第二個值爲0表示隱藏光標
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void startup()  // 數據初始化
{
	HideCursor(); // 隱藏光標
	// 小球屬性 
	ball_x = width / 2;
	ball_y = high / 2;
	ball_vx = 1;
	ball_vy = 1;
	ball_radius = 20; 
	//擋板的屬性
	bar_width = width / 6; 
	bar_high = high / 20;
	bar_x = width / 2;
	bar_y = high - bar_high;
	bar_top = bar_y - bar_high / 2;
	bar_bottom = bar_y + bar_high / 2;
	bar_left = bar_x - bar_width / 2;
	bar_right = bar_x + bar_width / 2;
	//方塊屬性
	block_high = high / block_num;
	block_width = width / block_num;
	for (int i = 0; i <= block_num; i++)
	{
		isBlockExist[i] = 1;
	}

	//初始化畫筆
	initgraph(width , high);
	BeginBatchDraw(); // 開始批量繪畫
}

void show()  // 顯示畫面
{
	gotoxy(0, 0);    // 光標移動到原點位置,以下重畫清屏
	//畫球
	setcolor(GREEN); //綠線
	setfillcolor(YELLOW);//黃邊
	fillcircle(ball_x, ball_y, ball_radius);

	// 畫 擋板
	setcolor(BLUE); 
	setfillcolor(RED);
	fillrectangle(bar_left, bar_top, bar_right, bar_bottom);

	// 方塊
	int block_left, block_top, block_right, block_bottom;
	for (int i = 0; i < block_num; i++)
	{
		block_left = i * block_width;
		block_right = block_left + block_width;
		block_top = 0;
		block_bottom = block_high;
		if (isBlockExist[i] )
		{
			setcolor(DARKGRAY);
			setfillcolor(LIGHTGREEN);
			fillrectangle(block_left, block_top, block_right, block_bottom);
		}
	}
	

	// 執行未完成的繪製任務
	FlushBatchDraw();
	Sleep(5);

}

void clear()
{
	//清除小球
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_x, ball_y, ball_radius);

	//擦除擋板移動的痕跡
	fillrectangle(bar_left, bar_top, bar_right, bar_bottom);

	// 擦除方塊
	int block_left, block_top, block_right, block_bottom;
	for (int i = 0; i < block_num; i++)
	{
		block_left = i * block_width;
		block_right = block_left + block_width;
		block_top = 0;
		block_bottom = block_high;
		if ( !isBlockExist[i])
			fillrectangle(block_left, block_top, block_right, block_bottom);
	}
}

void updateWithoutInput()  // 更新小球和減少方塊
{
	//更新小球的位置
	ball_x += ball_vx;
	ball_y += ball_vy;

	//撞牆調整球的方向
	if ((ball_x - ball_radius) < 0 || (ball_x + ball_radius) > width)
		ball_vx = -ball_vx;
	if ((ball_y - ball_radius) < 0 || (ball_y + ball_radius) > high)
		ball_vy = -ball_vy;

	//擋板接球
	if ( ((ball_y + ball_radius) >= bar_top && ball_x >= bar_left && ball_x <= bar_right )  )
		ball_vy = -ball_vy;

	// 方塊
	int block_left, block_top, block_right, block_bottom;
	for (int i = 0; i < block_num; i++)
	{
		if (isBlockExist[i] )
		{
			block_left = i * block_width;
			block_right = block_left + block_width;
			block_top = 0;
			block_bottom = block_high;
			if (((ball_y - ball_radius) == block_bottom && (ball_x >= block_left) && (ball_x <= block_right)))
			{
				isBlockExist[i] = 0;
				ball_vy = -ball_vy;
			}
		}
	}
}

void updateWithInput()  // 與用戶輸入有關的更新
{
	//獲取鍵位輸入
	char input;
	if (_kbhit())
	{
		input = _getch();
		if (input == 'a' && bar_left >= 0)
		{
			bar_x -= 15;
			bar_left = bar_x - bar_width / 2;
			bar_right = bar_x + bar_width / 2;
		}
		if (input == 'w' && bar_top >= 0)
		{
			bar_y -= 15;
			bar_top = bar_y - bar_high / 2;
			bar_bottom = bar_y + bar_high / 2;
		}
		if (input == 'd' && bar_right <= width)
		{
			bar_x += 15;
			bar_left = bar_x - bar_width / 2;
			bar_right = bar_x + bar_width / 2;
		}
		if (input == 's' && bar_bottom <= high)
		{
			bar_y += 15;
			bar_top = bar_y - bar_high / 2;
			bar_bottom = bar_y + bar_high / 2;
		}
	}
}

void gameOver() // 遊戲結束處理
{
	// 關閉羣刷
	EndBatchDraw();
	// 關閉畫筆
	closegraph();
}

int main()
{
	startup();  // 數據初始化	
	while (1)  //  遊戲循環執行
	{
		clear(); // 清屏
		updateWithoutInput();  // 與用戶輸入無關的更新
		updateWithInput();     // 與用戶輸入有關的更新
		show();  // 顯示畫面
	}
	gameOver(); //遊戲結束處理
	return 0;
}

本效果到此!!!!代碼全貼出 , 需要的可以學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章