附上下载链接:连连看vc++版源代码
文件功能及关系图:
GameEngine类
成员名 | 作用 |
---|---|
static GameEngine * m_pGameEngine | 指向自身的指针,供外界程序访问 |
HINSTANCE m_hInstance | 实例句柄 |
HWND m_hWnd | 窗口句柄 |
TCHAR m_szWindowClass[32] | 窗口类名 |
TCHAR m_szWndTitle[32] | 窗口标题 |
int m_iWidth,m_iHeight | 窗口宽高 |
int m_iFrameDelay | 调节游戏帧数 |
bool start_sign | 游戏开始标记 |
函数名 | 功能 |
---|---|
GameEngine(HINSTANCE hInstance,LPTSTR szWindowClass,LPTSTR szTitle,int iWidth,int iHeight,int iDelay) | 构造函数创建游戏实例 |
static GameEngine* GetEngine() | 返回成员 *m_pGameEngine |
HINSTANCE GetInstance() | 返回成员 m_hInstance |
HWND GetWnd() | 返回成员 m_hWnd |
void SetWnd(HWND hWnd) | 赋值给 m_hWnd |
LPTSTR GetTitle() | 返回成员 m_szWndTitle |
int GetWidth() | 返回成员 m_iWidth |
void SetWidth(int iWidth) | 赋值给 m_iWidth |
int GetHeight() | 返回成员 m_iHeight |
void SetHeight(int iHeight) | 赋值给 m_iHeight |
int GetDelay() | 返回成员 m_iFrameDelay |
void SetDelay(int iDelay) | 赋值给 m_iFrameDelay |
void setStart(bool sign) | 赋值给 start_sign |
bool getStart() | 返回成员start_sign |
BOOL Initiallize(int cmdShow) | 创建窗口 |
LRESULT HandleEvent(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) | 消息处理 |
GameEgine核心函数(不是GameEngine类函数)
函数名 | 功能 |
---|---|
BOOL GameInitial(HINSTANCE hInstance) | 创建GameEgine类对象 |
void GameStartBg() | 绘制游戏初始画面(游戏界面) |
void setDffclt(int difficult) | 设置游戏难度 |
void GameStart() | 绘制游戏初始画面(开始游戏画面) |
void LButtonDown(int x,int y) | 鼠标单击触发函数 |
void GameEnd() | 游戏结束相关操作 |
void GamePaint() | 游戏重绘 |
void GameCycle() | 游戏循环 |
bool IsResult() | 判断初始化后的2维数组是否有解 |
void set_clue_sign(bool sign) | 设置提示标志 |
bool IsTimeEnd() | 判断时间是否已经用完(倒计时) |
void playSound(int s_sort) | 播放音乐 |
void setSound(int s_sort) | 选择音乐 |
针对连连看设置的全局常量
宏定义 | 常量值 | 作用 |
---|---|---|
row | 16 | 地图行数 |
col | 17 | 地图列数 |
BLANK_STATE | -2 | 用于判断是否加边框(选中加边框,再次点击不加,) |
EASY | 1 | 简单难度 |
NORMAL | 2 | 中等难度 |
HARD | 3 | 困难难度 |
针对连连看游戏设置的变量(声明在llk.h)
变量名 | 作用 |
---|---|
int map[row][col] | 保存图片位置的2维数组(在数组中-1为有图片(之后会赋值),0为无图片) |
int num | 方块总个数 |
int sort_num[39] | 39个图形,每种图形4个 |
int sort_place[39][16] | 记录图形位置,即每种图片4个,位置表示(举例)[1][0]和[1][1]表示行坐标(十位和个位),[1][2]和[1][3]表示列坐标 |
POINT p1,p2 | 记录选中的两个方块位置 |
bool fram_sign | 绘画边框标志,true为有边框,false为无边框 |
int clue_x1,clue_y1,clue_x2,clue_y2 | 用于提示的一对方块(能消掉的) |
bool clue_sign | 提示标志 |
long int score | 分数 |
int game_time | 游戏时间 |
针对连连看游戏设置的函数
函数名 | 功能 |
---|---|
void SortPlace(int p_sort,int p_sort_num,int p_row,int p_col) | 记录图片放置位置 |
void temp_SortPlace(int p_sort,int p_sort_num,int p_row,int p_col) | 临时记录图片放置位置 |
void initial() | 初始化游戏变量 |
void ReInitial() | 重新初始化游戏变量 |
void clue() | 提示边框 |
void set_clue_sign(bool sign) | 设置提示标志 |
void PaintFrame(int g_left,int g_right,int g_top,int g_bottom,int c_index,int r_index) | 方块外框绘制,线条环绕绘制框架 |
bool IsLink(int x1, int y1, int x2, int y2) | 判断选中的两个方块是否可以连接 |
bool X1_Link_X2(int x,int y1,int y2) | X直连 |
bool Y1_Link_Y2(int x1,int x2,int y) | Y直连 |
bool OneCornerLink(int x1,int y1,int x2,int y2) | 判断是否只有一个拐角 |
bool TwoCornerLink(int x1,int y1,int x2,int y2) | 判断是否有两个拐角 |
bool X_Link(int x,int y1,int y2) | 判断有拐角是否能x直连 |
bool Y_Link(int x1,int x2,int y) | 判断有拐角是否能y直连 |
void playStartSound() | 播放游戏开始音乐 |
bool end(int n) | 判断游戏是否结束 |
void paintInfo() | 显示信息 |
在具体实现每一个函数之前,首先要清楚的是应该在哪些地方调用这些函数.因此我们不妨跟随着游戏运行时的执行顺序对这些函数进行放置,并对函数进行定义.
首先是winmain部分:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hpreInstance,LPSTR lpcmdline,int iShowCmd)
{
MSG msg;
static int iticktrigger=0;//设为开始时间0ms
int itickcount;
if(!GameInitial(hInstance))//创建GameEngine类对象g_pGame
return 0;
if(!GameEngine::GetEngine()->Initiallize(SW_SHOWNORMAL))//对窗口类对象wndclass进行赋值并注册,创建窗口
return 0;
::ZeroMemory(&msg,sizeof(msg));
GameStartBg();//绘制游戏背景
while(msg.message!=WM_QUIT)
{
if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
::Sleep(1);
itickcount=::GetTickCount();//返回从程序开始到现在的执行ms数
if(itickcount-iticktrigger>0)
{
if(GameEngine::GetEngine()->getStart() == true)//如果获取到的start_sign为真,开始游戏
{
GamePaint();//游戏重绘
GameCycle();//游戏循环
iticktrigger= itickcount+GameEngine::GetEngine()->GetDelay();//设置下一次重绘时间
}
}
}
}
return TRUE;
}
对winmain中出现的未定义函数进行定义:
BOOL GameInitial(HINSTANCE hInstance)
{
g_pGame=new GameEngine(hInstance,"MYCLASS","连连看 v1.0",960,600,delay);
if(g_pGame==NULL)
return FALSE;
return TRUE;
}
GameEngine::GameEngine(HINSTANCE hInstance, LPTSTR szWindowClass, LPTSTR szTitle,
int iWidth, int iHeight,int iDelay)
{
m_pGameEngine=this;
m_hInstance=hInstance;
m_hWnd=NULL;
if(lstrlen(szWindowClass)>0)
lstrcpy(m_szWindowClass,szWindowClass);
if(lstrlen(szTitle)>0)
lstrcpy(m_szWndTitle,szTitle);
m_iWidth=iWidth;
m_iHeight=iHeight;
m_iFrameDelay=iDelay;
start_sign = false;
}
BOOL GameEngine::Initiallize(int icmdShow)
{
static WNDCLASS wndclass;
wndclass.hInstance=m_hInstance;
wndclass.lpszClassName=m_szWindowClass;
wndclass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH);
if(!RegisterClass(&wndclass))
return FALSE;
m_hWnd=CreateWindow(m_szWindowClass,m_szWndTitle,WS_OVERLAPPEDWINDOW,150,50,m_iWidth,m_iHeight,NULL,NULL,m_hInstance,NULL);
if(!m_hWnd)
return FALSE;
SendMessage(m_hWnd,WM_SETICON,(WPARAM)TRUE,(LPARAM)LoadIcon(GetModuleHandle(NULL),(LPCTSTR)IDI_ICON1));
::ShowWindow(m_hWnd,icmdShow);
::UpdateWindow(m_hWnd);
return TRUE;
}
void GameStartBg()
{
HWND hwnd = g_pGame->GetWnd();
dc = ::GetDC(hwnd);
bufdc = ::CreateCompatibleDC(dc);
mdc = ::CreateCompatibleDC(dc);
mid = ::CreateCompatibleBitmap(dc,960,600);
bg = (HBITMAP)::LoadImage(NULL,"./image/bg.bmp",IMAGE_BITMAP,960,600,LR_LOADFROMFILE); //加载背景图片
::SelectObject(mdc,bg);
::BitBlt(dc,0,0,960,600,mdc,0,0,SRCCOPY);
::ReleaseDC(hwnd,bufdc);
::ReleaseDC(hwnd,mdc);
}
void GamePaint()
{
HWND hwnd = g_pGame->GetWnd();
int i,j,m;
//重绘背景
::SelectObject(bufdc,game_bg);
::BitBlt(mdc,0,0,960,600,bufdc,0,0,SRCCOPY);
//重绘游戏区
for(i = 0;i < row;i++)
{
for(j = 0;j < col;j++)
{
::ReleaseDC(hwnd,bufdc);
for(m = 1;m <= 39;m++)
{
if(map[i][j] == m)
{
::SelectObject(bufdc,pic[m-1]);
::BitBlt(mdc,game_left+j*31-2*31,game_top+i*34-2*34,31,34,bufdc,0,0,SRCCOPY);
}
}
}
}
//绘制边框
if(fram_sign == true)
PaintFrame(game_left,game_right,game_top,game_bottom,g_col_index,g_row_index);//绘制矩形边框
if(clue_sign == true)
clue();//绘制提示框
//显示信息
paintInfo();
::BitBlt(dc,0,0,960,600,mdc,0,0,SRCCOPY);
::ReleaseDC(hwnd,bufdc);
::ReleaseDC(hwnd,mdc);
}
//方块外框绘制,线条环绕绘制框架
void PaintFrame(int g_left,int g_right,int g_top,int g_bottom,int c_index,int r_index)
{
HWND hwnd = g_pGame->GetWnd();
::SelectObject(mdc,pen);
::MoveToEx(mdc,g_left+c_index*31,g_top+r_index*34,NULL);
::LineTo(mdc,g_left+c_index*31+31,g_top+r_index*34);
::LineTo(mdc,g_left+c_index*31+31,g_top+r_index*34+34);
::LineTo(mdc,g_left+c_index*31,g_top+r_index*34+34);
::LineTo(mdc,g_left+c_index*31,g_top+r_index*34);
}
//提示边框
void clue()
{
fram_sign = false;
//方块外框绘制,线条环绕绘制框架
PaintFrame(game_left,game_right,game_top,game_bottom,clue_y1,clue_x1);
PaintFrame(game_left,game_right,game_top,game_bottom,clue_y2,clue_x2);
}
//显示信息
void paintInfo()
{
char s_level[20]={0};
char s_score[20]={0};
char s_time[20]={0};
if( difficult == EASY)
::TextOut(mdc,100,34*2,"级别: 简单",10);
else if( difficult == NORMAL)
::TextOut(mdc,100,34*2,"级别: 中等",10);
else if( difficult == HARD)
::TextOut(mdc,100,34*2,"级别: 难",8);
::sprintf(s_score,"得分: %d",score);
::sprintf(s_time,"剩余时间: %d",game_time);
::TextOut(mdc,100,34*2+25,s_score,strlen(s_score));
::TextOut(mdc,100,34*2+50,s_time,strlen(s_time));
::TextOut(mdc,100,34*2+75+50,"“空格”键: 提示!",18);
}
void GameCycle()
{
}
接下来是最重要的消息机制设置,
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
return GameEngine::GetEngine()->HandleEvent(hWnd,msg,wParam,lParam);
}
对于HandleEvent(hWnd,msg,wParam,lParam)的定义:
LRESULT GameEngine::HandleEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int m,x,y;
switch(msg)
{
case WM_SYSCOMMAND: //使最大化失效
if(wParam == SC_MAXIMIZE)
return 0;
break;;
case WM_COMMAND:
{
m = LOWORD(wParam);
switch(m)
{
case ID_EASY: //处理菜单“简单”事件
start_sign = true;
setDffclt(1);
GameStart();
::SetTimer(m_hWnd,1,1000,NULL);
break;
case ID_NORMAL: //处理菜单“正常”事件
start_sign = true;
setDffclt(2);
GameStart();
::SetTimer(m_hWnd,1,1000,NULL);
break;
case ID_HARD: //处理菜单“难”事件
start_sign = true;
setDffclt(3);
GameStart();
::SetTimer(m_hWnd,1,1000,NULL);
break;
case ID_EXIT: //处理菜单“退出”事件
::PostQuitMessage(0);
break;
case ID_SOUND0: //处理菜单“音乐1”事件
setSound(0);
break;
case ID_SOUND1: //处理菜单“音乐2”事件
setSound(1);
break;
case ID_SOUND2: //处理菜单“音乐3”事件
setSound(2);
break;
case ID_HELP1: //处理菜单“帮助”事件
::MessageBox(hWnd," 操作说明:\n1. 选择“音乐”\n2. 选择游戏难度进行游戏(默认是音乐1)\n\n按键说明:\n1. “空格”键将会有提示出现\n3.选择“退出”,退出整个游戏\n","说明",MB_OK);
break;
case ID_ABOUT1: //处理菜单“关于”事件
::MessageBox(hWnd,"版本:\t连连看 v1.0","关于",MB_OK);
break;
}
}
break;
case WM_TIMER: //响应定时器
if( IsTimeEnd() )
start_sign = false;
break;
case WM_CHAR:
switch(wParam)
{
case ' ': //处理“空格”事件
set_clue_sign(true);
break;
}
break;
case WM_LBUTTONDOWN: //处理鼠标左键单击事件
x = LOWORD(lParam);
y = HIWORD(lParam);
LButtonDown(x,y);
break;
case WM_DESTROY:
GameEnd();
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd,msg,wParam,lParam);
}
对在消息机制出现的未定义函数进行定义:
void setDffclt(int n)
{
difficult = n;
if(n == EASY) //简单
game_time = 180;
if(n == NORMAL) //中等
game_time = 120;
if(n == HARD) //难
game_time = 60;
}
void GameStart()
{
HWND hwnd = g_pGame->GetWnd();//获取窗口句柄m_hWnd
RECT rect;
char s[16];
int i,j,m;
//载入方块图片
for(i = 0;i < 39;i++)
{
sprintf(s,"./image/%d.bmp",i+1);
pic[i] = (HBITMAP)::LoadImage(NULL,s,IMAGE_BITMAP,31,34,LR_LOADFROMFILE);
}
initial(); //初始化
IsResult(); //判断是否有解
playStartSound(); //播放开始音乐
dc = ::GetDC(hwnd);
bufdc = ::CreateCompatibleDC(dc);
mdc = ::CreateCompatibleDC(dc);
mid = ::CreateCompatibleBitmap(dc,960,600);
::SelectObject(mdc,mid);
//绘制背景
game_bg = (HBITMAP)::LoadImage(NULL,"./image/GameBg.bmp",IMAGE_BITMAP,960,600,LR_LOADFROMFILE);
::SelectObject(bufdc,game_bg);
::BitBlt(mdc,0,0,960,600,bufdc,0,0,SRCCOPY);
//绘制游戏区
::GetClientRect(hwnd,&rect);
game_left = int((rect.left+rect.right)/2-6.5*31);
game_right = int((rect.left+rect.right)/2+6.5*31);
game_top = int((rect.bottom+rect.top)/2-6*34);
game_bottom = int((rect.bottom+rect.top)/2+6*34);
for(i = 0;i < row;i++)
{
for(j = 0;j < col;j++)
{
::ReleaseDC(hwnd,bufdc);
for(m = 1;m <= 39;m++)
{
if(map[i][j] == m)
{
::SelectObject(bufdc,pic[m-1]);
::BitBlt(mdc,game_left+j*31-2*31,game_top+i*34-2*34,31,34,bufdc,0,0,SRCCOPY);
break;
}
}
}
}
::BitBlt(dc,0,0,960,600,mdc,0,0,SRCCOPY);
::ReleaseDC(hwnd,bufdc);
::ReleaseDC(hwnd,mdc);
}
void initial()
{
srand((unsigned)time(NULL));
int i,j;
int sort;
score = 0;
p1.x = BLANK_STATE;
p1.y = BLANK_STATE;
p2.x = BLANK_STATE;
p2.y = BLANK_STATE;
pen = ::CreatePen(PS_SOLID,3,RGB(255,0,0));
fram_sign = false;
clue_sign = false;
//清空map二维数组
for(i = 0;i < row-4;i++)
{
for(j = 0;j < col-4;j++)
map[i+2][j+2] = -1;
}
//初始化sort_num数组
for(i = 0;i < 39;i++)
sort_num[i] = 0;
//初始化sort_place二维数组
for(i = 0;i < 39;i++)
{
for(j = 0;j < 16;j++)
sort_place[i][j] = -1;
}
//初始化map二维数组
for(i = 0;i < row;i++)
{
for(j = 0;j < col;j++)
{
if(map[i][j] == -1)
{
while(1)
{
sort = rand()%39+1; //产生随机数
if(sort_num[sort - 1]<4)
{
map[i][j] = sort; //放进地图中
sort_num[sort - 1]++; //该种图片数量加1
num++; //方块总个数加1
SortPlace(sort,sort_num[sort-1],i-2,j-2); //记录图片放置位置
break;
}
}
}
}
}
}
//记录图片放置位置
void SortPlace(int p_sort,int p_sort_num,int p_row,int p_col)
{
if(p_row < 10)
{
sort_place[p_sort-1][p_sort_num*4-4] = 0; //一位数的话将十位补0
sort_place[p_sort-1][p_sort_num*4-3] = p_row; //取个位
}
else
{
sort_place[p_sort-1][p_sort_num*4-4] = p_row/10; //取十位
sort_place[p_sort-1][p_sort_num*4-3] = p_row%10; //取个位
}
if(p_col < 10)
{
sort_place[p_sort-1][p_sort_num*4-2] = 0; //一位数的话将十位补0
sort_place[p_sort-1][p_sort_num*4-1] = p_col; //取个位
}
else
{
sort_place[p_sort-1][p_sort_num*4-2] = p_col/10; //取十位
sort_place[p_sort-1][p_sort_num*4-1] = p_col%10; //取个位
}
}
//判断是否有解
bool IsResult()
{
int i,j,m,n;
POINT pp[4];
//取出对应种类方块的位置
for(i = 0;i < 39;i++)
{
for(j = 0;j < 16;j+=4)
{
pp[j/4].x = sort_place[i][j]*10 + sort_place[i][j+1];
pp[j/4].y = sort_place[i][j+2]*10 + sort_place[i][j+3];
}
//两两比较,判断是否存在能连通的方块
for(m = 0;m < 3;m++)
{
for(n = m+1;n < 4;n++)
{
if( IsLink(pp[m].x,pp[m].y,pp[n].x,pp[n].y) )
{
clue_x1 = pp[m].x;
clue_y1 = pp[m].y;
clue_x2 = pp[n].x;
clue_y2 = pp[n].y;
return true;
}
}
}
}
::MessageBox(NULL,"无解,将重列","提醒",MB_OK);
return false;
}
bool IsLink(int x1, int y1, int x2, int y2)
{
//X直连
if(x1 == x2)
{
if( X1_Link_X2(x1,y1,y2) )
return true;
}
//Y直连
if( y1 == y2 )
{
if( Y1_Link_Y2(x1,x2,y1) )
return true;
}
//一个拐角
if( OneCornerLink(x1,y1,x2,y2) )
return true;
//两个拐角
if( TwoCornerLink(x1,y1,x2,y2) )
return true;
return false;
}
//一个拐角
bool OneCornerLink(int x1,int y1,int x2,int y2)
{
if( X_Link(x1,y1,y2) && Y_Link(x2,x1,y2) ) //检测拐点1
return true;
else if( X_Link(x2,y2,y1) && Y_Link(x1,x2,y1) ) //检测拐点2
return true;
return false;
}
//两个拐角
bool TwoCornerLink(int x1,int y1,int x2,int y2)
{
int i;
int aa;
for(i = y1+1;i <= col-4;i++) //右检测
{
aa=map[x1+2][i+2];
if(map[x1+2][i+2] > 0)
{
break;
}
if( OneCornerLink(x1,i,x2,y2) )
return true;
}
for(i = x1+1;i <= row-4;i++) //下检测
{
aa=map[i+2][y1+2];
if(map[i+2][y1+2] > 0)
{
break;
}
if( OneCornerLink(i,y1,x2,y2) )
return true;
}
for(i = y1-1;i >= 0;i--) //左检测
{
aa=map[x1+2][i+2];
if(map[x1+2][i+2] > 0)
{
break;
}
if( OneCornerLink(x1,i,x2,y2) )
return true;
}
for(i = x1-1;i >= 0;i--) //上检测
{
aa=map[i+2][y1+2];
if(map[i+2][y1+2] > 0)
{
break;
}
if( OneCornerLink(i,y1,x2,y2) )
return true;
}
return false;
}
//播放游戏开始音乐
void playStartSound()
{
PlaySound("./music/start.wav",NULL,SND_ASYNC);
}
//选择音乐
void setSound(int s_sort)
{
sound_sort = s_sort;
}
//播放音乐
void playSound(int s_sort)
{
char ss_sort[20]={0};
::sprintf(ss_sort,"./music/clear%d.wav",s_sort);
PlaySound(ss_sort,NULL,SND_ASYNC);
}
//左键按下
void LButtonDown(int x,int y)
{
int m;
POINT pp[4];
int xx,yy;
int sort;
int col_index,row_index;
xx = x - game_left;
yy = y - game_top;
if(xx<=0 || yy<=0 || xx>=(col-4)*31 || yy>=(row-4)*34) //判断是否在游戏区内
return;
col_index = xx/31; //转化成列下标
row_index = yy/34; //转化成行下标
if( (map[row_index+2][col_index+2] != -1) && (map[row_index+2][col_index+2] != 0) )
{
if(p1.x == BLANK_STATE) //假设尚未记录第一个方块
{
p1.x = row_index;
p1.y = col_index;
PaintFrame(game_left,game_right,game_top,game_bottom,col_index,row_index); //方块外框绘制,线条环绕绘制框架
fram_sign = true;
g_row_index = row_index;
g_col_index = col_index;
return;
}
else
{
if( p1.x==row_index && p1.y==col_index ) //第二次点击本身
{
p1.x = BLANK_STATE;
fram_sign = false;
return;
}
else //第二次点击非本身
{
if(map[p1.x+2][p1.y+2] == map[row_index+2][col_index+2]) //第一次和第二次点击的两个方块类型一样
{
if( IsLink(p1.x,p1.y,row_index,col_index) ) //可以连接,消去连接的2个方块
{
sort = map[p1.x+2][p1.y+2];
score += 100; //计分
game_time += 1; //游戏时间+1
map[p1.x+2][p1.y+2] = -1; //将已消去的位置X置-1
map[row_index+2][col_index+2] = -1; //将已消去的位置Y置-1
fram_sign = false;
num-=2; //方块总数-2
playSound(sound_sort); //播放消去的声音
if (end(num) ) //判断游戏是否结束
{
g_pGame->setStart(false);
return;
}
sort_num[sort-1]-=1; //对应种类的方块数量-1
//写入对应种类方块的位置
for(m = 0;m < 16;m+=4)
{
//取出相同种类所对应的位置
pp[m/4].x = sort_place[sort-1][m]*10 + sort_place[sort-1][m+1];
pp[m/4].y = sort_place[sort-1][m+2]*10 + sort_place[sort-1][m+3];
//种类相同的话,将其位置置-1
if( (pp[m/4].x==p1.x) && (pp[m/4].y==p1.y) )
{
sort_place[sort-1][m] = -1;
sort_place[sort-1][m+1] = -1;
sort_place[sort-1][m+2] = -1;
sort_place[sort-1][m+3] = -1;
}
if( (pp[m/4].x == row_index) && (pp[m/4].y == col_index) )
{
sort_place[sort-1][m] = -1;
sort_place[sort-1][m+1] = -1;
sort_place[sort-1][m+2] = -1;
sort_place[sort-1][m+3] = -1;
}
}
p1.x = BLANK_STATE;
clue_sign = false;
//判断是否有解
while( !IsResult() )
{
ReInitial();
}
}
else //不可以连接
{
p1.x = row_index;
p1.y = col_index;
g_row_index = row_index;
g_col_index = col_index;
}
return;
}
else //第一次和第二次点击的两个方块类型不一样
{
p1.x = row_index;
p1.y = col_index;
g_row_index = row_index;
g_col_index = col_index;
return;
}
}
}
}
}
这样写搞得我也晕了,可能会导致我漏了一些没写出来的未定义函数(因为这是我项目完成后写的博客,如果是边写边做我可以通过调试知道那些函数还没定义),为了方便观察,下面粘贴出函数与函数之间的调用关系.
Winmain:
wndprc:
貌似还有游戏相关算法还没有介绍,有点累了,对连连看游戏算法感兴趣的可以下载我上传的vc++版连连看文件,我有写注释.因为我还要试着用老师给的游戏引擎再写一版vs2010的连连看游戏,下次我会具体介绍游戏算法,至于游戏是怎么运行的,函数调用应该放在哪个地方我就不说了.