C++怎么实现连连看游戏
发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,本篇内容主要讲解"C++怎么实现连连看游戏",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++怎么实现连连看游戏"吧!struct GridInfor
千家信息网最后更新 2024年11月19日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安全错误
数据库的锁怎样保障安全
延长县新闻网络安全
如何用电脑做网关服务器
怎么查找数据库大小
一个局域网服务器配置
暗黑3如何清空数据库
嵌入式软件开发要求
奥斯互联网科技有限公司
sql数据库的创建
网络安全的辩题
大飞哥网络安全30
汉川手机软件开发
qq数据库关系模型
黑林业计算机网络技术
重庆招聘 软件开发
全面战争三国如何开新服务器
怪兽猎人世界无法连接服务器
在云服务器上建站步骤
怎样在服务器上传软件
公安部网络安全演训
qq的服务器ip地址
成都网络安全产业有限公司
什么是数据库vf
蜀门数据库名称及密码
大学计算机网络技术好就业吗
银行的软件开发工作薪资
视频聊天数据库能不能查得到
怎么做直播app软件开发
后台服务器如何开启
哪里培训软件开发
郑州专业软件开发费用是多少