开发环境:Visual Studio 2019,easyx图形库

easyx下载官网:EasyX Graphics Library for C++https://easyx.cn/

easyx使用文档:

EasyX 文档 - 函数说明https://docs.easyx.cn/zh-cn/reference游戏功能列表:

其主要功能描述如下:

1.图片尺寸自适应

2.图片动态分割

3.查看原图

4.随机切换图片

5.交换拼图块

6.自动判断拼图成功

拓展功能:

  1. 背景音乐(开,关)
  2. 游戏中Esc键返回桌面
  3. 游戏规则窗口

游戏效果

封面(音乐按钮有点拉跨~)

游戏初始图(我的心是冰冰的)

 通关图

一.头文件和基本量


#include<conio.h>
#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<Windows.h>
#include<mmsystem.h>    //音乐
#pragma comment(lib,"Winmm.lib")    //静态库,调用音乐
using namespace std;
constexpr auto N = 3;    //3*3拼图
IMAGE img[4], imgs[9];     //img存整张图片,imgs暂存拼图块
int aim_c, aim_r;          //拼图块坐标
int map[3][3] = { 0 };     //存拼图块
int NUM = 0;          //关卡数计数

二.封面

//开始界面
void start()
{loadimage(NULL, L"cover.jpg");setbkmode(TRANSPARENT);settextcolor(BLACK);settextstyle(60, 0, _T("楷体"),0,0,4,false,false,false);outtextxy(180, 120, L"拼图游戏");                    //游戏名称settextstyle(30, 0, _T("微软雅黑"));setfillcolor(BROWN);setlinestyle(BS_SOLID, 5);setlinecolor(RED);fillroundrect(220, 220, 370, 270, 10, 10);settextstyle(30, 0, _T("宋体"), 0, 0, 6, false, false, false);  //开始按钮outtextxy(270, 230, L"开始");fillroundrect(220, 300, 370, 350, 10, 10);outtextxy(240, 310, L"游戏规则");setfillcolor(BROWN);setlinestyle(BS_SOLID, 5);setlinecolor(BLACK);fillcircle(490, 440, 30);  //音乐控制按钮:开fillcircle(560, 440, 30);  //音乐控制按钮:关outtextxy(380, 430, L"音乐:");setfillcolor(BLACK);POINT pts[] = { {481,425},{481,455},{507,440} };fillpolygon(pts, 3);fillrectangle(546, 425, 554, 455);fillrectangle(566, 425, 574, 455);rules();
}

三.数据初始化

//游戏初始化
void init()
{//加载资源图片,4张图4个关卡loadimage(&img[0], L"picture1.jpg",  600, 600);loadimage(&img[1], L"picture2.jpg", 600, 600);loadimage(&img[2], L"picture3.jpg", 600, 600);loadimage(&img[3], L"picture4.jpg", 600, 600);//设置最后一张图片为空白图片,作为目标图片loadimage(&imgs[8], L"white.jpg", 200, 200);//设置随机种子srand((unsigned)time(NULL));
}

四.封面规则按钮

