小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

手把手教MFC貪吃蛇

 夜★風 2010-11-18

13本文作者:唐伯虎  發(fā)布于:2010-8-28  分類:MFC編程  點擊:766
             很多人學(xué)了很久MFC,都不知道到底學(xué)了什么。因為他們被很多MFC的書給誤導(dǎo)了,時下的MFC的書大部分的章節(jié)都是如何運用控件。學(xué)來學(xué)去還是不知道學(xué)到了什么,除了移動控件。我就被這些誤導(dǎo)了好久,直到后來我嘗試編寫這個貪吃蛇,才開始真正理解MFC。
           MFC提供的很多控件,這些只是輔助編程用的,給編好的程序添加個按鈕之類的,真正要編寫windows程序,歸根結(jié)底還是要用c++的各種算法實現(xiàn)功能,MFC庫則幫助我們從命令行程序過渡到GUI程序。
           接下來我就開始指導(dǎo)貪吃蛇的編寫。
          首先,要創(chuàng)建一個基于對話框的mfc程序,取名為Snake,然后開始在這些自動生成的代碼中添加自己要實現(xiàn)的功能。
          我是怎么實現(xiàn)蛇的呢?
          我的方法是用GUI繪圖畫出很多小矩形,這些矩形連在一起,就可以出現(xiàn)一條蛇了。于是我們便要記錄每個小矩形的一個點的信息。我用了一個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結(jié)構(gòu)體
struct Food
{
 int x;
    int y;
}food;
有人不禁要問為何body不用結(jié)構(gòu)體呢,這里我主要是想用類的構(gòu)造函數(shù)。
 處理好這些微觀問題,我們再來宏觀研究這條蛇,我們需要這條蛇可以移動,可以吃食物,所以我們要建立一個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);
 };
由于食物的隨機出現(xiàn),需要保證不和蛇身重合,所以我們需要調(diào)用蛇的信息,所以我們不妨把創(chuàng)建食物的函數(shù)也加入到snake類中。
   接下來我們來看看實現(xiàn)這些功能的代碼
   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()函數(shù)中的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();
}
我們除了畫蛇之外,還必須要記錄成績 所以我們再建立畫出成績的函數(shù),并且還要給用戶按鍵提示
void DrawScore(CDC* pDC)
{
 CString s;
 s.Format("分數(shù):%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:右");
}
要想能夠?qū)崿F(xiàn)這些功能 需要先創(chuàng)建一個蛇的實例
 Snake snake;
然后在自動生成的代碼 CSnakeDlg::OnPaint()函數(shù)中實現(xiàn)蛇的繪畫
  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);
}

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多