断断续续地写了一个多月终于完成了,在此特别感谢两位室友的合作。 

  

  开始界面。

  点击“开始游戏”可以以普通用户身份进入游戏;

  点击“开始游戏(debug版)”可以进入含有人工智能的游戏,在这个版本中提供了计算机自动消除图形的人工智能按钮,主要是为了方便调试和测试代码正确性;

  点击“查看排名”可以看到本地玩家的成绩排名,时间越短排名将越高。

  点击“退出游戏”将关闭应用程序。

    

  查看排名界面 用户登录界面

  当用户点击开始游戏后,登录界面会跳出,输入名字后,名字将被读入数据库。只有输入了文字才能点击开始。

  

  游戏界面。

  系统生成大小为14 X 16,可以两两匹配的地图,并有背景音乐播放。

  人工智能按钮仅在debug版中出现,在普通游戏版本中不会出现。

  点击两个图标,如果这两个图标的连接路径的至多只拐2个弯(至多用3条折线表示),那么两个图标将消去。否则不会消去。(由于代码内部只判定了第2*i - 1和第2*i次点击能否匹配,且无法取消点击,所以如果出现第一个图标点错情况,可再随意点击一个图标来抵消)

  每次点击图标,都有点击音效,如果可以消除,则伴随着消除音效。其中点击图标实现了三态性。

  右上角显示时间,1s闪烁更新一次,该时间作为最后排名的依据。

  一共有3次提示和2次重新生成地图的机会,每次使用一个上面的数值都会减少,最后将会呈现灰色,按钮不可点击。

 点击提示按钮,两个可以消去的图标将会用红色圆圈高亮出来。

  点击重新生成地图按钮,地图将在原来有图标布局保持不变的基础上打乱图标,生成的新地图里的图标也是两两配对的。

  每次消除后,系统都会判定地图上是否还存在下一对可以消除的图标,如果地图上 已经没有可以消除的配对图标了,系统将会自动生成新地图,并会给出如下的提示。(系 统自动生成的地图不算在2次重新生成地图中)

  游戏结束后,用户的时间将会传入数据库,排名将被更新。

  与中期计划的对照,除了路径显示由于时间关系没能完成,其余所有功能目标都已实现。

    

关键设计思路或方法

连连看主要由以下几个文件组成:

game.h game.cpp

游戏核心类,用于游戏功能的实现,其余的头文件和实现文件都是用来辅助这个类的。继承自QObject。

主要实现了两个方面的功能,一个是组织管理了不同界面通过按钮的跳转,以及实现各个文件之间的信号传输,并完成了主界面的窗口的布局。

另一个是游戏内部判定,包括创建地图、重新生成地图、判定两个图标是否可以消除、人工智能寻找下一对可消除的方块等等。

主要函数:

用于界面的函数(包括信号与槽的建立):

void setlayout();//游戏界面布局

子函数:void setimage();//摆放图像,void setblock();//摆放砖块

Button *createButton(QString &str1,QString &str2,QString &str3);//新建三态按钮

QPushButton *createButton(QString &str);//给地图边缘创建普通按钮

void setStartWindow(); //开始界面布局

void start_normal();//普通的开始游戏(接口函数)

void start_debug();//debug版的开始游戏(接口函数)

void showGrade();//显示成绩

void del_start();//清除开始界面

void del_game();//清除游戏界面

void startGame();//开始游戏

void quitGame();//退出游戏

void changetext();//重新生成地图和提示次数更新

void changetext2();

void show();//用红圈标出两个可连接的图标

用于游戏逻辑的实现:

bool ok();    //判断两个图片能否消去(接口函数)

bool judge(); //判断地图上是否还存在可消的图片,如果有,记录坐标存入(x3,y3)(x4,y4)

void dfs(int x,int y,int x2,int y2,int type);//判断两个图片能否消去(搜索函数)

void del(int k,int x,int y);//消掉图片后更新bucket数组

void change(int num);//接收点击图片的坐标并作出判断

void ai();//人工智能

void createmap();//新建地图

void recreate();//重建生成地图

 

   button.h button.cpp

    实现按钮的三态性,即普通态、点击态、停留态。

button继承自QToolButton,利用QToolButton提供的virtual接口,重写了鼠标的点击、停留、普通态等函数。

(此代码非原创,只用于优化界面)

displaytime.h displaytime.cpp

时间显示类,用于用户游戏过程中时间流逝的显示以及完成游戏过程后记录时间,游戏结束后根据时间长短得排名榜。

继承了QWidget类,从窗口系统接收时间变化事件,并且在屏幕上绘制显示。利用QPushButton按钮命令显示不断变化的时间(以秒为单位)。

主要函数:

DisplayTime(QWidget *parent = 0) ;//定义构造函数,包括按钮定义显示、时间单位转化等

virtual ~DisplayTime();//定义析构函数,去除类中定义的指针

void end();//用于时间停止,控制其中时间显示变化的量

void timerEvent(QTimerEvent *event) ;//用于窗口变化时间的显示

player.h player.cpp

音乐播放类,用于用户开始游戏过程中背景音乐的播放、选择按下图片后音乐的提示以及消去两图片后的音乐提示。

主要函数:

~Player();//定义析构函数,去除类中定义的指针

void play();//用于背景音乐的播放

void stop();//用于一轮游戏结束时音乐的停止

void setLoops (int l); //设置背景音乐的循环次数,在void play()中使用无限次播放音乐

void play1 ();//用于选择按下图片的音乐播放

void stop1 ();//用于选择按下图片的音乐停止

void play2 ();//用于图片消去后的音乐播放

void stop2 ();//用于图片消去后的音乐停止

class.h enter.h enter.cpp

成绩管理类,用于创建新用户,传入传出新用户的名字和成绩,游戏结束后进行排序得到排名榜,以及将所有数据保存至外部Grade.txt文档。

其中class.h用于定义用户类User,以及一个eUser用于保存一个需要储存当前用户名及时间的变量user。enter.h用于创建用户名输入窗口。enter.cpp用于储存所有在以上两个头文件定义的函数。由于输入界面和用户类关系密切,于是将他们的函数储存在了同一cpp文件中。

主要函数:

属于用户类User的函数:

User(char* name,double time);//定义构造函数

~User();//由于类中有指针,所以自己定义析构函数

char* Get_Name() const;//得到用户名

double Get_Time() const;//得到通过时间

void point(char* Name,double Time);//输入用户名和时间

void set_name(char* Name);//输入用户名

void set_time(double Time);//输入时间

void Game_End(double now_time);//游戏结束后读取进行排名

属于enter.h的函数:

Enter(QWidget *parent = 0);//创建输入用户界面的窗口

void enableFindButton(const QString &text);//用户输入名字后才可以点击开始按钮

void startClicked();//点击后储存用户名

show.h show.cpp

