win32游戏开发(2) --连连看游戏制作(vc++版)
文章索引
- 源代码下载
- 工程目录一览
- 实现细节
源代码下载
附上下载链接:连连看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;//设为开始时间0msint itickcount;if(!GameInitial(hInstance))//创建GameEngine类对象g_pGamereturn 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_hWndRECT 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]++; //该种图片数量加1num++; //方块总个数加1SortPlace(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; //一位数的话将十位补0sort_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; //一位数的话将十位补0sort_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) ) //检测拐点1return true;else if( X_Link(x2,y2,y1) && Y_Link(x1,x2,y1) ) //检测拐点2return 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; //游戏时间+1map[p1.x+2][p1.y+2] = -1; //将已消去的位置X置-1map[row_index+2][col_index+2] = -1; //将已消去的位置Y置-1 fram_sign = false;num-=2; //方块总数-2playSound(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];//种类相同的话,将其位置置-1if( (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的连连看游戏,下次我会具体介绍游戏算法,至于游戏是怎么运行的,函数调用应该放在哪个地方我就不说了.
win32游戏开发(2) --连连看游戏制作(vc++版)相关推荐
- Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机
Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现 ...
- 最大的幻术-游戏开发-我的游戏构思-环境
最大的幻术-游戏开发-我的游戏构思-环境 游戏,具体而言是游戏软件.那么,通过软件来作为载体,通过软件实现内容.一款软件能不能称为游戏在于这款软件所提供的功能是不是游戏体验. 什么是游戏,我无法给出定 ...
- 【iphone游戏开发】Iphone游戏开发之五:游戏场景切换,点阵字的实现和Hiero工具的利用
Andy--清风 原创,转载请注明,谢谢 一.游戏场景切换 在iPhone游戏开发中,游戏之间的场景开发中有很多动画可以实现,具体实现的动画如下: CCTransitionRotoZoom//从大到小 ...
- 游戏开发心得——资料篇——游戏行业的详细职位介绍与定义分析
游戏开发心得--资料篇--游戏行业的详细职位介绍与分析(不定期更新) FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 本篇主要介绍一下博主所了 ...
- 独立游戏 Godot游戏开发日志2游戏本地化对话和任务系统
独立游戏 Godot游戏开发日志2游戏本地化对话和任务系统 开发日志2: 这段时间里我做了游戏本地化系统,对话和任务系统. 首先说说游戏本地化,大多数人可能会采用csv这种翻译格式,但是认为小游戏,没 ...
- 基于cocos2d-x的快速的游戏开发--回合制游戏
2019独角兽企业重金招聘Python工程师标准>>> #基于cocos2d-x的快速的游戏开发--回合制游戏 开发时间:3天 开发工具:cocos2d-x和cocostudio 开 ...
- 微信小游戏开发教程-2D游戏原理讲解
微信小游戏开发教程-2D游戏原理讲解 原理 为了更加形象的描述,这里先上一张图: 背景 a. 首先,我们看到背景好像是一张无限长的图片在向下移动.实际则不然,这是一张顶部和底部刚好重叠的图片.这是一种 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇
马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...
最新文章
- sqlite3数据存储最多存储多少条数据?达到上限如何处理?_在数据爆炸的当下,教你设计一个能实现9个9数据可靠性的存储系统...
- python数学表达式_Python入门笔记——(1)数字与表达式
- ASP.NET Page执行顺序如:OnPreInit()、OnInit()
- Wireshark安装和基本使用
- 【干货】Html与CSS入门学习笔记12-14【完】
- 沉沦17年,这位昔日科技霸主、最值钱企业,终于回来了……
- sml完整形式_411的完整形式是什么?
- 关于游戏架构设计的一些整理吧
- Python 正则模块的应用
- matlab避免使用for_MATLAB新手学习技巧第二波来袭
- 第O题 巧用二进制解答 现在有n个货物,第i个货物的重量是。。。
- ICLR'22 | 图机器学习最近都在研究什么?
- 第二章 部署war包到tomcat
- 攻防世界 Web_php_include write up
- SHA256 算法 加密文件、防文件篡改、文件校验
- python分词代码
- C# winform程序调用屏幕键盘
- Flutter中,解决按下返回键将应用挂起到后台,并不会退出的问题
- 面向大规模商业系统的数据库设计和实践
- 一篇出色的argumentative essay怎么写?