純C語言貪吃蛇游戲

来源:https://www.cnblogs.com/jo-qzy/archive/2017/12/26/8119846.html
-Advertisement-
Play Games

說明 上個學期暑假心血來潮,查了比較多的資料,寫了一個星期寫的貪吃蛇代碼,bug還有,開始游戲不能按空格,你按啥鍵開始都行,就是不能按空格,參考了C語言網的貪吃蛇,所以很像,裡面的代碼有參考,但是全是重新寫的,沒有直接照抄,不然也不會有bug了對不對 代碼裡面有我寫的註釋,應該可以看懂 貪吃蛇通過鏈 ...


說明

上個學期暑假心血來潮,查了比較多的資料,寫了一個星期寫的貪吃蛇代碼,bug還有,開始游戲不能按空格,你按啥鍵開始都行,就是不能按空格,參考了C語言網的貪吃蛇,所以很像,裡面的代碼有參考,但是全是重新寫的,沒有直接照抄,不然也不會有bug了對不對
代碼裡面有我寫的註釋,應該可以看懂
貪吃蛇通過鏈表實現

你可以前往我的github下載此代碼,VC++6.0和VS2017均可通過編譯

效果圖

代碼

#include "stdio.h"
#include "stdlib.h"
#include "windows.h"//包含Sleep函數,來控制運行速度
#include "conio.h"//測試時用到了getch()來獲取按鍵,最後完成改了獲取方式沒用到,不過還是放著吧
#include "time.h"//設置食物時隨機生成坐標用到time做種子

typedef struct SNAKE//包含坐標及尾指針,為什麼用typedef因為可以直接snake定義指針,方便
{
    int x;
    int y;
    struct SNAKE *next;
}snake;//typedef的用法http://blog.csdn.net/wangqiulin123456/article/details/8284939

void POS();//移動游標函數
void StayAwayFromWall();//判斷撞牆函數
void DonnotBiteYouself();//判斷咬到自己的函數
void drawmap();//畫地圖函數
void initsnake();//初始化蛇函數
void createfood();//創建食物函數
void gamecircle();//游戲移動迴圈函數
void move();//移動函數
void pause();//暫停函數
void welcome();//歡迎界面
void game();//游戲界面

snake *head,*end;//定義蛇頭、蛇尾
snake *p;//移動時用到的遍歷蛇的指針
int i,speed=300;//迴圈變數i、速度
int levelup,score=0;//達到一定分數變快、分數
int foodx,foody;//食物的(x,y)坐標
char key;//定義按鍵獲取

int main()
{
    welcome();
    game();
    getch();
    return 0;
}

void POS(int x,int y)//設置游標位置,參考網址https://baike.so.com/doc/1283395-1357065.html
{
    COORD pos;
    HANDLE output;
    pos.X=x;
    pos.Y=y;
    output=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(output,pos);
}

void StayAwayFromWall()
{
    if (head->x==0||head->x==58||head->y==0||head->y==29)
    {
        POS(28,14);
        printf("游戲結束你撞牆了\n");
        POS(28,15);
        system("pause");
        exit(0);
    }
}

void DonnotBiteYouself()
{
    while(p->next!=NULL)
    {
        p=p->next;
        if (head->x==p->x&&head->y==p->y)
        {
            POS(28,14);
            printf("游戲結束你咬到自己了\n");
            POS(28,15);
            system("pause");
            exit(0);
        }
    }
}

void drawmap()//畫棋盤
{
    for(i=0;i<60;i+=2)//列印上下邊框
    {
        POS(i,0);
        printf("■");
        POS(i,28);
        printf("■");
    }
    for(i=1;i<28;i++)//列印左右邊框
    {
        POS(0,i);
        printf("■"); 
        POS(58,i);
        printf("■"); 
    }
}

void initsnake()//初始化蛇身 
{
    end=(snake*)malloc(sizeof(snake));
    end->x=28;
    end->y=14;
    end->next=NULL;
    for (i=1;i<=3;i++)
    {
        head=(snake*)malloc(sizeof(snake));
        head->next=end;
        head->x=28+2*i;
        head->y=15;
        end=head;
    }
    while (end->next!=NULL)
    {
        POS(end->x,end->y);
        printf("■");
        end=end->next;
    }
}

