目录
游戏简介
打砖块游戏是一个常见的经典小游戏,很常见的欸!
代码编写步骤:
---------- 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;
}