www.gusucode.com > 连连看游戏VC++源代码-源码程序 > 连连看游戏VC++源代码-源码程序\code\ZLLKView.cpp
//Download by http://www.NewXing.com // ZLLKView.cpp : implementation of the CZLLKView class // /* Made by zhouyuhui in 2005.8.25 mail: xuchangyuhui@sohu.com It was made for my girl friend. Thank for your download. 2006.09.09 */ #include "stdafx.h" #include "ZLLK.h" #include "ZLLKDoc.h" #include "ZLLKView.h" #include "RecordDlg.h" #include "AddDlg.h" #include "mmsystem.h"//声音效果 #pragma comment(lib,"WINMM.LIB") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define tilex(y) y*BMP_WIDTH+DRAW_LEFT #define tiley(x) x*BMP_HEIGHT+DRAW_TOP extern int g_userlevel; extern int g_usergate; extern int g_userscore; DWORD oldtime=0,newtime; //用来判断连击 ///////////////////////////////////////////////////////////////////////////// // CZLLKView IMPLEMENT_DYNCREATE(CZLLKView, CView) BEGIN_MESSAGE_MAP(CZLLKView, CView) //{{AFX_MSG_MAP(CZLLKView) ON_COMMAND(ID_MENU_SCORE, OnMenuScore) ON_COMMAND(ID_MENU_FIRST, OnMenuFirst) ON_UPDATE_COMMAND_UI(ID_MENU_FIRST, OnUpdateMenuFirst) ON_COMMAND(ID_MENU_BACK, OnMenuBack) ON_UPDATE_COMMAND_UI(ID_MENU_BACK, OnUpdateMenuBack) ON_COMMAND(ID_MENU_EXIT, OnMenuExit) ON_WM_KEYDOWN() ON_WM_LBUTTONDOWN() ON_COMMAND(ID_MENU_INFO, OnMenuInfo) ON_UPDATE_COMMAND_UI(ID_MENU_INFO, OnUpdateMenuInfo) ON_COMMAND(ID_MENU_SORT, OnMenuSort) ON_UPDATE_COMMAND_UI(ID_MENU_SORT, OnUpdateMenuSort) ON_COMMAND(ID_MENU_STOP, OnMenuStop) ON_UPDATE_COMMAND_UI(ID_MENU_STOP, OnUpdateMenuStop) ON_COMMAND(ID_MENU_EFFECT, OnMenuEffect) ON_UPDATE_COMMAND_UI(ID_MENU_EFFECT, OnUpdateMenuEffect) ON_COMMAND(ID_MENU_MUSIC, OnMenuMusic) ON_UPDATE_COMMAND_UI(ID_MENU_MUSIC, OnUpdateMenuMusic) ON_WM_TIMER() ON_COMMAND(ID_MENU_HELP, OnMenuHelp) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CZLLKView construction/destruction CZLLKView::CZLLKView() { // TODO: add construction code here InitMap(); bingame=false; //没有进入游戏 //是否第二次点击 bSecondClicked=false; //初级 bfirst=false; bstop=false; bmusic=true; //图片坐标 xindex=-1; yindex=-1; //初始化有声音 bsoundeffect=true; //提示次数初始化 m_tishinumber=10; m_sortnumber=5; m_dotNumber=0; } CZLLKView::~CZLLKView() { } BOOL CZLLKView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs bitmap1.LoadBitmap(IDB_BITMAP_FOREFACE); bitmap2.LoadBitmap(IDB_BITMAP_FACE); return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CZLLKView drawing void CZLLKView::OnDraw(CDC* pDC) { CZLLKDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // 渲染客户去 CRect rcBlock; rcBlock.SetRect(0,0,660,640); pDC->FillSolidRect(&rcBlock,RGB(100,100,200)); CDC dcMemory1,dcMemory2; dcMemory1.CreateCompatibleDC(pDC); dcMemory1.SelectObject(&bitmap1); dcMemory2.CreateCompatibleDC(pDC); dcMemory2.SelectObject(&bitmap2); //输出图形 int i,j; for(i=1;i<=ROW_NUMBER;i++) { for(j=1; j<=LINE_NUMBER;j++) { if(llk_map[i][j].PicIndex>0) { if(llk_map[i][j].state==0) pDC->BitBlt(tilex(j),tiley(i), PIC_WIDTH,PIC_HEIGHT,&dcMemory1,PIC_WIDTH*(llk_map[i][j].PicIndex-1),0 ,SRCCOPY); else if(llk_map[i][j].state==1) pDC->BitBlt(tilex(j),tiley(i), PIC_WIDTH,PIC_HEIGHT,&dcMemory2,PIC_WIDTH*(llk_map[i][j].PicIndex-1),0 ,SRCCOPY); } } } if(bfirst) { DrawRectangleHollow(); DrawInfo(120,20,"剩余时间"); DrawInfo(20,20,"级别:"); DrawInfo(20,40,"关卡:"); DrawInfo(20,60,"重列:"); DrawInfo(20,80,"提示:"); DrawInfo(540,20,"分数:"); DrawInfo2(60,20,g_userlevel); DrawInfo2(60,40,g_usergate); DrawInfo2(60,60,m_sortnumber); DrawInfo2(60,80,m_tishinumber); DrawInfo2(560,40,g_userscore); } } ///////////////////////////////////////////////////////////////////////////// // CZLLKView printing BOOL CZLLKView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CZLLKView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CZLLKView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CZLLKView diagnostics #ifdef _DEBUG void CZLLKView::AssertValid() const { CView::AssertValid(); } void CZLLKView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CZLLKDoc* CZLLKView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CZLLKDoc))); return (CZLLKDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CZLLKView message handlers void CZLLKView::OnMenuScore() { // TODO: Add your command handler code here CRecordDlg recorddlg; recorddlg.DoModal(); } void CZLLKView::InitMap() { int i,j; for(i=0;i<VIRTUAL_ROW;i++) for(j=0;j<VIRTUAL_LINE;j++) { llk_map[i][j].PicIndex=0; llk_map[i][j].state=0; llk_map[i][j].event=0; } // for(i=0;i<15;i++) { pic_number[i]=0; pic_place[i+1]=NULL; } } void CZLLKView::InitEvent() { int i,x=0,y=0,tempx,tempy; int randevent,randplace; for(i=0;i<5;i++) //总共5次事件 { //随机计算 位置 randplace=rand()%(ROW_NUMBER*LINE_NUMBER)+1; tempy=randplace%LINE_NUMBER; tempx=randplace/LINE_NUMBER; if(tempx!=x&&tempy!=y) { x=tempx; y=tempy; //随机事件 randevent=rand()%3+1; //4为 事件总数 llk_map[tempx][tempy].event=randevent; } } } void CZLLKView::OnMenuFirst() { // TODO: Add your command handler code here int i,j; int temprand; CString str; CRect rect; //产生随机序列 (但是做得随机性不好) srand((unsigned)time(NULL)); for(i=1;i<=ROW_NUMBER;i++) for(j=1;j<=LINE_NUMBER;j++) { while(1) { temprand=rand()%15; // 产生0-14的随机数 if(pic_number[temprand]<6) { pic_number[temprand]++; llk_map[i][j].state=0; llk_map[i][j].event=0; llk_map[i][j].PicIndex=temprand+1; // 1-15 break; } } } //列出每幅图片所有的位置 ListPicPlace(); //初始化事件 InitEvent(); g_userscore=0; g_userlevel=1; g_usergate=1; //程序控制 bingame=true; bfirst=true; DrawRectangleHollow(); m_nUpper=0; DrawProgress(m_nUpper); // 总共400个时间 m_nSpeed=2; SetTimer(1,1200,0); DrawInfo(120,20,"剩余时间"); DrawInfo(20,20,"级别:"); DrawInfo(20,40,"关卡:"); DrawInfo(20,60,"重列:"); DrawInfo(20,80,"提示:"); DrawInfo(540,20,"分数:"); DrawInfo2(60,20,g_userlevel); DrawInfo2(60,40,g_usergate); DrawInfo2(60,60,m_sortnumber); DrawInfo2(60,80,m_tishinumber); DrawInfo2(560,40,g_userscore); DrawMap(); //音效 //if(m_soundeffect) // PlaySound(MAKEINTRESOURCE(IDR_WAVE_NEWGAME),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); } void CZLLKView::DrawMap() { //输出图形 CDC *pDc; pDc=GetDC(); CDC dcMemory; dcMemory.CreateCompatibleDC(pDc); dcMemory.SelectObject(&bitmap1); int i,j; for(i=1;i<=ROW_NUMBER;i++) { for(j=1; j<=LINE_NUMBER;j++) { if(llk_map[i][j].PicIndex>0) { if(llk_map[i][j].state==0) pDc->BitBlt(tilex(j),tiley(i), PIC_WIDTH,PIC_HEIGHT,&dcMemory,PIC_WIDTH*(llk_map[i][j].PicIndex-1),0 ,SRCCOPY); } } } } void CZLLKView::DrawBlank() { CDC *pDc; pDc=GetDC(); // 渲染客户去 CRect rcBlock; rcBlock.SetRect(0,0,660,640); pDc->FillSolidRect(&rcBlock,RGB(100,100,200)); } void CZLLKView::DrawFace(int xindex,int yindex,int PicIndex,int state) { CDC *pDc; pDc=GetDC(); CDC dcMemory1,dcMemory2; if(state) { dcMemory2.CreateCompatibleDC(pDc); dcMemory2.SelectObject(&bitmap2); pDc->BitBlt(tilex(yindex),tiley(xindex),PIC_WIDTH-4,PIC_HEIGHT-4,&dcMemory2,PIC_WIDTH*(PicIndex-1),0,SRCCOPY); } else { dcMemory1.CreateCompatibleDC(pDc); dcMemory1.SelectObject(&bitmap1); pDc->BitBlt(tilex(yindex),tiley(xindex),PIC_WIDTH-4,PIC_HEIGHT-4,&dcMemory1,PIC_WIDTH*(PicIndex-1),0,SRCCOPY); } } void CZLLKView::DrawFaceBlank(int xindex,int yindex) { CDC *pDc; pDc=GetDC(); CRect rect; if(xindex==9||yindex==10) { rect.top=tiley(xindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(yindex); rect.right=rect.left+PIC_WIDTH; pDc->FillSolidRect(&rect,RGB(100,100,200)); } else { rect.top=tiley(xindex); rect.bottom=rect.top+PIC_HEIGHT-4; rect.left=tilex(yindex); rect.right=rect.left+PIC_WIDTH-4; pDc->FillSolidRect(&rect,RGB(100,100,200)); } } void CZLLKView::OnUpdateMenuFirst(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bfirst) pCmdUI->Enable(false); else pCmdUI->Enable(true); } void CZLLKView::OnMenuBack() { // TODO: Add your command handler code here KillTimer(1); bingame=false; bfirst=false; bSecondClicked=false; bstop=false; m_dotNumber=0; m_tishinumber=10; m_sortnumber=5; //图片坐标 xindex=-1; yindex=-1; InitMap(); DrawBlank(); } void CZLLKView::OnUpdateMenuBack(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bfirst) pCmdUI->Enable(true); else pCmdUI->Enable(false); } void CZLLKView::OnMenuExit() { // TODO: Add your command handler code here PostQuitMessage(0); } void CZLLKView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default switch(nChar) { case VK_F2: OnMenuFirst(); break; case VK_F5: OnMenuInfo(); break; case VK_F6: OnMenuSort(); break; case VK_F7: OnMenuStop(); break; default: break; } CView::OnKeyDown(nChar, nRepCnt, nFlags); } void CZLLKView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default int iTop,iLeft,iRight,iBottom; CRect rect; iTop=DRAW_TOP+BMP_HEIGHT; iBottom=iTop+BMP_HEIGHT*ROW_NUMBER; iLeft=DRAW_LEFT+BMP_WIDTH; iRight=iLeft+BMP_WIDTH*LINE_NUMBER; //进入了游戏,并且鼠标在这个范围内 if(bingame&&point.x>iLeft&&point.x<iRight&&point.y>iTop&&point.y<iBottom) { if(bsoundeffect) PlaySound(MAKEINTRESOURCE(IDR_WAVE_DOWN),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); int tempx,tempy; // 地图中的行列值 int xtempindex,ytempindex; tempy=point.x/BMP_WIDTH; tempx=point.y/BMP_HEIGHT; xtempindex=tempx-1; ytempindex=tempy-2; CString str; //所点击图形编号大于0 就是此位置有图像 if(llk_map[xtempindex][ytempindex].PicIndex>0) { if(bSecondClicked) //是第二次点击 { //str.Format("%d,%d,%d,%d,%d,%d",xtempindex,ytempindex,xindex,yindex,llk_map[xtempindex][ytempindex].PicIndex,llk_map[xindex][yindex].PicIndex); //AfxMessageBox(str); //判断点击的是不是上次点击的图片 if((xtempindex==xindex)&&(ytempindex==yindex))//如果是 { llk_map[xtempindex][ytempindex].state=0; rect.top=tiley(xtempindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(ytempindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); //DrawFace(xtempindex,ytempindex,llk_map[xtempindex][ytempindex].PicIndex,0); } else//如果不是上次点击的图片 判断图片类型是否相同 { if(llk_map[xtempindex][ytempindex].PicIndex==llk_map[xindex][yindex].PicIndex) { //如果图片类型相同:判断是否连通(xindex yindex) (xtempindex ytempindex) bsuccess=CheckConnection(xindex,yindex,xtempindex,ytempindex); if(bsuccess) //如果连通 则消除 并且更新图片位置列表 { //判断连击次数 newtime=timeGetTime(); if((newtime-oldtime)>2000) m_dotNumber=0; else m_dotNumber++; oldtime=newtime; //如果连击次数大于0 //更新用户分数 g_userscore+=m_dotNumber*50; g_userscore+=100; DrawInfo2(560,40,g_userscore); // 更新连机次数 CString str; if(m_dotNumber>0) { str.Format("连击%d次",m_dotNumber); DrawInfo3(140,70,str); } //更新滚动条 m_nUpper+=5; //更新图片位置列表 ReleasePicPlace(llk_map[xindex][yindex].PicIndex,xindex,yindex); ReleasePicPlace(llk_map[xtempindex][ytempindex].PicIndex,xtempindex,ytempindex); if(bsoundeffect) PlaySound(MAKEINTRESOURCE(IDR_WAVE_OK),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); //把该位置图片号设为0 llk_map[xtempindex][ytempindex].PicIndex=0; llk_map[xindex][yindex].PicIndex=0; rect.top=tiley(xtempindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(ytempindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); //DrawFaceBlank(xtempindex,ytempindex); rect.top=tiley(xindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(yindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); //DrawFaceBlank(xindex,yindex); //判断位置事件 if(llk_map[xtempindex][ytempindex].event==1||llk_map[xindex][yindex].event==1) { m_tishinumber++; DrawInfo3(140,70,"将奖励提示1次"); } else if (llk_map[xtempindex][ytempindex].event==2||llk_map[xindex][yindex].event==2) { m_sortnumber++; DrawInfo3(140,70,"将奖重列1次"); } else if(llk_map[xtempindex][ytempindex].event==3||llk_map[xindex][yindex].event==3) { g_userscore+=100; DrawInfo3(140,70,"将奖分数100"); } } else // 不连通 { if(bsoundeffect) PlaySound(MAKEINTRESOURCE(IDR_WAVE_NO),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); llk_map[xindex][yindex].state=0; rect.top=tiley(xindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(yindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); } } else //图片类型不同 { if(bsoundeffect) PlaySound(MAKEINTRESOURCE(IDR_WAVE_NO),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); llk_map[xindex][yindex].state=0; rect.top=tiley(xindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(yindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); //DrawFace(xindex,yindex,llk_map[xindex][yindex].PicIndex,0); } } xindex=-1; yindex=-1; } else //是第一次点击 { llk_map[xtempindex][ytempindex].state=1; rect.top=tiley(xtempindex); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(ytempindex); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); //DrawFace(xtempindex,ytempindex,llk_map[xtempindex][ytempindex].PicIndex,1); xindex=xtempindex; yindex=ytempindex; } } //判断是否消完,弹出对话框 纪录分数 if(IsPicEmpty()) //已经消完 { //PlaySound(MAKEINTRESOURCE(IDR_WAVE_WIN),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC); bingame=false; KillTimer(1); //对话框 CAddDlg adddlg; if(adddlg.DoModal()==IDOK) { OnMenuBack(); } } else //(!IsPicEmpty()) //没有消完 { //判断是否无解 if(IsNoConnection()) { AfxMessageBox("已经无法消除",MB_OK); OnMenuBack(); } } bSecondClicked=!bSecondClicked; } CView::OnLButtonDown(nFlags, point); } bool CZLLKView::CheckConnection(int x1, int y1, int x2, int y2) { int i,temp; //分为八种 if((x1==x2))//同一行 { if(IsLineConnection(x1,y1,x2,y2)) return true; else { for(i=1;i<=x1;i++) { if(IsLinePicEmpty(x1,y1,(x1-i),y1)) if(IsNotLineConnection((x1-i),y1,x2,y2)) return true; } temp=VIRTUAL_ROW-x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1+i),y1)) if(IsNotLineConnection((x1+i),y1,x2,y2)) return true; } } } if((y1==y2))//同一列 { if(IsLineConnection(x1,y1,x2,y2)) return true; else { for(i=1;i<=y1;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1-i))) if(IsNotLineConnection(x1,(y1-i),x2,y2)) return true; } temp=VIRTUAL_LINE-y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1+i))) if(IsNotLineConnection(x1,(y1+i),x2,y2)) return true; } } } if((x2>x1)&&(y2>y1)) //(x2,y2)在(x1,y1)右下方 { if(IsNotLineConnection(x1,y1,x2,y2))//先判断只有一个折点 * 代表两个点 // *----------| return true; // | | // |__________* //先往下判断 temp=VIRTUAL_ROW-x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1+i),y1)) { if(IsNotLineConnection((x1+i),y1,x2,y2)) return true; } } //往右判断 temp=VIRTUAL_LINE-y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1+i))) { if(IsNotLineConnection(x1,(y1+i),x2,y2)) return true; } } //往上判断 for(i=1;i<=x1;i++) { if(IsLinePicEmpty(x1,y1,(x1-i),y1)) { if(IsNotLineConnection((x1-i),y1,x2,y2)) return true; } } //往左判断 for(i=1;i<=y1;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1-1))) { if(IsNotLineConnection(x1,(y1-1),x2,y2)) return true; } } } if((x2>x1)&&(y2<y1)) //(x2,y2)在(x1,y1)左下方 { if(IsNotLineConnection(x1,y1,x2,y2))//先判断只有一个折点 * 代表两个点 // |----------* return true; // | | // *__________| //先往下判断 temp=VIRTUAL_ROW-x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1+i),y1)) { if(IsNotLineConnection((x1+i),y1,x2,y2)) return true; } } //往左判断 temp=y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1-i))) { if(IsNotLineConnection(x1,(y1-i),x2,y2)) return true; } } //往上判断 temp=x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1-i),y1)) { if(IsNotLineConnection((x1-i),y1,x2,y2)) return true; } } //往右判断 temp=VIRTUAL_LINE-y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1+i))) { if(IsNotLineConnection(x1,(y1+i),x2,y2)) return true; } } } if((x2<x1)&&(y2<y1)) //(x2,y2)在(x1,y1) 左上方 { if(IsNotLineConnection(x1,y1,x2,y2))//先判断只有一个折点 * 代表两个点 // *----------| return true; // | | // |__________* //先往上判断 temp=x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1-i),y1)) { if(IsNotLineConnection((x1-i),y1,x2,y2)) return true; } } //往左判断 temp=y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1-i))) { if(IsNotLineConnection(x1,(y1-i),x2,y2)) return true; } } //先往下判断 temp=VIRTUAL_ROW-x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1+i),y1)) { if(IsNotLineConnection((x1+i),y1,x2,y2)) return true; } } //往右判断 temp=VIRTUAL_LINE-y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1+i))) { if(IsNotLineConnection(x1,(y1+i),x2,y2)) return true; } } } if((x2<x1)&&(y2>y1)) //(x2,y2)在(x1,y1)右上方 { if(IsNotLineConnection(x1,y1,x2,y2))//先判断只有一个折点 * 代表两个点 // |----------* return true; // | | // *__________| //先往上判断 temp=x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1-i),y1)) { if(IsNotLineConnection((x1-i),y1,x2,y2)) return true; } } //往右判断 temp=VIRTUAL_LINE-y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1+i))) { if(IsNotLineConnection(x1,(y1+i),x2,y2)) return true; } } //先往下判断 temp=VIRTUAL_ROW-x1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,(x1+i),y1)) { if(IsNotLineConnection((x1+i),y1,x2,y2)) return true; } } //往左判断 temp=y1; for(i=1;i<=temp;i++) { if(IsLinePicEmpty(x1,y1,x1,(y1-i))) { if(IsNotLineConnection(x1,(y1-i),x2,y2)) return true; } } } return false; } bool CZLLKView::IsLineConnection(int x1, int y1, int x2, int y2) //判断直线两点是不是可连通的 { int i,temp; if(x1==x2) //同一行 { temp=abs(y2-y1); if(y2>y1) { for(i=1;i<temp;i++) if(llk_map[x1][y1+i].PicIndex!=0) return false; } else { for(i=1;i<temp;i++) if(llk_map[x1][y1-i].PicIndex!=0) return false; } } if(y1==y2) //同一列 { temp=abs(x2-x1); if(x2>x1) { for(i=1;i<temp;i++) if(llk_map[x1+i][y1].PicIndex!=0) return false; } else { for(i=1;i<temp;i++) if(llk_map[x1-i][y1].PicIndex!=0) return false; } } return true; } // 判断直线(射线)除起始点 图片是否为空 // 0 2 0 0 0 0 0 bool CZLLKView::IsLinePicEmpty(int x1, int y1, int x2, int y2) { int i,temp; if(x1==x2) //同一行 { temp=abs(y2-y1); if(y2>y1) { for(i=1;i<=temp;i++) if(llk_map[x1][y1+i].PicIndex!=0) return false; } else { for(i=1;i<=temp;i++) if(llk_map[x1][y1-i].PicIndex!=0) return false; } } if(y1==y2) //同一列 { temp=abs(x2-x1); if(x2>x1) { for(i=1;i<=temp;i++) if(llk_map[x1+i][y1].PicIndex!=0) return false; } else { for(i=1;i<=temp;i++) if(llk_map[x1-i][y1].PicIndex!=0) return false; } } return true; } // 情况二:经过一个折点相连(+号代表折点) // 0 0 0 0 0 0 // 0 2 0 0 0 + * ------ + // 0 + 0 0 0 2 + ------ * // (两条路都可连通) bool CZLLKView::IsNotLineConnection(int x1, int y1, int x2, int y2) { if(IsLinePicEmpty(x1,y1,x1,y2)) { if(IsLineConnection(x1,y2,x2,y2)) return true; } if(IsLinePicEmpty(x1,y1,x2,y1)) { if(IsLineConnection(x2,y1,x2,y2)) return true; } return false; } //是否无解 bool CZLLKView::IsNoConnection() { int i; ZYHLLK_PATH *pic=NULL; ZYHLLK_PATH *Nextpic = NULL; for(i=1;i<=15;i++) { pic=pic_place[i]; while(pic!=NULL)//pic->next { Nextpic=pic; while(Nextpic->next!=NULL) { Nextpic=Nextpic->next; if(CheckConnection(pic->x,pic->y,Nextpic->x,Nextpic->y)) return false; } pic=pic->next; } } return true; } bool CZLLKView::IsPicEmpty() { int i,j; for(i=1;i<=ROW_NUMBER;i++) for(j=1;j<=LINE_NUMBER;j++) { if(llk_map[i][j].PicIndex!=0) return false; } return true; } //添加图片位置 这个函数是为判断无解和提示服务的 void CZLLKView::AddPicPlace(int picindex,int x,int y) { LPZYHLLK_PATH pic; if ((pic = (LPZYHLLK_PATH) GlobalAlloc(GPTR, sizeof(ZYHLLK_PATH))) == NULL) { printf("GlobalAlloc() failed with error %d\n", GetLastError()); return; } pic->x=x; pic->y=y; pic->next = pic_place[picindex]; pic_place[picindex] = pic; } //在链表释放图片位置 这个函数是为判断无解和提示服务的 void CZLLKView::ReleasePicPlace(int picindex,int x,int y) { ZYHLLK_PATH *pic = pic_place[picindex]; ZYHLLK_PATH *Prevpic = NULL; while(pic) { if ((pic->x==x)&&(pic->y==y)) { if (Prevpic) Prevpic->next = pic->next; else pic_place[picindex]= pic->next; GlobalFree(pic); return; } Prevpic = pic; pic = pic->next; } } //暂时没有用到 LPZYHLLK_PATH CZLLKView::QueryPicPlace(int picindex,int x,int y) { ZYHLLK_PATH *pic = pic_place[picindex]; while(pic) { if ((pic->x== x)&&(pic->y==y)) return pic; pic = pic->next; } return NULL; } //列出每幅图片的所有位置 用来判断无解和提示的 void CZLLKView::ListPicPlace() { int i,j; for(i=1;i<=ROW_NUMBER;i++) { for(j=1;j<=LINE_NUMBER;j++) { if(llk_map[i][j].PicIndex>0) { AddPicPlace(llk_map[i][j].PicIndex,i,j); } } } } //提示函数 void CZLLKView::BackPicPlace() { int i; CRect rect; ZYHLLK_PATH *pic=NULL; ZYHLLK_PATH *Nextpic = NULL; for(i=1;i<=15;i++) { pic=pic_place[i]; while(pic!=NULL) { Nextpic=pic; while(Nextpic->next!=NULL) { Nextpic=Nextpic->next; if(CheckConnection(pic->x,pic->y,Nextpic->x,Nextpic->y)) { llk_map[pic->x][pic->y].state=1; llk_map[Nextpic->x][Nextpic->y].state=1; rect.top=tiley(pic->x); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(pic->y); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); rect.top=tiley(Nextpic->x); rect.bottom=rect.top+PIC_HEIGHT; rect.left=tilex(Nextpic->y); rect.right=rect.left+PIC_WIDTH; InvalidateRect(&rect,TRUE); return; } } pic=pic->next; } } return; } //重列函数 void CZLLKView::SortPicPlace() { int i,j; CRect rect; CDWordArray arPic; for(i=1;i<=ROW_NUMBER;i++) { for(j=1;j<=LINE_NUMBER;j++) { llk_map[i][j].state=0; if(llk_map[i][j].PicIndex>0) arPic.Add(llk_map[i][j].PicIndex); } } //int k = 1;//初始化随机数发生器 //int divisor = ROW_NUMBER*LINE_NUMBER - k+1; index = rand() % divisor+1 k++ int index; for(i=1;i<=ROW_NUMBER;i++) { for(j=1;j<=LINE_NUMBER;j++) { if(llk_map[i][j].PicIndex>0) { index=(int(rand()*001+rand()*0.1+rand()))%arPic.GetSize(); llk_map[i][j].PicIndex=arPic.GetAt(index); arPic.RemoveAt(index); } } } //重新列出所有图片位置 for(i=0;i<15;i++) { pic_place[i+1]=NULL; } ListPicPlace(); //刷新屏幕 rect.top=DRAW_TOP+BMP_HEIGHT; rect.bottom=BMP_HEIGHT*ROW_NUMBER+DRAW_TOP+PIC_HEIGHT; rect.left=DRAW_LEFT+BMP_WIDTH; rect.right=BMP_WIDTH*LINE_NUMBER+DRAW_LEFT+PIC_WIDTH; InvalidateRect(&rect,TRUE); } void CZLLKView::OnMenuInfo() { // TODO: Add your command handler code here if(bingame) { if(m_tishinumber>0) { m_tishinumber--; DrawInfo(60,80,m_tishinumber); BackPicPlace(); } else { AfxMessageBox("提示已经用完"); } } } void CZLLKView::OnUpdateMenuInfo(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here CString str; str.Format("提示(%d) F5",m_tishinumber); pCmdUI->SetText(str); if(m_tishinumber<=0) pCmdUI->Enable(false); } void CZLLKView::OnMenuSort() { // TODO: Add your command handler code here if(bingame) { if(m_sortnumber>0) { m_sortnumber--; DrawInfo(60,60,m_sortnumber); SortPicPlace(); } else { AfxMessageBox("重列次数已经用完"); } } } void CZLLKView::OnUpdateMenuSort(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here CString str; str.Format("重列( %d) F6",m_sortnumber); pCmdUI->SetText(str); if(m_sortnumber<=0) pCmdUI->Enable(false); } void CZLLKView::OnMenuStop() { // TODO: Add your command handler code here if(bstop) SetTimer(1,1000,0); else KillTimer(1); bstop=!bstop; } void CZLLKView::OnUpdateMenuStop(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bstop) pCmdUI->SetCheck(true); else pCmdUI->SetCheck(false); } void CZLLKView::OnMenuEffect() { // TODO: Add your command handler code here bsoundeffect=!bsoundeffect; } void CZLLKView::OnUpdateMenuEffect(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bsoundeffect) pCmdUI->SetCheck(true); else pCmdUI->SetCheck(false); } void CZLLKView::OnMenuMusic() { // TODO: Add your command handler code here bmusic=!bmusic; } void CZLLKView::OnUpdateMenuMusic(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bmusic) pCmdUI->SetCheck(true); else pCmdUI->SetCheck(false); } void CZLLKView::DrawRectangleHollow() { CDC* pDC; pDC=GetDC(); CPen penNew(PS_SOLID,1,RGB(255,255,255)),*ppenOld; ppenOld=pDC->SelectObject(&penNew); pDC->MoveTo(118,38); pDC->LineTo(522,38); pDC->LineTo(522,61); pDC->LineTo(118,61); pDC->LineTo(118,38); } void CZLLKView::DrawProgress(int progress) { CDC *pDc; pDc=GetDC(); // 渲染客户去 CRect rect; rect.SetRect(120,40,120+progress,60); pDc->FillSolidRect(&rect,RGB(255,0,0)); } void CZLLKView::DrawInfo(int x,int y,CString str) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(255,0,0)); pDc->SetBkMode(TRANSPARENT); pDc->TextOut(x,y,str); } void CZLLKView::DrawInfo2(int x,int y,int i) { CDC *pDc; CString str; pDc=GetDC(); pDc->SetTextColor(RGB(255,0,0)); pDc->SetBkMode(TRANSPARENT); str.Format("%d",i); // 渲染客户去 CRect rect; rect.SetRect(x,y,x+40,y+40); pDc->FillSolidRect(&rect,RGB(100,100,200)); pDc->TextOut(x,y,str); } void CZLLKView::DrawInfo3(int x,INT y,CString str) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(255,0,0)); pDc->SetBkMode(TRANSPARENT); // 渲染客户去 CRect rect; rect.SetRect(x,y,x+100,y+15); pDc->FillSolidRect(&rect,RGB(100,100,200)); pDc->TextOut(x,y,str); } void CZLLKView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(m_nUpper<400) { m_nUpper=m_nUpper+m_nSpeed; DrawProgress(m_nUpper); } else { KillTimer(1); MessageBox(_T("你的时间用完了,SORRY!"),_T("ZYH连连看"),MB_YESNO); //调用排行榜 OnMenuBack(); } CView::OnTimer(nIDEvent); } void CZLLKView::OnMenuHelp() { // TODO: Add your command handler code here AfxMessageBox("还要帮助?\n连连看这么流行了,是个人都知道怎么玩吧\n不好意思,说过分了,好好玩吧。\n祝你好运了"); }