用于显示排行榜。即Grade.txt中的数据后显示在游戏界面中。

主要函数:

Show(QWidget *parent = 0);//创建查看排行的窗口

void Close(const QString &str,Qt::CaseSensitivity cs);//关闭该窗口

2.详细设计

game.h game.cpp

 

算法和界面的连接:

 

连连看游戏主要是对游戏中的图标进行操作,也就是说操作对象是图中的图标,但是在实际操作的时候不可能将每一个图标button对象作为参数传入判定算法,关于如何判定图标是哪个图标,如何判定两个图标是否相等,基于像素点的比较是不现实的。

所以在game.cpp中使用了整型二维数组来模拟图标。内部的算法都是在对整型二维数组进行操作,而图标采取和数组对应的下标索引,所以可以根据索引来连接对应的图片,在搜索的时候也是直接传入索引,寻找下一对可连接的图标时也会存储每个图标的坐标。

地图生成和打乱:

首先用于储存地图数据的是一个整形矩阵,有图标的地方用图标编号表示,否则以0表示,且最外围一圈必须为0,为之后路线判断时使用。因此为了生成一个10*14的地图,我们需要生成一个12*16的矩阵,并将最外围设为0。

每个图标出现4次,于是设置一个长度为10*14=140的数组并以此放入4个1,4

个2,……,4个35。将该数组中的数据打乱之后放入矩阵中除去值为0外其他的位置后便得到了打乱后的地图。

游戏中重新生成地图的原理也比较类似。在读取地图中所有不为0的位置的值后打乱,最后将得到的数据放回地图中,地图便重新生成了。

搜索算法:

 

利用深度优先搜索来判定两个图标能否消去。

dfs(x,y,x2,y2,type)// x,y是起点坐标x2,y2是终点坐标,type是前一次移动方向

如果两个图标不一样,回溯。

用count来记录当前的拐弯次数,当count>=3时,记录flag为true,回溯。

当flag为true时,回溯,在代码中多次使用引入这段判定让已经搜索成功的数据尽快一层层退出搜索。

dfs(x-1,y,x2,y2,Up);//向上搜索

dfs(x+1,y,x2,y2,Down);//向下搜索

dfs(x,y-1,x2,y2,Left);//向左搜索

dfs(x,y+1,x2,y2,Right);//向右搜索

如果前一次方位与下一次搜索方位不一样,count++。

人工智能:

如果对地图上每两个图标都进行暴力搜索,则会出现栈溢出,所以这样的算法不可行。

可以考虑牺牲空间来优化时间,可以在初始化地图时将所有相同图标的坐标存放到同一个桶里,每次消除图标或者改变地图时,就从第一个桶开始,利用搜索算法,两两判定能否消除。一旦可以消除,就退出寻找,并存储可以消除的两个坐标点,它们可以用于提示的输出,也可以用来判定当前地图是否可以继续,如果搜索不到可消除的图标,将重新生成地图。

如果图标被删除,更新桶,将两个图标从桶里移除;如果地图改变,则需要重新生成桶。

点击图标的信号连接:

  单独的clicked()信号不能传送参数,所以如果直接连接信号,必须对每个图标写 一个对应的接口槽函数,而地图上有14*16个图标,为每个图标都写函数显然是相当麻 烦的,所以在这里使用了信号中继器来存储坐标信息,并将坐标信息发送给槽函数。

由于信号中继器只允许传递一个Int或者一个QString,所以在这里将坐标点信息(x,y)压缩为100*x+y,被接收入槽函数后再还原坐标信息。再利用循环,就可以大大压缩代码量,使代码更加简洁、具有可读性。

接收坐标信号的槽函数:

接收来自用户点击图标后发送的坐标信号,并且作出相应的反馈。是game.cpp中最为核心的一个槽函数,描述了大部分的游戏组织逻辑。

奇数次接收坐标信号时,将坐标存储到类的私有成员(x1,y1)中;偶数次接收坐标信号时,将坐标存储到(x2,y2)中,先进入判定函数,判定成功后执行相应的消除方块操作、播放音乐操作;再进入搜索下一对可连接图标的函数,存储坐标信息于(x3,y3),(x4,y4)。搜索失败则调用重新生成地图函数;当前图标数目消减为0时执行计时停止、显示成功、界面转换、更新成绩等操作。

displaytime.h displaytime.cpp

 

时间的显示:

从按下开始游戏起,即开始时间变化,转化单位毫秒为秒。每一秒触动一次时间类函数,并通过一个整数型变量累加进行记录,利用QString转化数据类型,在标签按钮中显示,同样是每秒一个时间显示,形成时间流逝的效果。当时间变化位数增加时,利用文本自动调整函数,自动在标签按钮上调整合适的输出变量的空间。

游戏停止时,时间截止,通过变量控制,依旧每秒触动一次函数,但整数型变量不进行累加,显示的时间不变,形成时间停止的效果,可记录完成时间。

player.h player.cpp

 

音乐的播放:

为满足听觉效果享受,在工程运行中允许音乐播放,需要在game.pro文件中添加QT+=multimedia提供多媒体功能实现平台相关特性,接口功能覆盖了播放视频音频,录制视频音频,其中包括多种多媒体封装格式。

音乐类的播放主要继承了QSound类,该类的音乐播放要求其音乐必须为wav格式。根据绝对路径调用音乐,背景音乐播放时设置了无限循环的功能,一轮游戏结束由于使用setLoops循环,不能同时用stop停止,选择delete指针停止播放。在背景音乐基础上,鼠标每次按下图片时会播放“select”音乐,判断两张图片完成消去时调用pair音乐,为了防止音乐的重叠造成程序的异常,使用两个停止函数中止播放。

class.h enter.h enter.cpp show.h show.cpp

成绩的管理:

    

成绩管理的大概思路就是创建一个游戏全局存在的User,在游戏结束后传入用户姓名和成绩,并将排名信息储存在一个文档中。这个文档可以在主菜单界面点击排行榜按钮后读入查看。

因为QT默认读入的数据都为QString,为了实现类型统一,需要对读入的名字和时间进行类型转化。然后通过User中的set_name和set_time函数可以实现这两个信息的输入。同时在游戏结束时调用的Game_End函数在储存信息之前先做一个判断,将文本中的信息和新输入的信息进行比较,只取其中的前五个输入,作为排行榜数据,也是为了防止出现文件过大的情况。

  以下是具体的代码实现:

  game.h

