Easyx | 游戏实例:打砖块

目录

目录

游戏简介

图片素材

 游戏编写

预编译代码:

第一步:初始化砖块

第二步:绘制

第三步:移动木板

第四步:移动球

第五步:判断输赢

main 函数

效果预览

完整代码 


游戏简介

打砖块游戏是一个常见的经典小游戏,很常见的欸!

代码编写步骤:

---------- 1. 初始化砖块

---------- 2. 绘制

---------- 3. 移动木板

---------- 4. 移动球(反弹效果,消除砖块)

---------- 5. 判断输赢

图片素材

游戏中基本不需要图片,只有一个背景图(你也可以纯色填充)。

背景图:

 游戏编写

预编译代码:

#include <stdio.h>
#include <graphics.h>
#define ROW 6
#define COL 8
#define WIDTH 800
#define HEIGHT 600
#define BLOCK_W 100
#define BLOCK_H 25

第一步:初始化砖块

我们需要定义一个二维数组表示这些砖块。

int canvas[ROW][COL] = { 0 };

然后给它们用随机数初始化颜色,分别用 0 1 2 3 表示 空 蓝 黄 绿。

COLORREF colors[] = {BLACK, LIGHTBLUE, YELLOW, GREEN};

// 初始化砖块
void SetBlock()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			canvas[i][j] = rand() % 3 + 1;
		}
	}
}

第二步:绘制

遍历二维数组,挨个画长方形就行。

// 绘制窗口
void Draw()
{
	cleardevice();
	loadimage(&bk_img, ".\\Background.png", WIDTH, HEIGHT, true);
	putimage(0, 0, &bk_img);
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (canvas[i][j] == 0) continue;
			setfillcolor(colors[canvas[i][j]]);
			setlinecolor(BLACK);
			setlinestyle(NULL, 1);
			fillrectangle(j * BLOCK_W, i * BLOCK_H, (j + 1) * BLOCK_W, (i + 1) * BLOCK_H);
		}
	}
}

第三步:移动木板

定义木板结构体,并用异步按键实现接受用户输入。

// 木板结构体
struct Paddle
{
	int x;
	int y;
	int w;
	int h;
	int speed;
	COLORREF color;
};
Paddle paddle = { 300, 570, 200, 25, 10, RGB(220, 255, 255) };

// 移动木板
void MovePaddle()
{
	if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT))
	{
		paddle.x -= paddle.speed;
	}
	if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT))
	{
		paddle.x += paddle.speed;
	}
	if (paddle.x <= 0) paddle.x = 0;
	if (paddle.x + paddle.w >= WIDTH) paddle.x = WIDTH - paddle.w;
}

Draw 函数中加入画木板的代码:

setfillcolor(paddle.color);
solidrectangle(paddle.x, paddle.y, paddle.x + paddle.w, paddle.y + paddle.h);

第四步:移动球

反正就是弹来弹去,很简单:

struct Ball
{
	int x;
	int y;
	int r;
	int dx;
	int dy;
	COLORREF color;
};
Ball ball = { rand() % 200 + 300, rand() % 200 + 200, 15, 8, -8, RED};

// 移动球
void MoveBall()
{
	// 碰撞反弹
	if (ball.x - ball.r <= 0 || ball.x + ball.r >= WIDTH)
	{
		ball.dx = -ball.dx;
	}
	if (ball.y - ball.r <= 0)
	{
		ball.dy = -ball.dy;
	}
	if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.w)
	{
		if (ball.y + ball.r >= paddle.y)
		{
			ball.dy = -ball.dy;
		}
	}
	ball.x += ball.dx;
	ball.y += ball.dy;
	// 撞击砖块
	int i = (ball.y - ball.r) / BLOCK_H;
	int j = ball.x / BLOCK_W;
	if (i < ROW && j < COL && canvas[i][j] != 0)
	{
		canvas[i][j] = 0;
		ball.dy = -ball.dy;
	}
}

Draw 函数中加入绘制球的代码。

setfillcolor(ball.color);
solidcircle(ball.x, ball.y, ball.r);

第五步:判断输赢

赢:二维数组全部为 0;  输:球的 y 坐标大于窗口高度。

void JudgeWin()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (canvas[i][j] != 0) return;
		}
	}
	MessageBox(GetHWnd(), "你赢了!", "结果", MB_OK | MB_ICONINFORMATION);
	closegraph();
	exit(0);
}

