EasyX绘图实现反弹球消砖块

知识点:数组、循环、函数调用、鼠标交互

参考:《C语言课程设计与游戏开发实践教程》童晶

做游戏,学编程(C语言)

#include <conio.h>
#include <graphics.h>

#define High 480  // 游戏画面尺寸
#define Width 640
#define Brick_num 10 // 砖块个数

// 全局变量
int ball_x, ball_y; // 小球的坐标
int ball_vx, ball_vy; // 小球的速度
int radius;  // 小球的半径
int bar_x, bar_y; // 挡板中心坐标
int bar_high, bar_width;  // 挡板的高度和宽度
int bar_left, bar_right, bar_top, bar_bottom; // 挡板的上下左右位置坐标

int isBrickExisted[Brick_num]; // 每个砖块是否存在,1为存在,0为没有了
int brick_high, brick_width; // 每个砖块的高度和宽度

void startup()  // 数据初始化
{
	ball_x = Width / 2;
	ball_y = High / 2;
	ball_vx = 1;
	ball_vy = 1;
	radius = 20;

	bar_high = High / 20;
	bar_width = Width / 2;
	bar_x = Width / 2;
	bar_y = High - bar_high / 2;
	bar_left = bar_x - bar_width / 2;
	bar_right = bar_x + bar_width / 2;
	bar_top = bar_y - bar_high / 2;
	bar_bottom = bar_y + bar_high / 2;

	brick_width = Width / Brick_num;
	brick_high = High / Brick_num;

	int i;
	for (i = 0; i < Brick_num; i++)
		isBrickExisted[i] = 1;

	initgraph(Width, High);
	BeginBatchDraw();
}

void clean()  // 消除画面
{
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_x, ball_y, radius); 	// 绘制黑线、黑色填充的圆
	bar(bar_left, bar_top, bar_right, bar_bottom);	// 绘制黑线、黑色填充的挡板

	int i, brick_left, brick_right, brick_top, brick_bottom;
	for (i = 0; i < Brick_num; i++)
	{
		brick_left = i * brick_width;
		brick_right = brick_left + brick_width;
		brick_top = 0;
		brick_bottom = brick_high;
		if (!isBrickExisted[i])	 // 砖块没有了,绘制黑色
			fillrectangle(brick_left, brick_top, brick_right, brick_bottom);
	}
}

void show()  // 显示画面
{
	setcolor(YELLOW);
	setfillcolor(GREEN);
	fillcircle(ball_x, ball_y, radius);	// 绘制黄线、绿色填充的圆
	bar(bar_left, bar_top, bar_right, bar_bottom);	// 绘制黄线、绿色填充的挡板

	int i, brick_left, brick_right, brick_top, brick_bottom;

	for (i = 0; i < Brick_num; i++)
	{
		brick_left = i * brick_width;
		brick_right = brick_left + brick_width;
		brick_top = 0;
		brick_bottom = brick_high;

		if (isBrickExisted[i])	 // 砖块存在,绘制砖块
		{
			setcolor(WHITE);
			setfillcolor(RED);
			fillrectangle(brick_left, brick_top, brick_right, brick_bottom);	// 绘制砖块
		}
	}

	FlushBatchDraw();
	// 延时
	Sleep(3);
}

void updateWithoutInput()  // 与用户输入无关的更新
{
	// 挡板和小圆碰撞,小圆反弹;分小球在挡板上面和下面两种情况
	if (((ball_y + radius >= bar_top) && (ball_y + radius < bar_bottom - bar_high / 3))
		|| ((ball_y - radius <= bar_bottom) && (ball_y - radius > bar_top - bar_high / 3)))
		if ((ball_x >= bar_left) && (ball_x <= bar_right))
			ball_vy = -ball_vy;

	// 更新小圆坐标
	ball_x = ball_x + ball_vx;
	ball_y = ball_y + ball_vy;

	// 小圆和边界碰撞
	if ((ball_x == radius) || (ball_x == Width - radius))
		ball_vx = -ball_vx;
	if ((ball_y == radius) || (ball_y == High - radius))
		ball_vy = -ball_vy;

	// 判断小圆是否和某个砖块碰撞
	int i, brick_left, brick_right, brick_bottom;
	for (i = 0; i < Brick_num; i++)
	{
		if (isBrickExisted[i])	 // 砖块存在,才判断
		{
			brick_left = i * brick_width;
			brick_right = brick_left + brick_width;
			brick_bottom = brick_high;
			if ((ball_y <= brick_bottom + radius) && (ball_x >= brick_left) && (ball_x <= brick_right))
			{
				isBrickExisted[i] = 0;
				ball_vy = -ball_vy;
			}
		}
	}
}