#ifndef GAME_H
#define GAME_H#include"show.h"
#include"button.h"
#include"displaytime.h"
#include"player.h"
#include"enter.h"
#include"class.h"
#include<QLayout>
#include<QPushButton>
#include<QSignalMapper>
#include<QWidget>
#include<QMessageBox>
#include<iostream>class game:public QObject
{Q_OBJECTprivate:enum{Null,Right,Left,Up,Down};enum{MaxSizeX=10,MaxSizeY=14};enum{imagenum=36};int x1,y1,x2,y2,x3,y3,x4,y4;//(x1,y1)(x2,y2)记录当前点击两张图片坐标,//(x3,y3)(x4,y4)记录程序找到的下一对可以消掉的图片坐标int map[MaxSizeX+2][MaxSizeY+2];//地图int count;//记录连线拐弯次数int num[imagenum+1];//记录不同类型图片的个数bool flag;//判断两个图片能否消去的标记int isStart;//判断游戏目前处于哪个界面bool isAI;//是否开启debug模式struct{int x;int y;}bucket[imagenum+1][5];//存放不同类型图片的坐标//bucket[i][j]代表第i种图片的第j个图的坐标//用于辅助judge()函数QGridLayout *gridlayout;//表格布局QHBoxLayout *hlayout1,*hlayout2,*hlayout3,*hlayout4;//水平布局QVBoxLayout *vlayout;//竖直布局QSignalMapper *signalMapper[MaxSizeX][MaxSizeY];//信号中继站QPushButton *block[2*MaxSizeX+2*MaxSizeY+4];//地图边缘Button *image[MaxSizeX][MaxSizeY];//图片按钮QWidget *window;//主窗口QPushButton *changebutton;QPushButton *tipbutton;QPushButton *aibutton;DisplayTime *timer;QPushButton *startbutton;QPushButton *gradebutton;QPushButton *debugbutton;QPushButton *quitbutton;Player *sound;void createmap();//新建地图void setlayout();//窗口布局void setimage();void setblock();inline void initialbucket(){memset(num,0,sizeof(num));memset(bucket,0,sizeof(bucket));for(int i=1;i<=MaxSizeX;i++){for(int j=1;j<=MaxSizeY;j++){if(map[i][j]!=0){bucket[map[i][j]][num[map[i][j]]].x=i;bucket[map[i][j]][num[map[i][j]]++].y=j;}}}}//初始化bucket数组bool ok();//判断两个图片能否消去(接口函数)bool judge();//判断地图上是否还存在可消的图片,如果有,记录坐标存入(x3,y3)(x4,y4)void dfs(int x,int y,int x2,int y2,int type);//判断两个图片能否消去(搜索函数)void del(int k,int x,int y);//消掉图片后更新bucket数组Button *createButton(QString &str1,QString &str2,QString &str3);//给图片创建三态按钮QPushButton *createButton(QString &str);//给地图边缘创建普通按钮void del_start();//清除开始界面void del_game();//清除游戏界面public:game();virtual ~game();int imageNum;//记录屏幕上图片个数private slots:void change(int num);//接收点击图片的坐标并作出判断void show();//显示提示图片void recreate();//重建生成地图void changetext();//重新生成地图和提示次数更新void changetext2();void setStartWindow(); //游戏开始界面void ai();//人工智能void start_normal();//普通的开始游戏(接口函数)void start_debug();//debug版的开始游戏(接口函数)void showGrade();//显示成绩void startGame();//开始游戏void quitGame();//退出游戏
};#endif // GAME_H

game.cpp