void JudgeLose()
{
	if (ball.y - ball.r > HEIGHT)
	{
		MessageBox(GetHWnd(), "你输了!", "结果", MB_OK | MB_ICONINFORMATION);
		closegraph();
		exit(0);
	}
}

main 函数

int main()
{
	// 初始化窗口
	initgraph(WIDTH, HEIGHT);
	SetBlock();
	BeginBatchDraw();
	while (true)
	{
		Draw();
		MovePaddle();
		MoveBall();
		JudgeWin();
		JudgeLose();
		FlushBatchDraw();
	}
	EndBatchDraw();
	return 0;
}

效果预览

完整代码 

/********************************
* 项目名称:打砖块
* 开发环境:vs2022 + easyx
* 作者:轩
* 代码长度:170
* 完成时间:2022.12.30
* 用时:1.8 小时
********************************/

#include <stdio.h>
#include <graphics.h>
#include <time.h>
#define ROW 6
#define COL 8
#define WIDTH 800
#define HEIGHT 600
#define BLOCK_W 100
#define BLOCK_H 25

// 木板结构体
struct Paddle
{
	int x;
	int y;
	int w;
	int h;
	int speed;
	COLORREF color;
};
Paddle paddle = { 300, 570, 200, 25, 10, RGB(220, 255, 255) };

struct Ball
{
	int x;
	int y;
	int r;
	int dx;
	int dy;
	COLORREF color;
};
Ball ball = { rand() % 200 + 300, rand() % 200 + 200, 15, 8, -8, RED};

IMAGE bk_img;

int canvas[ROW][COL] = { 0 };
COLORREF colors[] = {BLACK, LIGHTBLUE, YELLOW, GREEN};

// 初始化砖块
void SetBlock()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			canvas[i][j] = rand() % 3 + 1;
		}
	}
}

// 绘制窗口
void Draw()
{
	cleardevice();
	loadimage(&bk_img, ".\\Background.png", WIDTH, HEIGHT, true);
	putimage(0, 0, &bk_img);
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (canvas[i][j] == 0) continue;
			setfillcolor(colors[canvas[i][j]]);
			setlinecolor(BLACK);
			setlinestyle(NULL, 1);
			fillrectangle(j * BLOCK_W, i * BLOCK_H, (j + 1) * BLOCK_W, (i + 1) * BLOCK_H);
		}
	}
	setfillcolor(paddle.color);
	solidrectangle(paddle.x, paddle.y, paddle.x + paddle.w, paddle.y + paddle.h);
	setfillcolor(ball.color);
	solidcircle(ball.x, ball.y, ball.r);
}

// 移动木板
void MovePaddle()
{
	if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT))
	{
		paddle.x -= paddle.speed;
	}
	if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT))
	{
		paddle.x += paddle.speed;
	}
	if (paddle.x <= 0) paddle.x = 0;
	if (paddle.x + paddle.w >= WIDTH) paddle.x = WIDTH - paddle.w;
}

// 移动球
void MoveBall()
{
	// 碰撞反弹
	if (ball.x - ball.r <= 0 || ball.x + ball.r >= WIDTH)
	{
		ball.dx = -ball.dx;
	}
	if (ball.y - ball.r <= 0)
	{
		ball.dy = -ball.dy;
	}
	if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.w)
	{
		if (ball.y + ball.r >= paddle.y)
		{
			ball.dy = -ball.dy;
		}
	}
	ball.x += ball.dx;
	ball.y += ball.dy;
	// 撞击砖块
	int i = (ball.y - ball.r) / BLOCK_H;
	int j = ball.x / BLOCK_W;
	if (i < ROW && j < COL && canvas[i][j] != 0)
	{
		canvas[i][j] = 0;
		ball.dy = -ball.dy;
	}
}

void JudgeWin()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (canvas[i][j] != 0) return;
		}
	}
	MessageBox(GetHWnd(), "你赢了!", "结果", MB_OK | MB_ICONINFORMATION);
	closegraph();
	exit(0);
}

void JudgeLose()
{
	if (ball.y - ball.r > HEIGHT)
	{
		MessageBox(GetHWnd(), "你输了!", "结果", MB_OK | MB_ICONINFORMATION);
		closegraph();
		exit(0);
	}
}

int main()
{
	// 初始化窗口
	initgraph(WIDTH, HEIGHT);
	SetBlock();
	BeginBatchDraw();
	while (true)
	{
		Draw();
		MovePaddle();
		MoveBall();
		JudgeWin();
		JudgeLose();
		FlushBatchDraw();
	}
	EndBatchDraw();
	return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值