拼图游戏--C++语言实现
开发环境: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.自动判断拼图成功
拓展功能:
- 背景音乐(开,关)
- 游戏中Esc键返回桌面
- 游戏规则窗口
游戏效果
封面(音乐按钮有点拉跨~)
游戏初始图(我的心是冰冰的)
通关图
一.头文件和基本量
#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++语言实现相关推荐
- C语言数组制作拼图游戏,C语言自制拼图游戏.doc
C语言自制拼图游戏 C语言~~自制-拼图游戏 原帖及讨论:/thread-233257-1-1.html //编译环境VC++6.0. 程序和资源一共15M. 来自 //需要的留个EMAIL.... ...
- 拼图游戏C语言课设实验报告,C语言拼图游戏实验报告.doc
C语言拼图游戏实验报告 课程设计实验报告 班级:光电104-2 姓名:刘云龙 学号:201058501220 一.实验题目:使用C语言编写一个小游戏(拼图游戏) 二.实验目的:C语言是每一个通信学生的 ...
- c语言课程设计--拼图游戏,C语言课程设计_拼图游戏.pdf
C -- 语言课程设计 拼图游戏 一.实验内容 玩家通过鼠标单击相邻位有空位的方块来移动方块,从而最终将一副散乱的图片拼成完 整的图片.要求如下: 1. 游戏的初始界面如图一,单击空格键进入游戏,进入 ...
- 拼图游戏c语言简单,(C语言拼图游戏.doc
(C语言拼图游戏 (郑重声明:本文绝对本人原创,盗版必究) (免费提供给爱好C语言的朋友,希望志同道合的朋友们一起加油!) (运行环境Turbo C,下载的朋友把图形驱动路径改为自己驱动实际路径即可) ...
- funcode拼图游戏c语言程序,同求funcode平台下拼图游戏的C语言代码
做了好几天,写了好多回就是不对,彻底崩溃.. #include "CommonAPI.h" //#include "LessonX.h" #include #d ...
- 【原创-更新完毕】|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载2
[原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载1_zhuyi8120的博客-CSDN博客 [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载3_zhuyi8120的博客-C ...
- C语言开发的拼图游戏
C语言开发的拼图游戏 项目效果 话不多是直接干货 引用的头文件 菜单栏 主界面 加载图片 画图片 游戏代码 我的B站链接:[B站链接](https://space.bilibili.com/27474 ...
- C语言项目实战:《拼图游戏》零基础项目
这篇文章主要为大家详细介绍了C语言实现--<拼图游戏项目>,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下! 网图 游戏介绍: 对刚开始接触拼图的玩家而言,所 ...
- 【原创-更新完毕】|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载1
[原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载2_zhuyi8120的博客-CSDN博客 [原创]|日历拼图游戏的解决方案(C语言-进阶应用)-详解连载3_zhuyi8120的博客-C ...
最新文章
- 关于网页js判断“客户端设备类型是移动端还是PC端“的解决方法?
- PHP面向对象构造函数,析构函数
- React Native 开发豆瓣评分(五)屏幕适配方案
- oracle导出数据带where,CSS_指定一个where条件来有条件地导出记录,在Oracle数据库中,exp中的query - phpStudy...
- (Origin)设置图例位置
- python系统学习:第二周之字典应用
- 图论及其应用 2018年期末考试 答案总结
- 以未来式计算机为题目的作文,未来式科技想象作文
- 利用matlab命令画出以下信号的波形,大连理工大学 信号与系统实验三报告
- JavaSwing实现简单连连看小游戏
- NX/UG二次开发—CAM—获取、修改程式的切削参数
- 爬虫--爬取人人网案列(一)
- 有感于李连杰壹基金计划
- package.json browserslist
- 商人渡模型matlab及模型假设,商人过河问题
- SpringAOP中@within和@annotation的区别
- Netbackup for sap 7.0学习之七:使用nbu进行sap系统的灾难恢复测试
- 心中无码:这是一个能自动脑补漫画空缺部分的AI项目
- C++ map遍历的几种方式
- 脏话一览,骂人可够狠的
热门文章
- knn算法python代码_KNN算法原理(python代码实现)
- 学python可以做什么职业-转行学python后,从事自由职业,分享下月入10000+的经验...
- nn.moduleList 和Sequential的理解
- 扩展自定义mq组件,使用rabbitmq_delayed_message_exchange延迟组件,完善消息延迟消息精度问题
- 高级MyBatis -- resultMap实现联表(一对多,多对一)
- 努比亚红魔7pro评测怎么样
- Swoole加速结巴分词
- 【python】通过loging模块将日志写入mysql数据库
- 数据挖掘——预测未来销售
- 卡在正在连接服务器,地下城与勇士DNF比赛服登陆时卡在“正在连接服务器”的黑屏界面中的解决方法...