C++怎么实现连连看游戏
发表于:2025-01-27 作者:千家信息网编辑
千家信息网最后更新 2025年01月27日,本篇内容主要讲解"C++怎么实现连连看游戏",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++怎么实现连连看游戏"吧!struct GridInfor
千家信息网最后更新 2025年01月27日C++怎么实现连连看游戏
本篇内容主要讲解"C++怎么实现连连看游戏",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++怎么实现连连看游戏"吧!
struct GridInfor //记入击中图片信息{ int idx,idy; //图纸坐标 int leftx,lefty; //屏幕坐标 int GridID; //图片类型}pre,cur,dur; struct //记录连线点{ int x; int y;}point[4]; static int pn; //记录连线点个数 void InitFace (); //初始化界面void Shuffle (); //随即打乱图片void ShowGrid (); //显示图片void RandGrid (); //绘制地图void Link (); //连接两图void Des_direct (); //直接相消void Des_one_corner(); //一折相消void Des_two_corner(); //两折相消void Load_picture (); //加载图片void Init_Grid (GridInfor& pre); //初始化格子信息void Leftbottondown (MOUSEMSG mouse); //实现鼠标左击效果void Draw_frame (int leftx,int lefty); //绘制边框void Mousemove (int leftx,int lefty); //实现鼠标移动效果bool Judg_val (int leftx,int lefty); //判断鼠标是否在游戏区void SeleReact (int leftx,int lefty); //显示选中效果void TranstoPhycoor (int* idx,int* idy); //图纸坐标转变为屏幕坐标void GridPhy_coor (int& leftx,int& lefty); //规范物理坐标void iPaint (long x1,long y1,long x2,long y2); //将直线销毁void DrawLine (int x1,int y1,int x2,int y2) ; //用直线连接两图bool DesGrid (GridInfor pre,GridInfor cur); //判断两者是否能相消bool Match_direct (POINT ppre,POINT pcur); //判断两者是否能够直接相消bool Match_one_corner (POINT ppre,POINT pcur); //判断两者是否能一折相消bool Match_two_corner (POINT ppre,POINT pcur); //判断两者是否能两折相消void ExchaVal (GridInfor& pre,GridInfor& cur); //交换图片信息bool Single_click_judge (int mousex,int mousey); //判断单击是否有效 void RecordInfor (int leftx,int lefty,GridInfor &grid); //记录选中的信息void TranstoDracoor (int mousex,int mousey,int *idx,int *idy); //鼠标坐标转化为图纸坐标void Explot (POINT point,int *left,int *right,int *top,int *bottel);//探索point点附近的空位置
接下来是我们随机产生图片的逻辑函数,这个要好好理解
void RandGrid() //产生图片的标记{ for(int iCount = 0, x = 1; x <= ROW; ++x ) { for( int y = 1; y <= COL; ++y ) { GridID[x][y] = iCount++ % GridNum + 1;} } } void Shuffle( ) //打乱棋盘{ int ix, iy, jx, jy, grid; for( int k = 0; k < 84; ++k ) { ix = rand() % ROW + 1; // 产生 1 - COL 的随机数 iy = rand() % COL + 1; // 产生 1 - ROW 的随机数 jx = rand() % ROW + 1; // 产生 1 - COL 的随机数 jy = rand() % COL + 1; // 产生 1 - ROW 的随机数 if( GridID[ix][iy] != GridID[jx][jy] ) //如果不相等就交换数据 { grid = GridID[ix][iy]; GridID[ix][iy] = GridID[jx][jy]; GridID[jx][jy] = grid;} } }
下面是我们的重点操作,鼠标控制函数,好好看好好学,写的时候一定要有耐心,别被bug击破了内心
void Mousemove (int leftx,int lefty) //鼠标移动时的变化{ static int prex,prey,preidx,preidy, curidx,curidy; if(Judg_val(leftx,lefty)) { TranstoDracoor(leftx,lefty,&curidx,&curidy); //转化为图纸坐标 if(GridID[curidy][curidx] != 0) { GridPhy_coor(leftx,lefty); if(pre.idx == preidx && pre.idy == preidy) putimage(prex,prey,&image[GridID[preidy][preidx]][1]); else putimage(prex,prey,&image[GridID[preidy][preidx]][0]); prex = leftx, prey = lefty; preidx = curidx, preidy = curidy; Draw_frame(leftx,lefty); //绘制边框 } } } void Leftbottondown (MOUSEMSG mouse) //左击时的变化{ static int click = 0, idx,idy; click++; SeleReact (mouse.x,mouse.y); //显示选中效果 if(click == 1) RecordInfor(mouse.x,mouse.y,pre); if(click == 2) { TranstoDracoor (mouse.x,mouse.y,&idx,&idy); if(idx != pre.idx || idy != pre.idy) { RecordInfor (mouse.x,mouse.y,cur); if(pre.GridID == cur.GridID && DesGrid(pre,cur)) { GridID[pre.idy][pre.idx] = GridID[cur.idy][cur.idx] =0; Link (); pn = 0; putimage(pre.leftx,pre.lefty,&image2); putimage(cur.leftx,cur.lefty,&image2); Init_Grid(pre); Init_Grid(cur); click = 0; } else { ExchaVal(dur,pre); ExchaVal(pre,cur); Init_Grid(cur); click = 1; putimage(dur.leftx,dur.lefty,&image[GridID[dur.idy][dur.idx]][0]); } } else click = 1; } } void SeleReact (int leftx,int lefty) //选中时效果{ if(Judg_val(leftx,lefty)) { int idx,idy; TranstoDracoor (leftx,lefty,&idx,&idy); GridPhy_coor (leftx,lefty); putimage(leftx,lefty,&image[GridID[idy][idx]][1]);} } bool Judg_val(int leftx,int lefty) //判断鼠标是否在游戏区{ return leftx > leftedge && leftx < leftedge + GridW * COL && lefty > topedge && lefty < topedge + GridH * ROW;} void TranstoDracoor (int mousex,int mousey ,int *idx,int *idy) //鼠标坐标转化为图纸坐标{ if(Judg_val(mousex,mousey)) { *idx = (mousex - leftedge) / 42 + 1; *idy = (mousey - topedge) / 48 + 1 ;} } void RecordInfor(int leftx,int lefty,GridInfor &grid) //记录选中的信息{ TranstoDracoor(leftx,lefty,&grid.idx,&grid.idy); grid.leftx = (grid.idx - 1) * 42 + leftedge; grid.lefty = (grid.idy - 1) * 48 + topedge; grid.GridID = GridID[grid.idy][grid.idx];} bool Single_click_judge (int mousex,int mousey) //判断单击是否有效{ int idx,idy; TranstoDracoor (mousex,mousey,&idx,&idy); //转化为图纸坐标 if(Judg_val(mouse.x,mouse.y) && GridID[idy][idx] != 0) return true; return false;} void Draw_frame(int leftx,int lefty) //绘制方框{ setcolor(RGB(126,91,68)); setlinestyle(PS_SOLID,NULL,1); rectangle(leftx,lefty,leftx+41,lefty+47); rectangle(leftx + 2,lefty + 2,leftx+39,lefty+45); setcolor(RGB(250,230,169)); rectangle(leftx + 1,lefty + 1,leftx+40,lefty+46); }
另外一个重点就是我们判断函数了,第一次使用鼠标点击棋盘中的棋子,该棋子此时为"被选中",以特殊方式显示;再次以鼠标点击其他棋子,若该棋子与被选中的棋子图案相同,且把第一个棋子到第二个棋子连起来,中间的直线不超过3根,则消掉这一对棋子,否则第一颗棋子恢复成未被选中状态,而第二颗棋子变成被选中状态。这个是重中之重,一定好好学,把其中的逻辑理解清楚,别只会Ctrl+c和Ctrl+v
bool DesGrid (GridInfor pre,GridInfor cur) //判断两者是否能相消{ bool match = false; POINT ppre,pcur; ppre.x = pre.idx; ppre.y = pre.idy; pcur.x = cur.idx; pcur.y = cur.idy; if(Match_direct(ppre,pcur)) match = true; else if(Match_one_corner(ppre,pcur)) match = true; else if(Match_two_corner(ppre,pcur)) match =true; return match;} bool Match_direct(POINT ppre,POINT pcur) //判断两者是否能够直接相消{ int k,t; if(ppre.x == pcur.x) { k = ppre.y > pcur.y ? ppre.y : pcur.y; t = ppre.y < pcur.y ? ppre.y : pcur.y; if(t + 1 == k) goto FIND; for(int i = t + 1;i < k ;i++) if(GridID[i][ppre.x] != 0) return false; if(i == k) goto FIND; } else if(ppre.y == pcur.y) { k = ppre.x > pcur.x ? ppre.x : pcur.x; t = ppre.x < pcur.x ? ppre.x : pcur.x; if(t + 1 == k) goto FIND; for(int i = t + 1;i < k ;i++) if(GridID[ppre.y][i] != 0) return false; if(i == k) goto FIND; } return false;FIND: point[pn].x = pcur.x, point[pn].y = pcur.y; pn++; point[pn].x = ppre.x, point[pn].y = ppre.y; pn++; return true;} bool Match_one_corner(POINT ppre,POINT pcur) //判断两者是否能一折相消{ int left,right,top,bottel,x = ppre.x,y = ppre.y; Explot(ppre,&left,&right,&top,&bottel); ppre.y = top - 1;RESEARCHX: if(ppre.y < bottel) ppre.y++; else goto BACK; if(Match_direct(ppre,pcur)) goto FIND; else goto RESEARCHX;BACK: ppre.y = y; ppre.x = left - 1;RESEARCHY: if(ppre.x < right) ppre.x++; else goto REBACK; if(Match_direct(ppre,pcur)) goto FIND; else goto RESEARCHY;REBACK: pn = 0; return false;FIND: point[pn].x = x,point[pn].y = y,pn++; return true;} bool Match_two_corner(POINT ppre,POINT pcur) //判断两者是否能两折相消{ int left,right,top,bottel,x = ppre.x,y = ppre.y; Explot(ppre,&left,&right,&top,&bottel); ppre.y = top - 1;RESEARCHX: if(ppre.y < bottel) ppre.y++; else goto BACK; if(Match_one_corner(ppre,pcur)) goto FIND; else goto RESEARCHX;BACK: ppre.y = y; ppre.x = left - 1;RESEARCHY: if(ppre.x < right) ppre.x++; else goto REBACK; if(Match_one_corner(ppre,pcur)) goto FIND; else goto RESEARCHY;REBACK: pn = 0;return false;FIND: point[pn].x = x,point[pn].y = y,pn++; return true;} void Explot(POINT point,int *left,int *right,int *top,int *bottel){ int x = point.x,y = point.y; x++; while(x <= COL + 1 && GridID[y][x] == 0) x++; *right = x - 1; x = point.x; x--; while(x >= 0 && GridID[y][x] == 0) x--; *left = x + 1; x = point.x; y++; while(y <= ROW + 1 && GridID[y][x] == 0) y++; *bottel= y - 1; y = point.y; y--; while(y >= 0 && GridID[y][x] == 0) y--; *top = y + 1; }
最后用主函数调用,这样就可以啦
void main(){ initgraph(M,N); mciSendString("play game_begin.mp3 repeat", NULL, 0, NULL); InitFace(); while(1) { mouse = GetMouseMsg(); switch(mouse.uMsg) { case WM_MOUSEMOVE: Mousemove(mouse.x,mouse.y); break; case WM_LBUTTONDOWN: if(Single_click_judge(mouse.x,mouse.y)) { Leftbottondown(mouse); } break; default: break; } } closegraph();}
到此,相信大家对"C++怎么实现连连看游戏"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
坐标
棋子
鼠标
图片
图纸
信息
效果
函数
随机数
连连看
C++
直线
有效
内容
屏幕
棋盘
状态
边框
逻辑
重点
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
江西通用软件开发参考价
汕头市网络安全it培训
达梦数据库 kettle
我的世界杀人服务器
虚拟机搭建web服务器访问不了
js软件开发招聘
三级计算机网络技术大题格式
深圳市研科软件开发有限公司
海南计算机网络安全
数据库cnt
服务器逻辑结构图
服务器主机租用价格
恩施四路串口服务器
能用小米笔记本做软件开发吗
天龙网络技术有限公司
大连网络安全等级保护
计算机数据库种类
保定齐天软件开发公司
鹏博士网络技术
激光切割CAM软件开发
画流程图软件开发
企业管理软件开发成本
找工作java软件开发
互联网带动科技发展
阿里服务器ip与宝塔ip
我的世界生存服务器pe
学校网络安全意识形态
金山区标准软件开发销售方法
自制拨号上网服务器
基因在线数据库验证