千家信息网

C++怎么实现连连看游戏

发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,本篇内容主要讲解"C++怎么实现连连看游戏",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++怎么实现连连看游戏"吧!struct GridInfor
千家信息网最后更新 2025年11月16日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安全错误 数据库的锁怎样保障安全 网络安全标志怎么画图片 陕西健康智慧养老软件开发 拍图解题软件开发 邯郸市瀚宇软件开发有限公司 江阴参考软件开发价格表 开发网络安全数据保护技术 网络安全层次五个层次是 服务器信息安全管理要求 组态软件开发意义 沈阳应用软件开发一般要多少钱 饥荒联机版怎么让服务器一直开着 无法登录邮箱怎么办提示网络安全 太原市网络安全办公室 优炫数据库 信创 我的世界服务器开小号虚拟ip 东阳软件开发 数据库恢复技术系统故障例题 镇海小程序软件开发 群辉云存储服务器不间断电源 金融软件开发工程师收入 江阴进口软件开发定制价格 vc2010数据库 网络安全最赚钱 广州微商代理软件开发公司 广州智能照明软件开发定制 无法登录邮箱怎么办提示网络安全 数据库员工工资 现代网络技术研究生方向 mssql修改数据库文件 服务器特殊gpu卡是什么
0