【遊戲】走迷宮遊戲分析

一、數據分析

      1、窗口顯示

           基本的思路是:讓GameApp從WinApp派生,裏面有一個m_pMainWnd指針,然後在InitInstance()中new一個GameWnd對象,m_pMainWnd指向它。

           然後m_pMainWnd調用顯示窗口、更新窗口的函數。

          

         

          

          2、全局數據及讀取    

          

GameWnd::GameWnd()//進行相關的數據初始化

{
    Create(NULL,"創建窗口");
    bitmap->m_hObject=LoadImage()//加載位圖數據
    ....

}

二、行走分析

       OnKeyDown()來處理人物上、下、左、右的走動。它會做這樣的處理,case vk_**,比如**=3,當方向不是這個方向時,dir = **,index = 0; 置初始圖片bitmap[dir,index],這樣的話,從A方向跳到B方向,這時是B方向初始圖片的第一個位置。

      參考15.32

      用鏈表保存行走路徑並回放的方法:     

struct list
{
       int m;//入口格的行數
       int n;//入口格的列數
       int x;//x方向移動的值
       int y;//y方向移動的值
       struct list *next;//前節點
       struct list *back;//後節點
       CBitmap* bitmap;//保存人物圖像的地址
}list* ptr,*preptr,*first;//當前節點地址,上一個節點的地址,第一個節點的地址
//--------------------
//在窗口類構造函數,初始化
ptr->m = m;//全局變量,人物的初始格子所在行
ptr->n = n;//人物初始格子所在列
ptr->bitmap = bitmap[0][0];//人物的初始圖片
ptr->next = NULL;
prt->back = NULL;
first = prt;//鏈表的首節點
//-----------------
//OnKeyDown中,用ptr記錄當前人物的位置
//下面之前的代碼已經計算了,方向鍵按下時,x,y的值,還有索引圖片的dir,index值
ptr->next = (list*)malloc(sizeof(list));
prt->next->m = m;//初始值
ptr->next->n = n;
ptr->next->x=x;
ptr->next->y=y;
ptr->next->bitmap=bitmap[dir][index];
preptr=ptr;//上一個節點值,first
ptr->next->next=NULL;//ptr-next是當前要加入的節點
ptr = ptr->next;//preptr已經指向了當前節點,ptr可正式指向要加入的節點
ptr ->back=preptr;//ptr當前節點的上一個節點是preptr
//----------------
//回放功能實現:在OnKeyDown出口判斷處,置bool變量go=TRUE;在OnTimer函數中,作爲一個判斷的標誌,再調用回放功能函數Go();
//回放函數Go()的實現,裏面會由OnTimer自動調用
  m = first->m
  n = first->n
  x = first->x
  y = first->y;
  mdc->SelectObject(wall);//選背景圖到內存dc
  for()//循環遍歷maze[i][j],=1時,說明是牆壁,
       dc.BitBlt(j*93,i*100,93,100,mdc,0,0,SRCCOPY);
  mdc->SelectObject(first->bitmap)
  if(first->back !=NULL)
       dc.BitBlt(first->back->n*93+first->back->x,first->back->m*100+first->back->y,93,100,mdc,0,0,WHITENESS);//顯示白色,塗抹掉前面的圖片
       dc.BitBlt(first->n*93+first->x,first->m*100+first->y,93,100,mdc,0,0,SRCCOPY);
  if(first->next=NULL)
    {
         go = false;
    }
  else
         first = first->next;//取下一個節點值,first已經是記錄最後的一個節點了,再次走時,走到出口處,將從這裏開始再次回放。

       2、判斷障礙功能的實現         

void GameWnd::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags)

{

	nChar==VK_DOWN;//根據這個標記,判斷方向鍵是否按下

	//1. 計算下一步的顯示的位置,即改變x,y,

	//2. 通過x,y計算其所在maze[8][8]的格,獲取maze[Index_x][Index_y]的索引值

	//3. 判斷索引值是否是空格標記,如果不是,在不改變x,y

}

 三、其他分析

          第一次響應WM_PAINT,應該是創建窗口之後的,UpdateWindow()發送的,其調用OnPaint(),必須調用CPaintDC dc(this);其中構造函數中有,EndPaint,來通知系統無效區域解除,否則系統將WM_PAINT移除隊列,會不斷髮送WM_PAINT消息。
        CClientDC局部變量在析構時,不會向窗口發送WM_PAINT。在該遊戲中,CClientDC在繪製時,只不過是時間落後與OnPaint()而已。CPaintDC會調用EndPaint,而改成CClientDC不會,從而在局部銷燬時不斷髮送WM_PAINT消息
        BeginPaint獨佔顯示卡,最後必須調用EndPaint釋放掉獨佔的顯示卡
       1.1~1.4,下走4幅圖片
       2.1~2.4,左走4幅圖片
       3.1~3.4,右走4幅圖片
       4.1~4.4,向上走4副圖片
       char ch[8];保存圖片名稱
       sprintf(ch,"%d.%d.bmp",i+1,j+1);//這樣將圖片的文件名轉化成字符串ch[8]中,

三、總結

       1、在窗口類GameWnd的構造函數中,就把所有數據加載到內存當中,並對全局數據進行初始化。

       2、在窗口結束時,都沒有釋放掉句柄,最終由操作系統來釋放。

       3、將鏈表list的數據結構直接寫到了遊戲的代碼中,這樣不用去寫一個鏈表list類。

參考:1、從新手到高手:C++全方位學習15.1

2、VC++從入門到精通精裝版

3、在WM_PAINT處理函數OnPaint()

4、Game32走迷宮遊戲源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章