void updateWithInput()  // 与用户输入有关的更新
{
	MOUSEMSG m;		// 定义鼠标消息
	if (MouseHit())  //这个函数用于检测当前是否有鼠标消息
	{
		m = GetMouseMsg();  	// 获取一条鼠标消息
		if (m.uMsg == WM_MOUSEMOVE)
		{
			// 鼠标移动时,挡板的位置等于鼠标所在的位置
			bar_x = m.x;
			bar_y = m.y;
			bar_left = bar_x - bar_width / 2;
			bar_right = bar_x + bar_width / 2;
			bar_top = bar_y - bar_high / 2;
			bar_bottom = bar_y + bar_high / 2;
		}
		else if (m.uMsg == WM_LBUTTONDOWN)
		{
			// 按下鼠标左键,初始化小球的位置为挡板上面中心
			ball_x = bar_x;
			ball_y = bar_top - radius - 3;
		}
	}
}

void gameover()
{
	EndBatchDraw();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		clean();  // 把之前绘制的内容取消
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();     // 与用户输入有关的更新
		show();  // 显示新画面
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}

 运行结果:

反弹球游戏和方块游戏都是比较经典的小游戏,使用easyx库可以很方便地实现这两个游戏。下面是反弹球游戏和方块游戏的要求: 反弹球游戏要求: 1. 画出一个小球和一个挡板; 2. 小球从挡板上方开始运动,碰到边界会反弹; 3. 小球碰到挡板会反弹,如果小球落到挡板下方,则游戏结束; 4. 挡板可以左右移动,通过键盘控制; 5. 当小球碰到砖块时,砖块失,小球会反弹; 6. 当所有砖块都被除时,游戏胜利。 方块游戏要求: 1. 画出一个矩形区域,里面有多个小矩形组成的砖块; 2. 有一个小球从上方开始运动,碰到边界会反弹; 3. 有一个挡板可以左右移动,通过键盘控制; 4. 当小球碰到砖块时,砖块失,小球会反弹; 5. 当所有砖块都被除时,游戏胜利; 6. 如果小球落到挡板下方,则游戏结束。 下面是反弹球游戏的代码示例: ```cpp #include <graphics.h> #include <conio.h> #include <time.h> #include <stdlib.h> #define BALL_RADIUS 10 #define BLOCK_WIDTH 50 #define BLOCK_HEIGHT 20 #define BLOCK_ROWS 5 #define BLOCK_COLS 10 #define BOARD_WIDTH 100 #define BOARD_HEIGHT 10 #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 int blocks[BLOCK_ROWS][BLOCK_COLS] = {0}; int score = 0; void initBlocks() { for (int i = 0; i < BLOCK_ROWS; i++) { for (int j = 0; j < BLOCK_COLS; j++) { blocks[i][j] = 1; } } } void drawBlocks() { for (int i = 0; i < BLOCK_ROWS; i++) { for (int j = 0; j < BLOCK_COLS; j++) { if (blocks[i][j] == 1) { int x = j * BLOCK_WIDTH; int y = i * BLOCK_HEIGHT; setfillcolor(RGB(255, 0, 0)); fillrectangle(x, y, x + BLOCK_WIDTH, y + BLOCK_HEIGHT); } } } } void drawBoard(int x) { setfillcolor(RGB(0, 255, 0)); fillrectangle(x, WINDOW_HEIGHT - BOARD_HEIGHT, x + BOARD_WIDTH, WINDOW_HEIGHT); } void drawBall(int x, int y) { setfillcolor(RGB(0, 0, 255)); fillellipse(x, y, BALL_RADIUS, BALL_RADIUS); } bool isCollide(int x, int y) { if (y + BALL_RADIUS >= WINDOW_HEIGHT - BOARD_HEIGHT && y + BALL_RADIUS <= WINDOW_HEIGHT) { if (x + BALL_RADIUS >= boardX && x - BALL_RADIUS <= boardX + BOARD_WIDTH) { return true; } } return false; } bool isCollideBlock(int x, int y, int &row, int &col) { row = (y - BALL_RADIUS) / BLOCK_HEIGHT; col = x / BLOCK_WIDTH; if (row >= 0 && row < BLOCK_ROWS && col >= 0 && col < BLOCK_COLS && blocks[row][col] == 1) { return true; } return false; } void updateBall(int &x, int &y, int &vx, int &vy) { x += vx; y += vy; if (x - BALL_RADIUS <= 0 || x + BALL_RADIUS >= WINDOW_WIDTH) { vx = -vx; } if (y - BALL_RADIUS <= 0) { vy = -vy; } if (y + BALL_RADIUS >= WINDOW_HEIGHT) { exit(0); } if (isCollide(x, y)) { vy = -vy; } int row, col; if (isCollideBlock(x, y, row, col)) { blocks[row][col] = 0; score++; vy = -vy; } } int main() { initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); initBlocks(); int ballX = WINDOW_WIDTH / 2; int ballY = WINDOW_HEIGHT / 2; int ballVX = 5; int ballVY = 5; int boardX = WINDOW_WIDTH / 2 - BOARD_WIDTH / 2; while (true) { cleardevice(); drawBlocks(); drawBoard(boardX); drawBall(ballX, ballY); updateBall(ballX, ballY, ballVX, ballVY); if (score == BLOCK_ROWS * BLOCK_COLS) { MessageBox(NULL, TEXT("You Win!"), TEXT("Message"), MB_OK); break; } if (_kbhit()) { int key = _getch(); if (key == 'a' && boardX > 0) { boardX -= 10; } if (key == 'd' && boardX + BOARD_WIDTH < WINDOW_WIDTH) { boardX += 10; } } Sleep(20); } closegraph(); return 0; } ``` 下面是方块游戏的代码示例: ```cpp #include <graphics.h> #include <conio.h> #include <time.h> #include <stdlib.h> #define BALL_RADIUS 10 #define BLOCK_WIDTH 50 #define BLOCK_HEIGHT 20 #define BLOCK_ROWS 5 #define BLOCK_COLS 10 #define BOARD_WIDTH 100 #define BOARD_HEIGHT 10 #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 int blocks[BLOCK_ROWS][BLOCK_COLS] = {0}; int score = 0; void initBlocks() { for (int i = 0; i < BLOCK_ROWS; i++) { for (int j = 0; j < BLOCK_COLS; j++) { blocks[i][j] = rand() % 2; } } } void drawBlocks() { for (int i = 0; i < BLOCK_ROWS; i++) { for (int j = 0; j < BLOCK_COLS; j++) { if (blocks[i][j] == 1) { int x = j * BLOCK_WIDTH; int y = i * BLOCK_HEIGHT; setfillcolor(RGB(255, 0, 0)); fillrectangle(x, y, x + BLOCK_WIDTH, y + BLOCK_HEIGHT); } } } } void drawBoard(int x) { setfillcolor(RGB(0, 255, 0)); fillrectangle(x, WINDOW_HEIGHT - BOARD_HEIGHT, x + BOARD_WIDTH, WINDOW_HEIGHT); } void drawBall(int x, int y) { setfillcolor(RGB(0, 0, 255)); fillellipse(x, y, BALL_RADIUS, BALL_RADIUS); } bool isCollide(int x, int y) { if (y + BALL_RADIUS >= WINDOW_HEIGHT - BOARD_HEIGHT && y + BALL_RADIUS <= WINDOW_HEIGHT) { if (x + BALL_RADIUS >= boardX && x - BALL_RADIUS <= boardX + BOARD_WIDTH) { return true; } } return false; } bool isCollideBlock(int x, int y, int &row, int &col) { row = (y - BALL_RADIUS) / BLOCK_HEIGHT; col = x / BLOCK_WIDTH; if (row >= 0 && row < BLOCK_ROWS && col >= 0 && col < BLOCK_COLS && blocks[row][col] == 1) { return true; } return false; } void updateBall(int &x, int &y, int &vx, int &vy) { x += vx; y += vy; if (x - BALL_RADIUS <= 0 || x + BALL_RADIUS >= WINDOW_WIDTH) { vx = -vx; } if (y - BALL_RADIUS <= 0) { vy = -vy; } if (y + BALL_RADIUS >= WINDOW_HEIGHT) { exit(0); } if (isCollide(x, y)) { vy = -vy; } int row, col; if (isCollideBlock(x, y, row, col)) { blocks[row][col] = 0; score++; vy = -vy; } } int main() { initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); srand(time(NULL)); initBlocks(); int ballX = WINDOW_WIDTH / 2; int ballY = WINDOW_HEIGHT / 2; int ballVX = 5; int ballVY = 5; int boardX = WINDOW_WIDTH / 2 - BOARD_WIDTH / 2; while (true) { cleardevice(); drawBlocks(); drawBoard(boardX); drawBall(ballX, ballY); updateBall(ballX, ballY, ballVX, ballVY); if (score == BLOCK_ROWS * BLOCK_COLS) { MessageBox(NULL, TEXT("You Win!"), TEXT("Message"), MB_OK); break; } if (_kbhit()) { int key = _getch(); if (key == 'a' && boardX > 0) { boardX -= 10; } if (key == 'd' && boardX + BOARD_WIDTH < WINDOW_WIDTH) { boardX += 10; } } Sleep(20); } closegraph(); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值