【游戏】走迷宫游戏分析

一、数据分析

      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走迷宫游戏源码

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