• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      手把手教MFC貪吃蛇

       夜★風 2010-11-18

      13本文作者:唐伯虎  發布于:2010-8-28  分類:MFC編程  點擊:766
                   很多人學了很久MFC,都不知道到底學了什么。因為他們被很多MFC的書給誤導了,時下的MFC的書大部分的章節都是如何運用控件。學來學去還是不知道學到了什么,除了移動控件。我就被這些誤導了好久,直到后來我嘗試編寫這個貪吃蛇,才開始真正理解MFC。
                 MFC提供的很多控件,這些只是輔助編程用的,給編好的程序添加個按鈕之類的,真正要編寫windows程序,歸根結底還是要用c++的各種算法實現功能,MFC庫則幫助我們從命令行程序過渡到GUI程序。
                 接下來我就開始指導貪吃蛇的編寫。
                首先,要創建一個基于對話框的mfc程序,取名為Snake,然后開始在這些自動生成的代碼中添加自己要實現的功能。
                我是怎么實現蛇的呢?
                我的方法是用GUI繪圖畫出很多小矩形,這些矩形連在一起,就可以出現一條蛇了。于是我們便要記錄每個小矩形的一個點的信息。我用了一個Body類
          class  Body
      {
      public:int x;
          int y;
          Body* next;
       Body* pre;
        Body(int xx,int yy)
       {
        x=xx;
        y=yy;
        next=NULL;
        pre=NULL;
         }
      };
      然后還需要食物,我們再建立一個food結構體
      struct Food
      {
       int x;
          int y;
      }food;
      有人不禁要問為何body不用結構體呢,這里我主要是想用類的構造函數。
       處理好這些微觀問題,我們再來宏觀研究這條蛇,我們需要這條蛇可以移動,可以吃食物,所以我們要建立一個snake類,并賦予它有移動,吃食物等的功能
      class Snake
      {
      public:Body*  head;
          void move();
         Snake()
       {
        Body* body1=new Body(0,0);
        Body* body2=new Body(1,0);
        body1->next=body2;
        body2->pre=body1;
        head=body2;
        }
              void creatfood();
       int isGameOver();
       Body* getHead(){return head;}
       void DrawSnake(CDC *pDC);
       void DrawFood(CDC *pDC);
       };
      由于食物的隨機出現,需要保證不和蛇身重合,所以我們需要調用蛇的信息,所以我們不妨把創建食物的函數也加入到snake類中。
         接下來我們來看看實現這些功能的代碼
         void Snake::move()
      {
       int xx=0;
       int yy=0;
       switch(direct)
       {
       case 0:{yy=head->y-1;xx=head->x;lastdirect=0;break;}
       case 1:{yy=head->y+1;xx=head->x;lastdirect=1;break;}
       case 2:{xx=head->x-1;yy=head->y;lastdirect=2;break;}
       case 3:{xx=head->x+1;yy=head->y;lastdirect=3;break;}
       }
       nextx=xx;
       nexty=yy;
         if(isGameOver()) return;
       if(food.x==xx&&food.y==yy)
       {
                  Body* p=new Body(xx,yy);
                   Body* q=new Body(0,0);
        q=head;
        q->next=p;
        p->pre=q;
        
        head=p;
       
        food.x=-1;
        food.y=-1;
       
        creatfood();
        score+=10;
        speed+=10;
      }
       else
       {
                     Body *p=head;
        while(p->pre)
        {
         p=p->pre;
        }
        while(p->next)
        {
        p->x=p->next->x;
        p->y=p->next->y;
        p=p->next;
       
        }
        head->x=xx;
        head->y=yy;
       }
      }
      注意move()函數中的case 0 1 2 3分別映射了按鍵的w、s、a、s鍵
      也即就是上下左右的按鍵。
      void  Snake::creatfood()
      {
      int t=1;
      int x=0;
      int y=0;
      while(t==1)
      {
           x=rand()%20;
           y=rand()%30;
         Body* p=head;
         t=0;
          while(p!=NULL)
        {
         if(p->x==x&&p->y==y)
         {  
          t=1;
         
          break;
         }
         else p=p->pre;
        }
      }
      food.x=x;food.y=y;
      }
      int Snake::isGameOver()
      {
        Body* p=head;
        if(nextx>19||nextx<0||nexty>29||nexty<0)
         {  
          return 1;
         };
        p=p->pre;
       while(p!=NULL)
       {
       if(p->x==nextx&&p->y==nexty) return 1;
       else p=p->pre;
       }
       
         return 0;
      }
      void Snake::DrawSnake(CDC* pDC)
      {
       CBrush br1;
       br1.CreateSolidBrush(RGB(255,255,255));
       pDC->SelectObject(&br1);
       pDC->Rectangle(10,10,210,310);
       br1.DeleteObject();
       int x;
       int y;
       Body *z=getHead();
       CBrush br;
       br.CreateSolidBrush(RGB(255,0,0));
       pDC->SelectObject(&br);
       while(z!=NULL)
       {
        x=int(z->x);
        y=int(z->y);
        pDC->Rectangle(10*x+12,10*y+12,10*x+20,10*y+20);
        z=z->pre;
       }
       br.DeleteObject();
      }
      void Snake::DrawFood(CDC* pDC)
      {
       if(food.x==-1&&food.y==-1) return ;
       CBrush br;
          br.CreateSolidBrush(RGB(255,0,0));
          pDC->SelectObject(&br);
       pDC->Rectangle(10*food.x+12,10*food.y+12,10*food.x+20,10*food.y+20);
       br.DeleteObject();
      }
      我們除了畫蛇之外,還必須要記錄成績 所以我們再建立畫出成績的函數,并且還要給用戶按鍵提示
      void DrawScore(CDC* pDC)
      {
       CString s;
       s.Format("分數:%d",score);
       pDC->SetTextColor(RGB(155,155,155));
       pDC->TextOut(222,40,s);
      }
      void DrawInit(CDC* pDC)
      {
       pDC->SetTextColor(RGB(222,222,222));
       pDC->TextOut(222,70,"W:上");
       pDC->TextOut(222,100,"S:下");
           pDC->TextOut(222,130,"A:左");
       pDC->TextOut(222,160,"D:右");
      }
      要想能夠實現這些功能 需要先創建一個蛇的實例
       Snake snake;
      然后在自動生成的代碼 CSnakeDlg::OnPaint()函數中實現蛇的繪畫
        CDC *pDC = GetDC();
        DrawInit(pDC);
              snake.creatfood();
        SetTimer(1,speed,NULL);
       snake.move();
       snake.DrawSnake(pDC);
             snake.DrawFood(pDC);
        那么這SetTimer()又是什么呢,這是定時器,我們必須定時刷新界面,才能顯示出蛇的移動,吃食
       void CSnakeDlg::OnTimer(UINT nIDEvent)
      {
       // TODO: Add your message handler code here and/or call default
          CDC*pDC=GetDC();
       if(snake.isGameOver())
       {
         CBrush br1;
              br1.CreateSolidBrush(RGB(255,255,255));
              pDC->SelectObject(&br1);
              pDC->Rectangle(10,10,210,310);
           br1.DeleteObject();
         CFont font;
          font.CreatePointFont(140,"宋體");
          pDC->SelectObject(&font);
         pDC->SetTextColor(RGB(255,0,0));
            pDC->TextOut(88,50,"游戲失敗");
            KillTimer(1);
          }
       else{
       
          snake.move();
       snake.DrawSnake(pDC);
       snake.DrawFood(pDC);
       DrawScore(pDC);
       SetTimer(1,speed,NULL);
       }
       CDialog::OnTimer(nIDEvent);
      }

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發表

        請遵守用戶 評論公約

        類似文章 更多

        主站蜘蛛池模板: 欧美国产日韩在线三区| 亚洲ΑV久久久噜噜噜噜噜| 欧美熟妇性XXXX欧美熟人多毛| 伊人热热久久原色播放WWW| 国产V亚洲V天堂A无码| 亚洲乱理伦片在线观看中字| 妺妺窝人体色WWW在线一| 国产精品普通话国语对白露脸| 九九久久精品国产免费看小说 | 精品国产丝袜自在线拍国语| 亚洲码欧美码一区二区三区| 成人啪精品视频网站午夜| 97无码免费人妻超级碰碰夜夜| 精品日韩人妻中文字幕| 国产午夜无码视频在线观看 | 午夜福利在线观看6080| 隔壁人妻被水电工征服| 欧美人成精品网站播放| 成 人 色 网 站免费观看| 欧美牲交a欧美牲交aⅴ图片| 国产成人精品亚洲日本在线观看 | 免费无码成人AV片在线 | 天天影视网色香欲综合网| 成在线人午夜剧场免费无码 | 四虎影视一区二区精品| 中文字幕日韩有码av| 无码人妻久久一区二区三区APP | 天堂亚洲免费视频| 亚洲精品乱码久久久久久自慰 | 免费无码成人AV片在线| 亚洲精品55夜色66夜色| 国产成人久久综合一区| 国产中文字幕日韩精品| 国产午夜视频在线观看| 隔壁人妻被水电工征服| 免费无码又爽又刺激高潮虎虎视频| 小污女小欲女导航| 好吊视频一区二区三区| 久久天天躁夜夜躁狠狠| 亚洲欧美日韩综合一区在线| 麻豆亚洲精品一区二区|