void createfood()
{
    srand(time(0));//配合rand使用
    flag:
    while(1)//由於food的x坐標必須為偶數,所以設置迴圈判斷是否為偶數
    {
        foody=rand()%27+1;//先生成y坐標,不能先生成x,x有判斷,先生成x會退出while不生成y
        foodx=rand()%55+2;//rand產生範圍數公式rand()%(m-n+1)+n……其中n<=要生成數的範圍<=m
        if (foodx%2==0)
        {
            break;
        }
    }
    p=head;
    while(1)
    {
        if(p->x==foodx&&p->y==foody)//若生成坐標和蛇重疊了,回到生成坐標迴圈
        {
            goto flag;
        }
        if(p->next==NULL)
        {
            break;
        }
        p=p->next;
    }
    POS(foodx,foody);
    printf("■");
}

void gamecircle()//游戲迴圈,包含移動,暫停功能
{
    key='d';
    while (1)
    {   
        if (GetAsyncKeyState(VK_UP)&&key!='s')
        {
            key='w';
        }
        else if (GetAsyncKeyState(VK_DOWN)&&key!='w')
        {
            key='s';
        }
        else if (GetAsyncKeyState(VK_RIGHT)&&key!='a')
        {
            key='d';
        }
        else if (GetAsyncKeyState(VK_LEFT)&&key!='d')
        {
            key='a';
        }
        else if (GetAsyncKeyState(VK_SPACE))
        {
            pause();
        }
        if (score==levelup&&speed>=10)//判斷成績,每累積30分速度變快
        {
            speed-=10;
            levelup+=30;
            POS(75,12);
            printf("當前速度:每隔%d毫秒移動向前移動",speed);
        }
        move();
    }
}

void move()//移動函數,上下左右箭頭操作,w前s後a左d右(符號說明),函數包含吃食物計分功能
{
    StayAwayFromWall();
    DonnotBiteYouself();
    p=(snake*)malloc(sizeof(snake));
    switch(key)
    {
    case 'd':
    {
        p->next=head;
        p->x=head->x+2;
        p->y=head->y;
        POS(p->x,p->y);
        printf("■");
        head=p;
        Sleep(speed);
        if (p->x==foodx&&p->y==foody)
        {
            createfood();
            score+=10;
            POS(75,11);
            printf("得分:%d",score);
            break;
        }
        while(p->next->next!=NULL)
        {
            p=p->next;
            if(p->next->next==NULL)
            {
                POS(p->x,p->y);
                printf(" ");
                free(p->next);
                p->next=NULL;
                p=head;
                break;
            }
        }
        break;
    }
    case 'w':
    {
        p->next=head;
        p->x=head->x;
        p->y=head->y-1;
        POS(p->x,p->y);
        printf("■");
        head=p;
        Sleep(speed);
        if (p->x==foodx&&p->y==foody)
        {
            createfood();
            score+=10;
            POS(75,11);
            printf("得分:%d",score);
            break;
        }
        while(p->next->next!=NULL)
        {
            p=p->next;
            if(p->next->next==NULL)
            {
                POS(p->x,p->y);
                printf(" ");
                free(p->next);
                p->next=NULL;
                p=head;
                break;
            }
        }
        break;
    }
    case 's':
    {
        p->next=head;
        p->x=head->x;
        p->y=head->y+1;
        POS(p->x,p->y);
        printf("■");
        head=p;
        Sleep(speed);
        if (p->x==foodx&&p->y==foody)
        {
            createfood();
            score+=10;
            POS(75,11);
            printf("得分:%d",score);
            break;
        }
        while(p->next->next!=NULL)
        {
            p=p->next;
            if(p->next->next==NULL)
            {
                POS(p->x,p->y);
                printf(" ");
                free(p->next);
                p->next=NULL;
                p=head;
                break;
            }
        }
        break;
    }
    case 'a':
    {
        p->next=head;
        p->x=head->x-2;
        p->y=head->y;
        POS(p->x,p->y);
        printf("■");
        head=p;
        Sleep(speed);
        if (p->x==foodx&&p->y==foody)
        {
            createfood();
            score+=10;
            POS(75,11);
            printf("得分:%d",score);
            break;
        }
        while(p->next->next!=NULL)
        {
            p=p->next;
            if(p->next->next==NULL)
            {
                POS(p->x,p->y);
                printf(" ");
                free(p->next);
                p->next=NULL;
                p=head;
                break;
            }
        }
        break;
    }
    }
}

