两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

一、源碼簡介

這是一個可以進行貪吃蛇游戲的小程序,采用C語言進行編寫。

上下左右控制運動方向,吃到食物得分,如果撞墻或者咬到自身,游戲結束。

編譯環(huán)境:VC6.0(采取純C語言寫法)

第三方庫:無


二、運行截圖

游戲結束界面

貪吃蛇界面1

貪吃蛇界面2


三、源碼解析

先看整個程序的邏輯:

開始界面

進行游戲

初始化

以下循環(huán):

{

根據(jù)輸入按鍵的不同,做出不同的反應。

每經(jīng)過一段時間,蛇進行移動。

}

結束游戲

主函數(shù)以及游戲運行的Gamerun函數(shù)如下。

int main()
{
       Gamestart();
       Gamerun();
       Gameend();
       return 0;
}
void Gamerun()
{
       Initsnake();//初始化蛇
       Createfood();//創(chuàng)建食物
       while(1)
       {
              Pos(64,10);
        printf("得分:%d ",score);
              if(GetAsyncKeyState(VK_UP)&&status!=D)status=U;//根據(jù)之前是否有按下某種按鍵,改變前進方向或者暫停   
        else if(GetAsyncKeyState(VK_DOWN)&&status!=U)status=D;
        else if(GetAsyncKeyState(VK_LEFT)&&status!=R)status=L;
        else if(GetAsyncKeyState(VK_RIGHT)&&status!=L)status=R;
        else if(GetAsyncKeyState(VK_SPACE))Pause();
        else if(GetAsyncKeyState(VK_ESCAPE))
        {
            exit(0);
            break;
        }
        else;
        Sleep(sleeptime);//經(jīng)過一段時間繼續(xù)前進
        if(Snakemove());//如果行動成功(沒有死)
        else
            break;//否則跳出循環(huán)
       }
}


其中,接收輸入按鍵可以用<Windows.h>中的GetAsyncKeyState函數(shù),它可以判斷之前的一段時間內是否輸入了某按鍵。

我們用U,D,L,R來表示蛇頭朝向上下左右。經(jīng)過定義之后,可以用這四個字母為status賦值。

#define U 1
#define D 2
#define L 3
#define R 4
int status;

蛇并不能180?轉彎,所以要注意判定按鍵方向是否與目前前進方向相反。

另外我們在這里還用了一個Pos函數(shù)。這個函數(shù)的目的是將光標定位到(x,y)處,并且能在此進行寫入。

void Pos(int x,int y)//定義一個設置光標位置的函數(shù)
{
    COORD pos;
    HANDLE hOutput;
    pos.X=x;
    pos.Y=y;
    hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOutput,pos);
}

用到的幾個函數(shù)都可以在<windows.h>當中找到。

COORD是windows API中定義的一種結構,表示一個字符在控制臺屏幕上的坐標;

GetStdHandle用于返回一個句柄,表明是輸入,輸出還是錯誤(參數(shù)分別是STD_INPUT_HANDLE,STD_OUTPUT_HANDLE,STD_ERROR_HANDLE),HANDLE是對應的句柄的結構體;

SetConsoleCursorPosition可在指定的控制臺屏幕緩沖區(qū)中設置光標位置。

更多內容可以在控制臺文檔 - Windows Console | Microsoft Docs中搜索找到。

 

Pause是另外一個我們定義的函數(shù)。如果不按下空格,程序就會循環(huán)Sleep指令。

void Pause()//定義暫停函數(shù)
{
   while(1)
   {
       Sleep(100);
       if(GetAsyncKeyState(VK_ESCAPE))break;
       else;
    }
}

 

在進行具體游戲函數(shù)的編寫之前,我們還需要確定游戲數(shù)據(jù)是如何存儲及調用的,也就是如何保存蛇身的坐標。像蛇身這樣的線性結構,非常適合用一個鏈表進行存儲。將蛇身的一個點的坐標放入一個結構體當中,結構體中還有指向下一個結構體的指針。