//封面规则函数
int rules()
{ExMessage Mou;    //鼠标消息while (1){Mou = getmessage(EM_MOUSE);switch (Mou.message)    //对鼠标信息进行匹配{case WM_LBUTTONDOWN:            //按下左键if (Mou.x >= 220 && Mou.x <= 370 && Mou.y >= 300 && Mou.y <= 350){HWND hwnd = GetHWnd();MessageBox(NULL, L"1.鼠标左键点击空白图处周围图片交换位置\n2.鼠标右键任意处按下显示参照图片\n3.鼠标中键更换背景图片\n4.按Esc键返回封面", L"游戏规则", MB_OKCANCEL);break;                     //规则按钮}if (Mou.x >= 220 && Mou.x <= 370 && Mou.y >= 220 && Mou.y <= 270){return 0;                  //开始按钮}if (Mou.x >= 460 && Mou.x <= 520 && Mou.y >= 410 && Mou.y <= 470){BGM();                     //音乐播放按钮break;}if (Mou.x >= 530 && Mou.x <= 590 && Mou.y >= 410 && Mou.y <= 470){mciSendString(L"close back", 0, 0, 0);     //音乐关闭按钮break;}}}}

五.构造拼图

//拼图构造函数
void GameInit()
{//把拼图贴上去putimage(0, 0, &img[NUM]);//设置绘图目标为img对象   对拼图图片进行切割SetWorkingImage(&img[NUM]);for (int y = 0, n = 0; y < N; y++){for (int x = 0; x < N; x++){if (n == 8)   break;//获取100*100像素图片,存储在img中;getimage(&imgs[n++], x * 200, y * 200, (x + 1) * 200, (y + 1) * 200);}}//设置绘图目标为绘图窗口SetWorkingImage();//初始化地图0~15for (int i = 0, k = 0; i < N; i++){for (int j = 0; j < N; j++){map[i][j] = k++;}}//打乱地图for (int k = 0; k <= 1000; k++){//得到目标所在的行和列for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (map[i][j] == 8)  //空白图片作为交换目标{aim_r = i;aim_c = j;break;}}}//一千次打乱顺序之后需要将空白图片转移到右下角//可以封装成函数下面这个代码if (k == 1000){//将空白图片循环转移到右下角while (aim_r < 2){//保证空白目标在最下map[aim_r][aim_c] = map[aim_r + 1][aim_c];map[aim_r + 1][aim_c] = 8;aim_r++;}while (aim_c < 2){//保证空白目标在最右map[aim_r][aim_c] = map[aim_r][aim_c + 1];map[aim_r][aim_c + 1] = 8;aim_c++;}return;}int dir = rand() % 4;   //随机一个方向switch (dir){case 0:  //向上交换if (aim_r >= 1){//空白图片和空白处上面的图片交换map[aim_r][aim_c] = map[aim_r - 1][aim_c];map[aim_r - 1][aim_c] = 8;break;}case 1:  //向下交换if (aim_r < 2){//空白图片和空白处下面的图片交换map[aim_r][aim_c] = map[aim_r + 1][aim_c];map[aim_r + 1][aim_c] = 8;break;}case 2:  //向左交换if (aim_c >= 1){//空白图片和空白处左边的图片交换map[aim_r][aim_c] = map[aim_r][aim_c - 1];map[aim_r][aim_c - 1] = 8;break;}case 3:  //向右交换if (aim_c < 2){//空白图片和空白处右边的图片交换 map[aim_r][aim_c] = map[aim_r][aim_c + 1];map[aim_r][aim_c + 1] = 8;break;}}}
}

六.绘图函数

//绘图函数
void DrawMap()
{FlushBatchDraw();  //开始渲染图片for (int y = 0; y < N; y++){for (int x = 0; x < N; x++){putimage(x * 200, y * 200, &imgs[map[y][x]]);}}EndBatchDraw();
}

七.背景音乐

//背景音乐函数
void BGM()
{//打开音乐,播放音乐mciSendStringW(L"open ./Thrills.mp3 alias back", NULL, 0, NULL);mciSendStringW(_T("play back repeat"), 0, 0, 0);
}

八.数据更新

//数据更新函数
void play()
{int col, row;  //鼠标点击的位置ExMessage msg;    //鼠标消息msg = getmessage(EM_MOUSE|EM_KEY);   //获取鼠标消息switch (msg.message)      //对鼠标消息进行匹配{case WM_LBUTTONDOWN:  //当鼠标消息是左键按下时//获取鼠标按下所在列col = msg.x / 200;if (msg.x == 600)col = 2;//获取鼠标按下所在行row = msg.y / 200;if (msg.y == 600)row = 2;//得到目标所在行和列for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (map[i][j] == 8)    //空白处为交换目标{aim_r = i;aim_c = j;}}}//判断鼠标点击位置和目标是否相邻,相邻交换数据if (row == aim_r && col == aim_c + 1 ||row == aim_r && col == aim_c - 1 ||row == aim_r + 1 && col == aim_c ||row == aim_r - 1 && col == aim_c){//鼠标点击图片和空白目标图片交换map[aim_r][aim_c] = map[row][col];map[row][col] = 8;}DrawMap();break;case WM_RBUTTONDOWN: //当鼠标消息是右键按下时putimage(0, 0, &img[NUM]);   //将关卡图片贴到窗口上break;case WM_RBUTTONUP:  //当鼠标消息是右键抬起时DrawMap();break;case WM_MBUTTONDOWN:NUM++;if (NUM == 4)NUM = 0;   //返回第一张图//重新开始游戏GameInit(); //游戏初始化DrawMap();  //渲染地图break;case WM_KEYDOWN:if (msg.vkcode == VK_ESCAPE)    //按Esc键返回封面{start();break;}}
}

九.通关判断

//通关判断函数
void Judge()
{//判断当前每张图片是否在对应位置if (map[0][0] == 0 && map[0][1] == 1 && map[0][2] == 2 &&map[1][0] == 3 && map[1][1] == 4 && map[1][2] == 5 &&map[2][0] == 6 && map[2][1] ==7 && map[2][2] == 8 ){//挑战成功之后将全图贴上putimage(0, 0, &img[NUM++]);//四个关卡都胜利之后退出程序if (NUM == 4){MessageBox(GetHWnd(), L"挑战成功", L"Vectory", MB_OK);exit(0);return;}//每过一个关卡判断是否进入下一个关卡if (MessageBox(GetHWnd(), L"是否进入下一关", L"Vectory", MB_YESNO) == IDYES){//重新开始游戏GameInit(); //游戏初始化DrawMap();  //渲染地图}//退出游戏else exit(0);}
}

十.完整程序

#include<conio.h>
#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<Windows.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
using namespace std;
constexpr auto N = 3;
IMAGE img[4], imgs[9];
int aim_c, aim_r;
int map[3][3] = { 0 };
int NUM = 0;
//游戏规则,开始界面设计
void start();//封面按钮
int rules();//加载资源
void init();//游戏数据初始化
void GameInit();//游戏渲染
void DrawMap();//播放音乐
void BGM();//玩家操作
void play();//判断输赢
void Judge();int main()
{//设置窗口大小initgraph(6 * 100, 6 * 100);//设置图片start();init();GameInit();DrawMap();while (1){play();Judge();}system("pause");//等待用户按键closegraph();return 0;
}
//开始界面
void start()
{loadimage(NULL, L"cover.jpg");setbkmode(TRANSPARENT);settextcolor(BLACK);settextstyle(60, 0, _T("楷体"),0,0,4,false,false,false);outtextxy(180, 120, L"拼图游戏");                    //游戏名称settextstyle(30, 0, _T("微软雅黑"));setfillcolor(BROWN);setlinestyle(BS_SOLID, 5);setlinecolor(RED);fillroundrect(220, 220, 370, 270, 10, 10);settextstyle(30, 0, _T("宋体"), 0, 0, 6, false, false, false);  //开始按钮outtextxy(270, 230, L"开始");fillroundrect(220, 300, 370, 350, 10, 10);outtextxy(240, 310, L"游戏规则");setfillcolor(BROWN);setlinestyle(BS_SOLID, 5);setlinecolor(BLACK);fillcircle(490, 440, 30);  //音乐控制按钮:开fillcircle(560, 440, 30);  //音乐控制按钮:关outtextxy(380, 430, L"音乐:");setfillcolor(BLACK);POINT pts[] = { {481,425},{481,455},{507,440} };fillpolygon(pts, 3);fillrectangle(546, 425, 554, 455);fillrectangle(566, 425, 574, 455);rules();
}
//游戏初始化
void init()
{//加载资源图片,4张图4个关卡loadimage(&img[0], L"picture1.jpg",  600, 600);loadimage(&img[1], L"picture2.jpg", 600, 600);loadimage(&img[2], L"picture3.jpg", 600, 600);loadimage(&img[3], L"picture4.jpg", 600, 600);//设置最后一张图片为空白图片,作为目标图片loadimage(&imgs[8], L"white.jpg", 200, 200);//设置随机种子srand((unsigned)time(NULL));
}
//封面选项函数
int rules()
{ExMessage Mou;    //鼠标消息while (1){Mou = getmessage(EM_MOUSE);switch (Mou.message)    //对鼠标信息进行匹配{case WM_LBUTTONDOWN:            //按下左键if (Mou.x >= 220 && Mou.x <= 370 && Mou.y >= 300 && Mou.y <= 350){HWND hwnd = GetHWnd();MessageBox(NULL, L"1.鼠标左键点击空白图处周围图片交换位置\n2.鼠标右键任意处按下显示参照图片\n3.鼠标中键更换背景图片\n4.按Esc键返回封面", L"游戏规则", MB_OKCANCEL);break;                     //规则按钮}if (Mou.x >= 220 && Mou.x <= 370 && Mou.y >= 220 && Mou.y <= 270){return 0;                  //开始按钮}if (Mou.x >= 460 && Mou.x <= 520 && Mou.y >= 410 && Mou.y <= 470){BGM();                     //音乐播放按钮break;}if (Mou.x >= 530 && Mou.x <= 590 && Mou.y >= 410 && Mou.y <= 470){mciSendString(L"close back", 0, 0, 0);     //音乐关闭按钮break;}}}}
//拼图构造函数
void GameInit()
{//把拼图贴上去putimage(0, 0, &img[NUM]);//设置绘图目标为img对象   对拼图图片进行切割SetWorkingImage(&img[NUM]);for (int y = 0, n = 0; y < N; y++){for (int x = 0; x < N; x++){if (n == 8)   break;//获取100*100像素图片,存储在img中;getimage(&imgs[n++], x * 200, y * 200, (x + 1) * 200, (y + 1) * 200);}}//设置绘图目标为绘图窗口SetWorkingImage();//初始化地图0~15for (int i = 0, k = 0; i < N; i++){for (int j = 0; j < N; j++){map[i][j] = k++;}}//打乱地图for (int k = 0; k <= 1000; k++){//得到目标所在的行和列for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (map[i][j] == 8)  //空白图片作为交换目标{aim_r = i;aim_c = j;break;}}}//一千次打乱顺序之后需要将空白图片转移到右下角//可以封装成函数下面这个代码if (k == 1000){//将空白图片循环转移到右下角while (aim_r < 2){//保证空白目标在最下map[aim_r][aim_c] = map[aim_r + 1][aim_c];map[aim_r + 1][aim_c] = 8;aim_r++;}while (aim_c < 2){//保证空白目标在最右map[aim_r][aim_c] = map[aim_r][aim_c + 1];map[aim_r][aim_c + 1] = 8;aim_c++;}return;}int dir = rand() % 4;   //随机一个方向switch (dir){case 0:  //向上交换if (aim_r >= 1){//空白图片和空白处上面的图片交换map[aim_r][aim_c] = map[aim_r - 1][aim_c];map[aim_r - 1][aim_c] = 8;break;}case 1:  //向下交换if (aim_r < 2){//空白图片和空白处下面的图片交换map[aim_r][aim_c] = map[aim_r + 1][aim_c];map[aim_r + 1][aim_c] = 8;break;}case 2:  //向左交换if (aim_c >= 1){//空白图片和空白处左边的图片交换map[aim_r][aim_c] = map[aim_r][aim_c - 1];map[aim_r][aim_c - 1] = 8;break;}case 3:  //向右交换if (aim_c < 2){//空白图片和空白处右边的图片交换 map[aim_r][aim_c] = map[aim_r][aim_c + 1];map[aim_r][aim_c + 1] = 8;break;}}}
}
//绘图函数
void DrawMap()
{FlushBatchDraw();  //开始渲染图片for (int y = 0; y < N; y++){for (int x = 0; x < N; x++){putimage(x * 200, y * 200, &imgs[map[y][x]]);}}EndBatchDraw();
}
//背景音乐函数
void BGM()
{//打开音乐,播放音乐mciSendStringW(L"open ./Thrills.mp3 alias back", NULL, 0, NULL);mciSendStringW(_T("play back repeat"), 0, 0, 0);
}
//数据更新函数
void play()
{int col, row;  //鼠标点击的位置ExMessage msg;    //鼠标消息msg = getmessage(EM_MOUSE|EM_KEY);   //获取鼠标消息switch (msg.message)      //对鼠标消息进行匹配{case WM_LBUTTONDOWN:  //当鼠标消息是左键按下时//获取鼠标按下所在列col = msg.x / 200;if (msg.x == 600)col = 2;//获取鼠标按下所在行row = msg.y / 200;if (msg.y == 600)row = 2;//得到目标所在行和列for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){if (map[i][j] == 8)    //空白处为交换目标{aim_r = i;aim_c = j;}}}//判断鼠标点击位置和目标是否相邻,相邻交换数据if (row == aim_r && col == aim_c + 1 ||row == aim_r && col == aim_c - 1 ||row == aim_r + 1 && col == aim_c ||row == aim_r - 1 && col == aim_c){//鼠标点击图片和空白目标图片交换map[aim_r][aim_c] = map[row][col];map[row][col] = 8;}DrawMap();break;case WM_RBUTTONDOWN: //当鼠标消息是右键按下时putimage(0, 0, &img[NUM]);   //将关卡图片贴到窗口上break;case WM_RBUTTONUP:  //当鼠标消息是右键抬起时DrawMap();break;case WM_MBUTTONDOWN:NUM++;if (NUM == 4)NUM = 0;   //返回第一张图//重新开始游戏GameInit(); //游戏初始化DrawMap();  //渲染地图break;case WM_KEYDOWN:if (msg.vkcode == VK_ESCAPE)    //按Esc键返回封面{start();break;}}
}
//通关判断函数
void Judge()
{//判断当前每张图片是否在对应位置if (map[0][0] == 0 && map[0][1] == 1 && map[0][2] == 2 &&map[1][0] == 3 && map[1][1] == 4 && map[1][2] == 5 &&map[2][0] == 6 && map[2][1] ==7 && map[2][2] == 8 ){//挑战成功之后将全图贴上putimage(0, 0, &img[NUM++]);//四个关卡都胜利之后退出程序if (NUM == 4){MessageBox(GetHWnd(), L"挑战成功", L"Vectory", MB_OK);exit(0);return;}//每过一个关卡判断是否进入下一个关卡if (MessageBox(GetHWnd(), L"是否进入下一关", L"Vectory", MB_YESNO) == IDYES){//重新开始游戏GameInit(); //游戏初始化DrawMap();  //渲染地图}//退出游戏else exit(0);}
}

注:游戏主体代码来自微信公众号:编程学习基地

拼图游戏--C++语言实现相关推荐

  1. C语言数组制作拼图游戏,C语言自制拼图游戏.doc

    C语言自制拼图游戏 C语言~~自制-拼图游戏 原帖及讨论:/thread-233257-1-1.html //编译环境VC++6.0. 程序和资源一共15M. 来自 //需要的留个EMAIL.... ...

  2. 拼图游戏C语言课设实验报告,C语言拼图游戏实验报告.doc

    C语言拼图游戏实验报告 课程设计实验报告 班级:光电104-2 姓名:刘云龙 学号:201058501220 一.实验题目:使用C语言编写一个小游戏(拼图游戏) 二.实验目的:C语言是每一个通信学生的 ...

  3. c语言课程设计--拼图游戏,C语言课程设计_拼图游戏.pdf

    C -- 语言课程设计 拼图游戏 一.实验内容 玩家通过鼠标单击相邻位有空位的方块来移动方块,从而最终将一副散乱的图片拼成完 整的图片.要求如下: 1. 游戏的初始界面如图一,单击空格键进入游戏,进入 ...

  4. 拼图游戏c语言简单,(C语言拼图游戏.doc

    (C语言拼图游戏 (郑重声明:本文绝对本人原创,盗版必究) (免费提供给爱好C语言的朋友,希望志同道合的朋友们一起加油!) (运行环境Turbo C,下载的朋友把图形驱动路径改为自己驱动实际路径即可) ...

  5. funcode拼图游戏c语言程序,同求funcode平台下拼图游戏的C语言代码

    做了好几天,写了好多回就是不对,彻底崩溃.. #include "CommonAPI.h" //#include "LessonX.h" #include #d ...

  6. 【原创-更新完毕】|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载2

    [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载1_zhuyi8120的博客-CSDN博客 [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载3_zhuyi8120的博客-C ...

  7. C语言开发的拼图游戏

    C语言开发的拼图游戏 项目效果 话不多是直接干货 引用的头文件 菜单栏 主界面 加载图片 画图片 游戏代码 我的B站链接:[B站链接](https://space.bilibili.com/27474 ...

  8. C语言项目实战:《拼图游戏》零基础项目

    这篇文章主要为大家详细介绍了C语言实现--<拼图游戏项目>,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下! 网图 游戏介绍: 对刚开始接触拼图的玩家而言,所 ...

  9. 【原创-更新完毕】|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载1

    [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载2_zhuyi8120的博客-CSDN博客 [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载3_zhuyi8120的博客-C ...

最新文章

  1. 关于网页js判断“客户端设备类型是移动端还是PC端“的解决方法?
  2. PHP面向对象构造函数,析构函数
  3. React Native 开发豆瓣评分(五)屏幕适配方案
  4. oracle导出数据带where,CSS_指定一个where条件来有条件地导出记录,在Oracle数据库中,exp中的query - phpStudy...
  5. (Origin)设置图例位置
  6. python系统学习:第二周之字典应用
  7. 图论及其应用 2018年期末考试 答案总结
  8. 以未来式计算机为题目的作文,未来式科技想象作文
  9. 利用matlab命令画出以下信号的波形,大连理工大学 信号与系统实验三报告
  10. JavaSwing实现简单连连看小游戏
  11. NX/UG二次开发—CAM—获取、修改程式的切削参数
  12. 爬虫--爬取人人网案列(一)
  13. 有感于李连杰壹基金计划
  14. package.json browserslist
  15. 商人渡模型matlab及模型假设,商人过河问题
  16. SpringAOP中@within和@annotation的区别
  17. Netbackup for sap 7.0学习之七:使用nbu进行sap系统的灾难恢复测试
  18. 心中无码:这是一个能自动脑补漫画空缺部分的AI项目
  19. C++ map遍历的几种方式
  20. 脏话一览,骂人可够狠的

热门文章

  1. knn算法python代码_KNN算法原理(python代码实现)
  2. 学python可以做什么职业-转行学python后,从事自由职业,分享下月入10000+的经验...
  3. nn.moduleList 和Sequential的理解
  4. 扩展自定义mq组件,使用rabbitmq_delayed_message_exchange延迟组件,完善消息延迟消息精度问题
  5. 高级MyBatis -- resultMap实现联表(一对多,多对一)
  6. 努比亚红魔7pro评测怎么样
  7. Swoole加速结巴分词
  8. 【python】通过loging模块将日志写入mysql数据库
  9. 数据挖掘——预测未来销售
  10. 卡在正在连接服务器,地下城与勇士DNF比赛服登陆时卡在“正在连接服务器”的黑屏界面中的解决方法...