void pause()//暫停函數,bug:暫停之後會出現蛇短一格。。繼續蛇身恢復正常,不會解決
{
    do//額外增加的語句,解決上面說的bug,不知道暫停次數多了會不會崩潰,錶面上問題是解決了的
    {
        p=p->next;
    }while(p->next!=NULL);
    POS(p->x,p->y);
    printf("■");
    while(1)//暫停語句
    {
        Sleep(100);
        if (GetAsyncKeyState(VK_SPACE))
        {
            break;
        }
    }//不能用system("pause");會出現按任意鍵繼續字樣
    POS(p->x,p->y);
    printf(" ");
}

void welcome()
{
    POS(28,10);
    printf("歡迎來到貪吃蛇");
    POS(28,11);
    printf("游戲規則:");
    POS(28,12);
    printf("1、不能撞牆");
    POS(28,13);
    printf("2、不能撞自己");
    POS(28,14);
    printf("3、空格可以暫停,再次按下繼續游戲");
    POS(28,15);
    printf("4、要玩的開心");
    POS(28,16);
    printf("5、別按空格開始游戲!!!你按別的鍵都可以繼續,就是別按空格");
    POS(28,17);
    printf("作者:屈振宇");
    POS(28,18);
    printf("別問我為什麼和c語言網上的貪吃蛇那麼像");
    POS(28,19);
    printf("因為結構體和地圖包括坐標的使用都是參照他做的");
    POS(28,20);
    system("pause");
    system("cls");
}

void game()
{
    drawmap();
    initsnake();
    createfood();
    POS(75,11);
    printf("得分:%d",score);
    POS(75,12);
    printf("當前移動速度:每隔%d毫秒移動向前移動",speed);
    POS(75,13);
    printf("每獲得30分速度會加快");
    POS(75,14);
    printf("不能撞牆不能撞自己");
    POS(75,15);
    printf("按空格可以暫停……");
    gamecircle();
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • c3p0-0.9.2.1 jar包和mchange-commons-java-0.2.3.4 jar 包 下載地址: https://pan.baidu.com/s/1jHDiR7g 密碼 tyek ...
  • 環境:python3.6 目的:根據列表 中的字元串導入對應模塊 僅筆記,並知道有什麼實際用處 ...
  • ##閉包 :內部函數,在外部調用不在他函數範圍的變數 def outer(): x=10 def inner(): print(x) return inner #outer()() f=outer() f() 這裡inner就是一個閉包,閉包=內部函數+環境,這裡環境是x=10。閉包是為瞭解釋調用不 ...
  • node-schedule每次都是通過新建一個scheduleJob對象來執行具體方法。 時間數值按下表表示 指定時間有兩種方式1 字元串指定 *之間一定要加空格,否則不執行 每到秒數為4的倍數時執行 在秒位*後加/4 和後面的*之間要有空格schedule.scheduleJob('*/4 * * ...
  • Infi-chu: http://www.cnblogs.com/Infi-chu/ 模塊:filecmp 安裝:Python版本大於等於2.3預設自帶 功能:實現文件、目錄、遍歷子目錄的差異 常用方法: 1.單文件對比(cmp): 2.多文件對比(cmpfiles): 3.目錄對比(dircmp) ...
  • Description 給你一棵TREE,以及這棵樹上邊的距離.問有多少對點它們兩者間的距離小於等於K Input N(n<=40000) 接下來n-1行邊描述管道,按照題目中寫的輸入 接下來是k Output 一行,有多少對點之間的距離小於等於k Sample Input 7 1 6 13 6 3 ...
  • Zookerper在Linux上的安裝 最近在項目的時候,遇到一些linux的相關安裝,雖然不難,但是步驟不少,一不小心就會出錯,這樣去找錯誤費時費力,所以一般都是需要重新再來,實在是讓人頭疼,所以這裡做個總結,為需要的朋友留下一個參考,也給自己加深一下印象。 先來說一下zookeeper的安裝 要 ...
  • Spring Data JPA是依附於Spring Boot的,學習Spring Data JPA之前得先把Spring Boot的環境搭建起來。 先附上一個Spring Data JPA的官方鏈接:https://docs.spring.io/spring-data/jpa/docs/curren ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...