struct SNAKE//定義蛇身上的一個點
{
   int x,y;
   SNAKE *next;//定義一個指針,指向蛇下一個點的地址
};

 

準備工作做完之后,接下來的是游戲主體部分。

接下來我們要寫的函數(shù)包括:

void Creatmap()//定義創(chuàng)建地圖的函數(shù)
void Initsnake()//初始化函數(shù)
int Hitwall()//檢測是否撞墻
int Eatitself()//檢測是否碰到自身
void Createfood()//定義創(chuàng)建食物的函數(shù)
int Snakemove()//定義蛇身行動的函數(shù)
void Gamestart()//開始頁面以及初始化
void Gameend()//游戲結束

其中Snakemove會用到Hitwall,Eatitself,Createfood。

 

1. 創(chuàng)建地圖

void Creatmap()//定義創(chuàng)建地圖的函數(shù)
{
   int i;
    for(i=0;i<58;i+=2)//打印上下邊框
    {
        Pos(i,0);
        printf("■");
        Pos(i,26);
        printf("■");
    }
    for(i=1;i<26;i++)//打印左右邊框
    {
        Pos(0,i);
        printf("■");
        Pos(56,i);
        printf("■");
    }
}

利用好之前定義的Pos函數(shù)就可以了。

 

2. 初始化蛇身以及游戲參數(shù)

void Initsnake()//初始化函數(shù)
{
   sleeptime=300;
   score=0;
   status=D;
   SNAKE *tail;
    int i;
    tail=(SNAKE*)malloc(sizeof(SNAKE));//從蛇尾開始,頭插法,以x,y設定開始的位置//
    tail->x=24;
    tail->y=5;
    tail->next=NULL;
    for(i=1;i<=4;i++)//設定整個蛇身體各點的位置
    {
        head=(SNAKE*)malloc(sizeof(SNAKE));
        head->next=tail;
        head->x=24+2*i;
        head->y=5;
        tail=head;
    }
    while(tail!=NULL)//從頭到尾,輸出蛇身
    {
        Pos(tail->x,tail->y);
        printf("■");
        tail=tail->next;
    }
}

malloc函數(shù)用于動態(tài)為指針分配內存空間。其參數(shù)為分配空間的大小,返回值為該空間地址。注意這個地址對應void類型的指針,所以一定要用(SNAKE*)這樣方式進行強制類型轉化。

malloc函數(shù)的意義是初始化指針。如果指針不進行初始化,那么就會指向一個沒有意義的地址,成為一個野指針,在對指針指向的位置進行讀或寫操作時,程序就會報錯。類似的函數(shù)還有new,有興趣的同學可以查查它們的區(qū)別。

 

3. 檢測撞墻行為

int Hitwall()//檢測是否撞墻
{
   if(head->x==0||head->x==56||head->y==0||head->y==26)return 1;
   else
       return 0;
}

 

4. 檢測是否碰到自身

int Eatitself()//檢測是否碰到自身
{
   SNAKE *s;
   s=head->next;
   while(s->next!=NULL)//利用循環(huán)對每個點進行判定
   {
      if(s->x==head->x&&s->y==head->y)return 1;
      else
          s=s->next;
   }
   return 0;
}

 

5. 創(chuàng)建食物

void Createfood()//定義創(chuàng)建食物的函數(shù)
{
    SNAKE *food_1;
    SNAKE *q;
    srand((unsigned)time(NULL));//利用時間獲取隨機種子
    food_1=(SNAKE*)malloc(sizeof(SNAKE));
    food_1->x=2*(rand()%26)+2;//利用隨機種子獲取坐標
    food_1->y=rand()%24+1;
    q=head;
    while(q->next!=NULL)//利用循環(huán)對每個點進行判定
    {
        if(q->x==food_1->x&&q->y==food_1->y) //判斷蛇身是否與食物重合
        {
            free(food_1);
            food_1=NULL;//不將地址置為NULL,也會讓指針變?yōu)橐爸羔?
            Createfood();
        }
        q=q->next;
    }
    Pos(food_1->x,food_1->y);
    food=food_1;
    printf("■");//打印食物
}

