一、引言
核心功能:图形界面、点击消除、胜负判断
开发工具:VS2019 + EasyX图形库
二、核心代码解析
初始化部分
此部分定义了游戏窗口大小、图形尺寸、行列数等常量,声明了游戏所需的图像变量和函数,为游戏搭建基本框架。
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<time.h>
#include<graphics.h>
#define WIDTH 600 //图形页面的行
#define HEIGHT 800 //图形界面的列
#define BLOCKSIZE 100 //小方格大小
#define ROW 4 //底层二维数组的行
#define COL 6 //底层二维数组的列
#define CLOTHESSIZE 6 //衣服部件数量
#define CORTOON 14 //动画图片数量
int blocks[ROW][COL]; //衣服部件对应的底层数组
IMAGE clothes[CLOTHESSIZE]; //衣服部件数组
IMAGE nn[CORTOON]; //动画图片数组
IMAGE bkimg1, bkimg2;
void SetBlocks();
void MyPutImages();
void Click();
void Check();
主函数逻辑
主函数中,首先初始化图形界面,加载背景图片并显示初始界面。通过循环检测鼠标点击,当点击“开始游戏”区域时,切换背景图片。接着初始化二维数组数据,将数据映射到图形界面,处理鼠标点击事件,最后检查游戏是否结束。
int main() {
initgraph(WIDTH, HEIGHT);
//1.初始界面图片
loadimage(&bkimg1, "bg1.jpg", WIDTH, HEIGHT, true); //加载第一幅图
loadimage(&bkimg2, "bg1.png", WIDTH, HEIGHT, true); //加载第二幅图
putimage(0,0,&bkimg1); //显示第一幅图
settextcolor(MAGENTA);
settextstyle(60, 40, "楷体");
setbkcolor(WHITE);
outtextxy(140, 500, "开始游戏");
char path[20];
for (int i = 0;i < CLOTHESSIZE;i++) {
sprintf(path, "lin/clothes%d.png", i + 1); //重定向
loadimage(&clothes[i], path, BLOCKSIZE - 10, BLOCKSIZE - 10, true);
memset(path, 0, 15); //清理path
}
//2.点击开始,页面跳转
MOUSEMSG msg;
while (1) {
msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN&&msg.x>=140&&msg.x<=450
&&msg.y>=500&&msg.y<=560) {
//printf("x=%d y=%d\n", msg.x, msg.y); //测像素
putimage(0, 0, &bkimg2); //显示第二幅图
//加音乐
break;
}
}
//3.初始化二维数组数据(随机1~6,偶数个)
SetBlocks();
//打印底层数据
for (int i = 0;i < ROW;i++) {
for (int j = 0;j < COL;j++) {
printf("%-5d", blocks[i][j]);
}
printf("\n");
}
//4.二维数组数据 映射到图形界面窗口
MyPutImages();
//5.鼠标点击 第一次点击第二次消 统计分数
Click();
//6.图片消除完成 游戏结束
Check();
system("pause");
closegraph();
return 0;
}
游戏逻辑函数
SetBlocks
函数随机生成数字填充二维数组。
MyPutImages
函数根据二维数组中的值,将对应的小图片绘制到图形界面上。
Click
函数处理鼠标点击事件,连续两次点击到不同位置且相同的图片消除。
Check
函数检查游戏是否结束。
//初始化二维数组
void SetBlocks() {
//保证数据是偶数
srand((unsigned int)time(NULL));
for (int i = 0;i < ROW/2;i++) {
for (int j = 0;j < COL;j++) {
blocks[i][j] = rand() % 6 + 1;//[1,6]
}
}
for (int i = ROW/2;i < ROW;i++) {
for (int j = 0;j < COL;j++) {
blocks[i][j] = blocks[i-ROW/2][j];
}
}
int i1, i2, j1, j2;
//打乱数据 控制打乱次数
for (int i = 0;i < ROW / 2;i++) {
for (int j = 0;j < COL;j++) {
i1 = rand() % ROW;
j1 = rand() % COL;
i2 = rand() % ROW;
j2 = rand() % COL;
int temp = blocks[i1][j1];
blocks[i1][j1] = blocks[i2][j2];
blocks[i2][j2] = temp;
}
}
}
//根据二维数组数据 映射图片
void MyPutImages() {
//衣服部件图片 加载到内存
for (int i = 0;i < ROW;i++) {
for (int j = 0;j < COL;j++) {
if (blocks[i][j] !=0) {
putimage(0 + 100 * j, 180 + 100 * i, &clothes[blocks[i][j] - 1]); //显示二维数组对应的图片
}
}
}
}
//两次点击的图片一样 消除
void Click() {
int count = 0;
int i1, i2, j1, j2; //点击的行列坐标
MOUSEMSG msg;
while (1) {
msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN && msg.x >= 0 && msg.x <= WIDTH
&& msg.y >= 180 && msg.y <= 580) {
count++;
if (count == 1) {
i1 = (msg.y - 180) / 100;
j1 = msg.x / 100;
}
else if (count == 2) {
i2 = (msg.y - 180) / 100;
j2 = msg.x / 100;
if (i1 == i2 && j1 == j2) { //原地点击不消除
continue;
}
if (blocks[i1][j1] == blocks[i2][j2]) { //消除
blocks[i1][j1] = blocks[i2][j2]=0;
putimage(0, 0, &bkimg2);
MyPutImages();
}
count = 0;
}
}
if (msg.uMsg == WM_RBUTTONDOWN) {
break;
}
}
}
//检查是否消完 消完播放动画
void Check() {
int flag = 1;
for (int i = 0;i < ROW;i++) {
for (int j = 0;j < COL;j++) {
if (blocks[i][j] != 0)
flag=0;
}
}
if (flag) {
//图片加载到内存上
char path[20];
for (int i = 0;i < CORTOON;i++) {
sprintf(path, "sn/nn%d.jpg", i + 1); //重定向
loadimage(&nn[i], path, WIDTH, HEIGHT, true);
memset(path, 0, 15); //清理path
}
//快速显示图片形成动画
for (int i = 0; i < CORTOON; i++) {
putimage(0, 0, &nn[i]); // 在坐标(0, 0)处显示图片
Sleep(200); // 控制动画速度,单位为毫秒
}
}
}
三、 扩展建议
- 增加计分系统
- 添加音效反馈
- 实现关卡进度保存
四、总结
通过这200行左右的代码,初步实现了消消乐游戏的基本框架,包括界面初始化、资源加载、游戏数据初始化、图形映射以及简单的交互逻辑。后续可进一步完善,增加游戏音效、优化界面等,丰富游戏功能。