#include "game.h"
#include<QBitmap>
#include<QPixmap>
#include<QTimer>
#include<QPalette>
#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<time.h>game::game()
{window=0;isStart=2;setStartWindow();
}game::~game()
{if(isStart==1){del_game();delete window;}else if(isStart==0){del_start();delete window;}
}void game::createmap()
{std::cout<<"createmap"<<std::endl;int b[MaxSizeX*MaxSizeY];int i,j,k;for(i=0;i<MaxSizeX*MaxSizeY;i+=4){b[i]=b[i+1]=b[i+2]=b[i+3]=i/4+1;}srand((unsigned)time(NULL));std::random_shuffle(b,b+MaxSizeX*MaxSizeY);k=0;memset(map,0,sizeof(map));for(i=1;i<=MaxSizeX;i++){for(j=1;j<=MaxSizeY;j++){map[i][j]=b[k];k++;}}
}
void game::recreate()
{std::cout<<"recreate"<<std::endl;int b[MaxSizeX*MaxSizeY];int i,j;int k=0;int temp;for(i=1;i<=MaxSizeX;i++){for(j=1;j<=MaxSizeY;j++){b[k]=map[i][j];k++;}}srand((unsigned)time(NULL));for(i=1;i<MaxSizeX*MaxSizeY;i++){if(b[i]==0)continue;j=rand()%(i+1);k=2;while(b[j]==0){j=rand()%(i+k);k++;}temp=b[i];b[i]=b[j];b[j]=temp;}k=0;for(i=1;i<=MaxSizeX;i++){for(j=1;j<=MaxSizeY;j++){map[i][j]=b[k];k++;}}for(i=0;i<MaxSizeX;i++){for(j=0;j<MaxSizeY;j++){if(map[i+1][j+1]!=0){delete image[i][j];delete signalMapper[i][j];}}}setimage();initialbucket();if(!judge())recreate();
}void game::del_game()
{std::cout<<"game::~game()"<<std::endl;int i,j;for(i=0;i<MaxSizeX;i++){for(j=0;j<MaxSizeY;j++){if(map[i+1][j+1]!=0){delete image[i][j];delete signalMapper[i][j];}}}for(i=0;i<2*MaxSizeX+2*MaxSizeY+4;i++){delete block[i];}delete changebutton;delete tipbutton;if(isAI)delete aibutton;delete timer;delete gridlayout;delete vlayout;delete hlayout1;
}void game::del_start()
{std::cout<<"game::~game()"<<std::endl;delete startbutton;delete gradebutton;delete hlayout1;delete hlayout2;delete hlayout3;delete vlayout;
}void game::change(int num)
{std::cout<<"change"<<std::endl;int x=num/100+1;int y=num%100+1;double ftime;enum{first,second};static int vis=first;if(vis==first){x1=x;y1=y;vis=second;sound->play1();sound->stop1();}else if(vis==second){x2=x;y2=y;if(x1==x2&&y1==y2){sound->play1();sound->stop1();}else if(ok()){del(map[x1][y1],x1,y1);del(map[x1][y1],x2,y2);delete image[x1-1][y1-1];delete image[x2-1][y2-1];delete signalMapper[x1-1][y1-1];delete signalMapper[x2-1][y2-1];map[x1][y1]=0;map[x2][y2]=0;imageNum-=2;std::cout<<imageNum<<std::endl;if(imageNum==0){QMessageBox msg;timer->end();sound->stop();ftime=timer->count;//std::cout<<"time is:"<<eUser::user.Get_Name()<<std::endl;eUser::user.Game_End(eUser::user.qname,ftime);//std::cout<<"time is:"<<ftime<<std::endl;msg.setText(tr("You Win This Game, Congratulation"));msg.exec();del_game();delete window;setStartWindow();return;}if(!judge()){QMessageBox msg;msg.setText(tr("地图上无可连接的图标,\n系统将自动生成新地图"));msg.exec();recreate();}}else{sound->play1();sound->stop1();}vis=first;}
}void game::setimage()
{std::cout<<"setimage"<<std::endl;QString str1[]={"D:/game/image/1.jpg","D:/game/image/2.jpg","D:/game/image/3.jpg","D:/game/image/4.jpg","D:/game/image/5.jpg","D:/game/image/6.jpg","D:/game/image/7.jpg","D:/game/image/8.jpg","D:/game/image/9.jpg","D:/game/image/10.jpg","D:/game/image/11.jpg","D:/game/image/12.jpg","D:/game/image/13.jpg","D:/game/image/14.jpg","D:/game/image/15.jpg","D:/game/image/16.jpg","D:/game/image/17.jpg","D:/game/image/18.jpg","D:/game/image/19.jpg","D:/game/image/20.jpg","D:/game/image/21.jpg","D:/game/image/22.jpg","D:/game/image/23.jpg","D:/game/image/24.jpg","D:/game/image/25.jpg","D:/game/image/26.jpg","D:/game/image/27.jpg","D:/game/image/28.jpg","D:/game/image/29.jpg","D:/game/image/30.jpg","D:/game/image/31.jpg","D:/game/image/32.jpg","D:/game/image/33.jpg","D:/game/image/34.jpg","D:/game/image/35.jpg","D:/game/image/36.jpg"};QString str2[]={"D:/game/image/1_1.jpg","D:/game/image/2_1.jpg","D:/game/image/3_1.jpg","D:/game/image/4_1.jpg","D:/game/image/5_1.jpg","D:/game/image/6_1.jpg","D:/game/image/7_1.jpg","D:/game/image/8_1.jpg","D:/game/image/9_1.jpg","D:/game/image/10_1.jpg","D:/game/image/11_1.jpg","D:/game/image/12_1.jpg","D:/game/image/13_1.jpg","D:/game/image/14_1.jpg","D:/game/image/15_1.jpg","D:/game/image/16_1.jpg","D:/game/image/17_1.jpg","D:/game/image/18_1.jpg","D:/game/image/19_1.jpg","D:/game/image/20_1.jpg","D:/game/image/21_1.jpg","D:/game/image/22_1.jpg","D:/game/image/23_1.jpg","D:/game/image/24_1.jpg","D:/game/image/25_1.jpg","D:/game/image/26_1.jpg","D:/game/image/27_1.jpg","D:/game/image/28_1.jpg","D:/game/image/29_1.jpg","D:/game/image/30_1.jpg","D:/game/image/31_1.jpg","D:/game/image/32_1.jpg","D:/game/image/33_1.jpg","D:/game/image/34_1.jpg","D:/game/image/35_1.jpg","D:/game/image/36_1.jpg"};QString str3[]={"D:/game/image/1_2.jpg","D:/game/image/2_2.jpg","D:/game/image/3_2.jpg","D:/game/image/4_2.jpg","D:/game/image/5_2.jpg","D:/game/image/6_2.jpg","D:/game/image/7_2.jpg","D:/game/image/8_2.jpg","D:/game/image/9_2.jpg","D:/game/image/10_2.jpg","D:/game/image/11_2.jpg","D:/game/image/12_2.jpg","D:/game/image/13_2.jpg","D:/game/image/14_2.jpg","D:/game/image/15_2.jpg","D:/game/image/16_2.jpg","D:/game/image/17_2.jpg","D:/game/image/18_2.jpg","D:/game/image/19_2.jpg","D:/game/image/20_2.jpg","D:/game/image/21_2.jpg","D:/game/image/22_2.jpg","D:/game/image/23_2.jpg","D:/game/image/24_2.jpg","D:/game/image/25_2.jpg","D:/game/image/26_2.jpg","D:/game/image/27_2.jpg","D:/game/image/28_2.jpg","D:/game/image/29_2.jpg","D:/game/image/30_2.jpg","D:/game/image/31_2.jpg","D:/game/image/32_2.jpg","D:/game/image/33_2.jpg","D:/game/image/34_2.jpg","D:/game/image/35_2.jpg","D:/game/image/36_2.jpg"};for(int i=0;i<MaxSizeX;i++){for(int j=0;j<MaxSizeY;j++){int tmp=map[i+1][j+1];if(tmp!=0){signalMapper[i][j]= new QSignalMapper;image[i][j]=createButton(str1[tmp-1],str2[tmp-1],str3[tmp-1]);gridlayout->addWidget(image[i][j],i+1,j+1);connect(image[i][j],SIGNAL(clicked()),signalMapper[i][j],SLOT(map()));signalMapper[i][j]->setMapping(image[i][j],100*i+j);connect(signalMapper[i][j],SIGNAL(mapped(int)),this, SLOT(change(int)));}}}
}void game::setStartWindow()
{isStart=0;window=new QWidget;window->setAutoFillBackground(true);QPalette palette;palette.setBrush(QPalette::Background,QBrush(QPixmap("D:/game/image/window.jpg")));window->setPalette(palette);startbutton=new QPushButton("开始游戏");gradebutton=new QPushButton("查看排名");debugbutton=new QPushButton("开始游戏(debug版)");quitbutton=new QPushButton("退出游戏");vlayout=new QVBoxLayout;hlayout1=new QHBoxLayout;hlayout2=new QHBoxLayout;hlayout3=new QHBoxLayout;hlayout4=new QHBoxLayout;hlayout1->addStretch();hlayout1->addWidget(startbutton);hlayout1->addStretch();hlayout2->addStretch();hlayout2->addWidget(gradebutton);hlayout2->addStretch();hlayout3->addStretch();hlayout3->addWidget(debugbutton);hlayout3->addStretch();hlayout4->addStretch();hlayout4->addWidget(quitbutton);hlayout4->addStretch();vlayout->addLayout(hlayout1);vlayout->addLayout(hlayout3);vlayout->addLayout(hlayout2);vlayout->addLayout(hlayout4);window->setLayout(vlayout);window->setFixedSize(600,450);window->show();connect(startbutton,SIGNAL(clicked()),this,SLOT(start_normal()));connect(debugbutton,SIGNAL(clicked()),this,SLOT(start_debug()));connect(gradebutton,SIGNAL(clicked()),this,SLOT(showGrade()));connect(quitbutton,SIGNAL(clicked()),this,SLOT(quitGame()));
}void game::setblock()
{std::cout<<"setblock"<<std::endl;QString str("D:/game/image/a.jpg");int cnt=0;for(int i=0;i<=MaxSizeX+1;i++){block[cnt]=createButton(str);gridlayout->addWidget(block[cnt++],i,0);}for(int j=1;j<=MaxSizeY+1;j++){block[cnt]=createButton(str);gridlayout->addWidget(block[cnt++],0,j);}for(int i=1;i<=MaxSizeX+1;i++){block[cnt]=createButton(str);gridlayout->addWidget(block[cnt++],i,MaxSizeY+1);}for(int j=1;j<=MaxSizeY+1;j++){block[cnt]=createButton(str);gridlayout->addWidget(block[cnt++],MaxSizeX+1,j);}
}void game::setlayout()
{QString str1("D:/game/image/map2.png");QString str2("D:/game/image/tip3.png");std::cout<<"setlayout"<<std::endl;window=new QWidget;window->setWindowTitle(tr("连连看"));window->resize(250,100);gridlayout=new QGridLayout;hlayout1=new QHBoxLayout;vlayout=new QVBoxLayout;changebutton=new QPushButton;QPixmap img1(str1),img2(str2);changebutton->setIcon(img1);changebutton->setIconSize(QSize(150,100));changebutton->setFlat(true);tipbutton=new QPushButton;tipbutton->setIcon(img2);tipbutton->setFlat(true);tipbutton->setIconSize(QSize(150,100));if(isAI)aibutton=new QPushButton(tr("人工智能"));else{aibutton=new QPushButton;aibutton->setFlat(true);}timer=new DisplayTime;vlayout->addWidget(timer);vlayout->addWidget(changebutton);vlayout->addWidget(tipbutton);vlayout->addWidget(aibutton);connect(tipbutton,SIGNAL(clicked()),this,SLOT(show()));connect(tipbutton,SIGNAL(clicked()),this,SLOT(changetext()));connect(changebutton,SIGNAL(clicked()),this,SLOT(recreate()));connect(changebutton,SIGNAL(clicked()),this,SLOT(changetext2()));if(isAI)connect(aibutton,SIGNAL(clicked()),this,SLOT(ai()));setblock();setimage();window->setAutoFillBackground(true);QPalette palette;palette.setBrush(QPalette::Background,QBrush(QPixmap("D:/game/image/background3.jpg")));window->setPalette(palette);hlayout1->addLayout(gridlayout);hlayout1->addLayout(vlayout);window->setLayout(hlayout1);window->show();judge();}void game::changetext()
{QString str[]={"D:/game/image/tip0.png","D:/game/image/tip1.png","D:/game/image/tip2.png"};QPixmap img0(str[0]),img1(str[1]),img2(str[2]);static int cnt=1;if(cnt==1){tipbutton->setIcon(img2);}else if(cnt==2){tipbutton->setIcon(img1);}else if(cnt==3){tipbutton->setIcon(img0);tipbutton->setEnabled(false);}cnt++;
}void game::changetext2()
{QString str[]={"D:/game/image/map0.png","D:/game/image/map1.png"};QPixmap img0(str[0]),img1(str[1]);static int cnt=1;if(cnt==1){changebutton->setIcon(img1);}else if(cnt==2){changebutton->setIcon(img0);changebutton->setEnabled(false);}cnt++;
}void game::start_normal()
{isAI=false;Enter *start=new Enter;start->show();connect(start->startButton,SIGNAL(clicked()),this,SLOT(startGame()));
}void game::start_debug()
{isAI=true;Enter *start=new Enter;start->show();connect(start->startButton,SIGNAL(clicked()),this,SLOT(startGame()));
}void game::startGame()
{isStart=1;delete startbutton;delete gradebutton;delete hlayout1;delete hlayout2;delete hlayout3;delete vlayout;delete window;isStart=true;imageNum=MaxSizeX*MaxSizeY;createmap();initialbucket();setlayout();sound->play();
}void game::showGrade()
{Show *p=new Show();p->show();
}void game::quitGame()
{isStart=3;del_start();delete window;
}Button *game::createButton(QString &str1,QString &str2,QString &str3)
{Button *button=new Button;button->setGeometry(0,0,0,0);QPixmap img1,img2,img3;img1.load(str1);img2.load(str2);img3.load(str3);button->setFixedSize(img1.width(),img1.height());button->SetButtonIcons(img1,img2,img3);button->setIconSize(QSize(img1.width(),img1.height()));return button;
}QPushButton *game::createButton(QString &str)
{QPushButton *button=new QPushButton;QPixmap img(str);button->setFixedSize(img.width(),img.height());button->setFlat(true);return button;
}bool game::ok()
{std::cout<<"ok"<<std::endl;flag=false;count=0;if(map[x1][y1]!=map[x2][y2])return false;dfs(x1,y1,x2,y2,Null);if(flag){sound->play2();sound->stop2();return true;}return false;
}void game::dfs(int x,int y,int x2,int y2,int type)
{if(flag)return;if(count>=3)return;if(x==MaxSizeX+2||x<0||y==MaxSizeY+2||y<0)return;if(x==x2&&y==y2){flag=true;return;}if(map[x][y]!=0&&type!=Null)return;if(type!=Up&&type!=Null){count++;dfs(x-1,y,x2,y2,Up);count--;}else{dfs(x-1,y,x2,y2,Up);}if(flag)return;if(type!=Down&&type!=Null){count++;dfs(x+1,y,x2,y2,Down);count--;}else{dfs(x+1,y,x2,y2,Down);}if(flag)return;if(type!=Left&&type!=Null){count++;dfs(x,y-1,x2,y2,Left);count--;}else{dfs(x,y-1,x2,y2,Left);}if(flag)return;if(type!=Right&&type!=Null){count++;dfs(x,y+1,x2,y2,Right);count--;}else{dfs(x,y+1,x2,y2,Right);}if(flag)return;
}bool game::judge()
{std::cout<<"judge"<<std::endl;flag=false;static int cnt=1;for(int k=1;k<=imagenum;k++){for(int i=0;i<num[k]-1;i++){for(int j=i+1;j<num[k];j++){x3=bucket[k][i].x;y3=bucket[k][i].y;x4=bucket[k][j].x;y4=bucket[k][j].y;count=0;dfs(x3,y3,x4,y4,Null);//   std::cout<<x3<<" "<<y3<<" "<<x4<<" "<<y4<<" "<<std::endl;if(flag){std::cout<<cnt++<<":yes,("<<x3<<","<<y3<<")("<<x4<<","<<y4<<")"<<std::endl;return true;}}}}std::cout<<cnt++<<":false"<<std::endl;return false;
}void game::del(int k,int x,int y)
{int i;for(i=0;i<num[k];i++){if(bucket[k][i].x==x&&bucket[k][i].y==y)break;}for(;i<num[k]-1;i++){bucket[k][i].x=bucket[k][i+1].x;bucket[k][i].y=bucket[k][i+1].y;}num[k]--;
}void game::show()
{std::cout<<"show"<<std::endl;QString str1[]={"D:/game/image/1_3.jpg","D:/game/image/2_3.jpg","D:/game/image/3_3.jpg","D:/game/image/4_3.jpg","D:/game/image/5_3.jpg","D:/game/image/6_3.jpg","D:/game/image/7_3.jpg","D:/game/image/8_3.jpg","D:/game/image/9_3.jpg","D:/game/image/10_3.jpg","D:/game/image/11_3.jpg","D:/game/image/12_3.jpg","D:/game/image/13_3.jpg","D:/game/image/14_3.jpg","D:/game/image/15_3.jpg","D:/game/image/16_3.jpg","D:/game/image/17_3.jpg","D:/game/image/18_3.jpg","D:/game/image/19_3.jpg","D:/game/image/20_3.jpg","D:/game/image/21_3.jpg","D:/game/image/22_3.jpg","D:/game/image/23_3.jpg","D:/game/image/24_3.jpg","D:/game/image/25_3.jpg","D:/game/image/26_3.jpg","D:/game/image/27_3.jpg","D:/game/image/28_3.jpg","D:/game/image/29_3.jpg","D:/game/image/30_3.jpg","D:/game/image/31_3.jpg","D:/game/image/32_3.jpg","D:/game/image/33_3.jpg","D:/game/image/34_3.jpg","D:/game/image/35_3.jpg","D:/game/image/36_3.jpg"};QString str3[]={"D:/game/image/1_2.jpg","D:/game/image/2_2.jpg","D:/game/image/3_2.jpg","D:/game/image/4_2.jpg","D:/game/image/5_2.jpg","D:/game/image/6_2.jpg","D:/game/image/7_2.jpg","D:/game/image/8_2.jpg","D:/game/image/9_2.jpg","D:/game/image/10_2.jpg","D:/game/image/11_2.jpg","D:/game/image/12_2.jpg","D:/game/image/13_2.jpg","D:/game/image/14_2.jpg","D:/game/image/15_2.jpg","D:/game/image/16_2.jpg","D:/game/image/17_2.jpg","D:/game/image/18_2.jpg","D:/game/image/19_2.jpg","D:/game/image/20_2.jpg","D:/game/image/21_2.jpg","D:/game/image/22_2.jpg","D:/game/image/23_2.jpg","D:/game/image/24_2.jpg","D:/game/image/25_2.jpg","D:/game/image/26_2.jpg","D:/game/image/27_2.jpg","D:/game/image/28_2.jpg","D:/game/image/29_2.jpg","D:/game/image/30_2.jpg","D:/game/image/31_2.jpg","D:/game/image/32_2.jpg","D:/game/image/33_2.jpg","D:/game/image/34_2.jpg","D:/game/image/35_2.jpg","D:/game/image/36_2.jpg"};delete image[x3-1][y3-1];delete image[x4-1][y4-1];delete signalMapper[x3-1][y3-1];delete signalMapper[x4-1][y4-1];signalMapper[x3-1][y3-1]=new QSignalMapper;signalMapper[x4-1][y4-1]=new QSignalMapper;image[x3-1][y3-1]=createButton(str1[map[x3][y3]-1],str1[map[x3][y3]-1],str3[map[x3][y3]-1]);image[x4-1][y4-1]=createButton(str1[map[x4][y4]-1],str1[map[x4][y4]-1],str3[map[x4][y4]-1]);gridlayout->addWidget(image[x3-1][y3-1],x3,y3);gridlayout->addWidget(image[x4-1][y4-1],x4,y4);connect(image[x3-1][y3-1],SIGNAL(clicked()),signalMapper[x3-1][y3-1],SLOT(map()));connect(image[x4-1][y4-1],SIGNAL(clicked()),signalMapper[x4-1][y4-1],SLOT(map()));signalMapper[x3-1][y3-1]->setMapping(image[x3-1][y3-1],100*(x3-1)+y3-1);signalMapper[x4-1][y4-1]->setMapping(image[x4-1][y4-1],100*(x4-1)+y4-1);connect(signalMapper[x3-1][y3-1],SIGNAL(mapped(int)),this, SLOT(change(int)));connect(signalMapper[x4-1][y4-1],SIGNAL(mapped(int)),this, SLOT(change(int)));
}void game::ai()
{change(100*(x3-1)+y3-1);change(100*(x4-1)+y4-1);
}

button.h(button.h和button.cpp不是原创的)

#ifndef BUTTON
#define BUTTON
#include<QToolButton>class Button : public QToolButton
{Q_OBJECT
private:QIcon m_NormalIcon;QIcon m_FocusIcon;QIcon m_PressedIcon;
protected:void enterEvent(QEvent *event);void leaveEvent(QEvent *event);void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);
public:Button(QWidget *parent = 0);virtual ~Button();void SetButtonIcons(const QIcon &normal,const QIcon &focus = QIcon(),const QIcon &pressed = QIcon() );
};#endif // BUTTON

button.cpp

#include"button.h"Button::Button(QWidget *parent)
: QToolButton(parent)
{setDown(false);setFocusPolicy(Qt::NoFocus);
}Button::~Button()
{}void Button::enterEvent(QEvent *event)
{if( isEnabled() && !m_FocusIcon.isNull() )setIcon(m_FocusIcon);
}void Button::leaveEvent(QEvent *event)
{if( isEnabled() )setIcon(m_NormalIcon);
}
void Button::mousePressEvent(QMouseEvent *event)
{if( isEnabled() && !m_PressedIcon.isNull() )setIcon(m_PressedIcon);QToolButton::mousePressEvent(event);
}void Button::mouseReleaseEvent(QMouseEvent *event)
{if( isEnabled() && m_FocusIcon.isNull() )setIcon(m_FocusIcon);QToolButton::mouseReleaseEvent(event);
}void Button::SetButtonIcons(const QIcon &normal,const QIcon &focus, const QIcon &pressed)
{m_NormalIcon = normal;m_FocusIcon = focus;m_PressedIcon = pressed;setIcon(m_NormalIcon);
}

class.h

#ifndef CLASS_H
#define CLASS_H#include <QDialog>class User
{
public:User(char* name,double time);char* Get_Name() const;double Get_Time() const;void point(char* Name,double Time);void Game_End(QString qname, double now_time);~User();void set_name(char* Name);void set_time(double Time);QString qname;
private:char* name;double time;
};class eUser{
public:static User user;
};#endif

enter.h

#ifndef ENTER_H
#define ENTER_H
#include"class.h"
#include <QDialog>class QLabel;
class QLineEdit;
class QPushButton;class Enter : public QDialog
{Q_OBJECTpublic:Enter(QWidget *parent = 0);QPushButton *startButton;User *user;
signals:void EnterGame(const QString &str,Qt::CaseSensitivity cs);void EnterPrevious(const QString &str,Qt::CaseSensitivity cs);private slots:void enableFindButton(const QString &text);void startClicked();private:QLabel *label;QLineEdit *lineEdit;QPushButton *returnButton;
};#endif // ENTER_H

enter.cpp

#include <QtGui>
#include "enter.h"
#include "class.h"
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QByteArray>
#include <iostream>
#include <fstream>
using namespace std;User::User(char* name="NULL",double time=10000)
{this->name = (char*)malloc(strlen(name)+1);strcpy(this->name,name);this->time = time;
}char* User::Get_Name() const
{return name;
}double User::Get_Time() const
{return time;
}void User::set_name(char* Name)
{this->name=Name;
}void User::set_time(double Time)
{this->time=Time;
}void User::point(char* Name,double Time)
{this->name=Name;this->time=Time;
}void User::Game_End(QString qname,double now_time)
{char* ch;QByteArray ba = qname.toLatin1();ch=ba.data();User allname[6];User temp(ch,now_time);double Time;char* Name=(char*)malloc(10*sizeof(char));int rank=0;ifstream out("D:/game/grade/Grade.txt",ios::in);while(out>>Name>>Time){allname[rank].point(Name,Time);//cout<<allname[rank].Get_Name()<<"  "<<rank+1<<"  "<<allname[rank].Get_Time()<<endl;if(rank<=5){rank++;Name=(char*)malloc(10);}elsebreak;}out.close();allname[5]=temp;/*for(rank=0;rank<5;rank++){cout<<allname[rank].Get_Name()<<"  "<<rank+1<<"  "<<allname[rank].Get_Time()<<endl;}*/for(int i=0;i<5;i++){for(rank=0;rank<5-i;rank++){if(allname[rank].Get_Time()>allname[rank+1].Get_Time()){temp=allname[rank];//cout<<temp.Get_Name()<<"  "<<rank+1<<"  "<<temp.Get_Time()<<endl;allname[rank]=allname[rank+1];allname[rank+1]=temp;}}}/*for(rank=0;rank<5;rank++){cout<<allname[rank].Get_Name()<<"  "<<rank+1<<"  "<<allname[rank].Get_Time()<<endl;}*/ofstream file;file.open("D:/game/grade/Grade.txt",ios::out);for(rank=0;rank<5;rank++){if(allname[rank].Get_Time()!=10000){cout<<allname[rank].Get_Name()<<"  "<<rank+1<<"  "<<allname[rank].Get_Time()<<endl;}file<<allname[rank].Get_Name()<<"  "<<allname[rank].Get_Time()<<endl;}file.close();
}User::~User()
{if(name!=NULL)free(name);
}User eUser::user;Enter::Enter(QWidget *parent) :QDialog(parent)
{label=new QLabel(tr("Please input your name:"));lineEdit=new QLineEdit;label->setBuddy(lineEdit);startButton=new QPushButton(tr("Start!"));startButton->setDefault(true);startButton->setEnabled(false);returnButton=new QPushButton(tr("Return"));connect(lineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(enableFindButton(const QString &)));connect(startButton,SIGNAL(clicked()),this,SLOT(startClicked()));connect(returnButton,SIGNAL(clicked()),this,SLOT(close()));QHBoxLayout *lastButton=new QHBoxLayout;lastButton->addWidget(returnButton);lastButton->addWidget(startButton);QVBoxLayout *mainLayout= new QVBoxLayout;mainLayout->addWidget(label);mainLayout->addWidget(lineEdit);mainLayout->addLayout(lastButton);setLayout(mainLayout);setWindowTitle(tr("Enter"));setFixedHeight(sizeHint().height());
}void Enter::startClicked()
{QString text=lineEdit->text();char* ch;QByteArray ba = text.toLatin1();ch=ba.data();eUser::user.set_name(ch);eUser::user.qname=text;//cout<<"name is "<<eUser::user.Get_Name()<<endl;close();
}void Enter::enableFindButton(const QString &text)
{startButton->setEnabled(!text.isEmpty());
}

displaytime.h

#ifndef DISPLAYTIME_H
#define DISPLAYTIME_H
#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QString>
#include <QPushButton>
#include <class.h>class DisplayTime : public QWidget
{Q_OBJECT
public:long count;QString time;DisplayTime(QWidget *parent = 0);virtual ~DisplayTime();void end();
private:QPushButton *timeLabel;QTimer* timer;
public slots:void timerEvent(QTimerEvent * event);
};
#endif // DISPLAYTIME_H

displaytime.cpp

#include "displaytime.h"
#include<iostream>static int flag=0;
DisplayTime::DisplayTime(QWidget *parent): QWidget(parent)
{count=-1;timeLabel = new QPushButton(this);timer=new QTimer(this);timeLabel->setText("时间: ");timerEvent(0);timer->setInterval(1000); //转化毫秒单位为秒//connect(timer,SIGNAL(timeout()),this,SLOT(timerEvent(QTimerEvent *event)));startTimer(1000);timeLabel->show();
}DisplayTime::~DisplayTime()
{std::cout<<"diaplaytime::~diaplaytime"<<std::endl;flag=0;delete timer;delete timeLabel;
}void DisplayTime::timerEvent(QTimerEvent *event)
{Q_UNUSED(event);if(!flag){count++;}QString time=QString::number(count,10);//转换数据类型timeLabel->setText("时间: "+time);//输出时间结果timeLabel->adjustSize();//自动调整文本大小
}void DisplayTime::end()
{flag=1;
}

player.h

#ifndef Player_H
#define Player_H
#include <QSound>class Player : public QSound
{Q_OBJECT
private:QSound* backsound;QSound* sound1;QSound* sound2;public:void play();void stop();~Player();void setLoops (int l);void play1 ();void stop1 ();void play2 ();void stop2 ();
};
#endif // PLAYER_H

player.cpp

#include "player.h"
#include<iostream>/*Player::Player(): QSound
{backsound = new QSound("D:/game/music/music/Background.wav");
}*/void Player::play()
{backsound = new QSound("D:/game/music/music/Background.wav");backsound->setLoops(-1);backsound->play();
}void Player::stop()
{std::cout<<"stop"<<std::endl;delete backsound;
}Player::~Player()
{backsound->stop();std::cout<<"player::~player"<<std::endl;delete backsound;delete sound1;delete sound2;
}void Player::play1 ()
{std::cout<<"play1"<<std::endl;sound1 = new QSound("D:/game/music/music/select.wav");sound1->play();
}void Player::play2 ()
{std::cout<<"play2"<<std::endl;sound2 = new QSound("D:/game/music/music/pair.wav");sound2->play();
}void Player::stop1 ()
{std::cout<<"stop1"<<std::endl;sound1 = new QSound("D:/game/music/music/select.wav");sound1->stop();
}void Player::stop2 ()
{std::cout<<"stop2"<<std::endl;sound2 = new QSound("D:/game/music/music/pair.wav");sound2->stop();
}

show.h

#ifndef SHOW_H
#define SHOW_H#include <QDialog>class QLabel;
class QPushButton;class Show : public QDialog
{Q_OBJECTpublic:Show(QWidget *parent = 0);signals:void Close(const QString &str,Qt::CaseSensitivity cs);private:QLabel *label;QPushButton *closeButton;
};#endif // SHOW_H

show.cpp

#include "show.h"
#include <QtGui>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <iostream>
#include <fstream>
using namespace std;Show::Show(QWidget *parent): QDialog(parent)
{label=new QLabel;char* name[5];int time[5];char *Name=(char*)malloc(10*sizeof(char));int Time;int rank=0;ifstream out("D:/game/grade/Grade.txt",ios::in);while(out>>Name>>Time){name[rank]=Name;time[rank]=Time;if(rank<=5){rank++;Name=(char*)malloc(10*sizeof(char));}elsebreak;}out.close();label->setText("Best Grade\n\n1."+QString(name[0])+" "+QString::number(time[0])+"\n2."+QString(name[1])+" "+QString::number(time[1])+"\n3."+QString(name[2])+" "+QString::number(time[2])+"\n4."+QString(name[3])+" "+QString::number(time[3])+"\n5."+QString(name[4])+" "+QString::number(time[4])+"\n");closeButton=new QPushButton(tr("Close"));closeButton->setDefault(true);closeButton->setEnabled(true);connect(closeButton,SIGNAL(clicked()),this,SLOT(close()));QVBoxLayout *mainLayout= new QVBoxLayout;mainLayout->addWidget(label);mainLayout->addWidget(closeButton);QHBoxLayout *window=new QHBoxLayout;window->addStretch();window->addLayout(mainLayout);window->addStretch();setLayout(window);int width=280;int height=320;setWindowTitle(tr("Show Grade"));setFixedSize(width,height);
}

[Qt C++] 连连看相关推荐

  1. 果蔬连连看java源代码_《基于Qt的连连看游戏的设计》-毕业论文.doc

    PAGE 精品 摘 要 在现今电子信息高速发展的时代,电子游戏已然成为大众最受欢迎的娱乐消遣方式,经典的连连看是个老少皆宜的小游戏,它实现由各式各样的成对图片组成,然后存储在一个二维的数组中,计算机随 ...

  2. Qt版连连看之极速连连看:设计

    [源码及安装包下载地址]http://code.google.com/p/speedlink/downloads/list [项目展示及相关截图在最后] 术语约定: 面板:连连看中用于拜访小图案的区域 ...

  3. Qt版连连看之极速连连看:界面设计(一)QSS更换主题

    [github地址]speedlink-qt 极速连连看在界面上的特点: 1.支持更换主题 2.画面能够全部切换,基本不使用对话框等方式进行消息提示 3.使用的某些控件(如移动到上面发出声音的按钮.具 ...

  4. Qt版连连看之极速连连看:结构解析

    [github地址]speedlink-qt [源码结构说明] 本来想用Umbrello自动生成类图的,可惜不知道怎么的,我的源码导入之后Umbrello老是死掉,而我又不怎么会画UML图,只好画个概 ...

  5. Qt版连连看之极速连连看:路线判定算法

    [github地址]speedlink-qt 连连看路线判定算法分析 连连看游戏规则:若两个图块相同且它们可以用一条两折之内的折线相连,那么它们消除掉. 用一个二位数组表示连连看的面板,那么每一种图块 ...

  6. Qt实现一个连连看小游戏

    Qt 可以做什么? Qt 虽然经常被当做一个 GUI 库,用来开发图形界面应用程序,但这并不是 Qt 的全部:Qt 除了可以绘制漂亮的界面(包括控件.布局.交互),还包含很多其它功能,比如多线程.访问 ...

  7. QT连连看(RPG玩法)

    QT连连看(RPG玩法) QLink(连连看) 在连连看游戏中,会有⼀个地图,地图上有许多不同种类的⽅块,通过将相同种类的两个⽅块相连,可以将这两个 ⽅块消除,⽤户获得分数. 在整个连连看的过程中,除 ...

  8. 基于QT实现简单的连连看小游戏

    资源下载地址:https://download.csdn.net/download/sheziqiong/85788216 资源下载地址:https://download.csdn.net/downl ...

  9. 在传统连连看游戏的基础上设计出新游戏增量式的创新(结对编程)(2011212026徐颖 2011212023 裴乐)

    一.游戏简介 游戏"连连看"顾名思义就是找出相关联的东西,这个连连看在网上基本是用在小游戏中,就是找出相同的两样东西,在一定的规则之内可以做为相关联处理."连连看&quo ...

最新文章

  1. 安卓Design包之AppBar和Toolbar的联用
  2. RStudio启动后修改文件(数据)读取默认目录
  3. C++_vptr与vtbl,虚函数与虚表
  4. 数字断路器获得商用认证
  5. python的异常处理机制
  6. java.lang包—类Class
  7. 在JDK 8中连接字符串
  8. h5jumppage.php,h5使用webviewjsbridge跟原生交互,点击标签调用2次webview
  9. 同步与异步系列之二 导读目录
  10. 智能硬件(2)---手机访问智能硬件的三种模式
  11. java实现冗余校验_循环冗余校验_循环冗余校验码计算_循环冗余校验 java实现(6)...
  12. UCOS操作系统——消息传递(十二)
  13. 微信小程序 实现简单倒计时功能
  14. NLP(二):n元模型
  15. 笔记本键盘失灵怎么办? 笔记本电脑按键失灵的一般解决办法
  16. 葵花宝典第一招:唐氏均线成交量参数
  17. ubuntu java 中文_Ubuntu下 JAVA GUI 程序汉字显示为方框解决办法
  18. 正宗、创新红烧肉全法
  19. getSharedPreferences()与getSharedPreferences()与getDefaultSharedPreferences()的区别
  20. [bzoj1812][ioi2005]riv(树上dp)

热门文章

  1. ISIS(中间系统到中间系统)及其配置
  2. PIC单片机该怎么加密
  3. 【JavaLearn】(22)jQuery介绍、选择器、事件、动画、DOM编程、操作CSS、表单验证
  4. ArrayList 源码分析
  5. 用c语言写生成 mif文件的软件,MIF文件生成(.MIF File Generator Utility)
  6. 哈工大操作系统课程实验记录
  7. 20190820美团视频一面面经
  8. 机器学习(十二)如何选择学习模型以及如何评估和优化你的学习模型?
  9. [Swift]LeetCode1135. 最低成本联通所有城市 | Connecting Cities With Minimum Cost
  10. 锁仓怎么解_锁仓怎么解锁?解锁的方法是什么?