對于食物位置的數(shù)據(jù),我們同樣用SNAKE結構體進行存儲,這樣可以便于與蛇身進行連接。

因為食物的位置要隨機生成,所以我們需要一個隨機種子來表征這種隨機性。

srand函數(shù)在<stdlib. h>當中,是隨機數(shù)發(fā)生器的初始化函數(shù)。其參數(shù)只有一個,為隨機數(shù)產(chǎn)生器的初始值(種子值)。為了防止隨機數(shù)出現(xiàn)重復,我們常用(unsigned)time(&t)來生成隨機種子,原理是使用 time函數(shù)來獲得系統(tǒng)時間,它的返回值為從 00:00:00 GMT, January 1, 1970 到現(xiàn)在所持續(xù)的秒數(shù),然后將time_t型數(shù)據(jù)轉化為(unsigned)型再傳給srand函數(shù)。當然這還有另外一個用法,不用定義time_t型t變量,即: srand((unsigned) time(NULL)),直接傳入一個空指針,因為程序中往往并不需要經(jīng)過參數(shù)獲得的數(shù)據(jù)。

 

6. 蛇身行動

int Snakemove()//定義蛇身行動的函數(shù)
{
   SNAKE *nexthead;//蛇將要走到的位置
   nexthead=(SNAKE*)malloc(sizeof(SNAKE));
    SNAKE *n;
   if(status==U)//根據(jù)移動方向,計算下一個點的坐標
   {
      nexthead->x=head->x;
      nexthead->y=head->y-1;
      nexthead->next=head;
   }
   else if(status==D)
   {
      nexthead->x=head->x;
      nexthead->y=head->y+1;
      nexthead->next=head;
   }
   else if(status==L)
   {
      nexthead->x=head->x-2;
      nexthead->y=head->y;
      nexthead->next=head;
   }
   else
   {
      nexthead->x=head->x+2;
      nexthead->y=head->y;
      nexthead->next=head;
   }
   head=nexthead;
   if(Hitwall())//是否撞墻
   {
      typelose=1;
      return 0;
   }
   else;
   if(Eatitself())//是否咬到自身
   {
      typelose=2;
      return 0;
   }
   else;
   if(head->x==food->x&&head->y==food->y)//如果前方是食物
   {
      score++;
      Createfood();
   }
   else
   {
      n=head;
      while(n->next->next!=NULL)n=n->next;//將移動到的下一個點打印,同時去掉尾部的點
      Pos(n->next->x,n->next->y);
      printf("  ");
      Pos(head->x,head->y);
      printf("■");
      free(n->next);
      n->next=NULL;
    }
   return 1;
}

 

7. 游戲開始及終止

void Gamestart()//開始頁面以及初始化
{
   system("mode con cols=100 lines=30");
   Startpage();//開始頁面
   Creatmap();//繪制地圖
}
void Gameend()//游戲結束
{
    system("cls");//清除屏幕
    Pos(24,12);
    if(typelose==1)
    {
        printf("對不起,您撞到墻了。游戲結束.");
    }
    else if(typelose==2)
    {
        printf("對不起,您咬到自己了。游戲結束.");
    }
    Pos(24,13);
    printf("您的得分是%d\n",score);
}

四、完整源碼

C語言貪吃蛇源碼下載

點贊(0)

C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習題和答疑,點擊了解:

一點編程也不會寫的:零基礎C語言學練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進階課程

從零到寫出一個爬蟲的Python編程課程

只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程

信息學奧賽或C++選手的 必學C++課程

藍橋杯ACM、信息學奧賽的必學課程:算法競賽課入門課程

手把手講解近五年真題的藍橋杯輔導課程

Dotcpp在線編譯      (登錄可減少運行等待時間)