溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言怎么實(shí)現(xiàn)控制臺版貪吃蛇游戲

發(fā)布時(shí)間:2021-07-28 19:10:30 來源:億速云 閱讀:188 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“C語言怎么實(shí)現(xiàn)控制臺版貪吃蛇游戲”,在日常操作中,相信很多人在C語言怎么實(shí)現(xiàn)控制臺版貪吃蛇游戲問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C語言怎么實(shí)現(xiàn)控制臺版貪吃蛇游戲”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

/*
{
 conio.h
 阻塞式: getch():   從無回顯的控制臺獲取字符。無緩沖區(qū),只有當(dāng)按下一個(gè)鍵才會執(zhí)行后面的程序。
 非阻塞式: kbhit()    檢測緩沖區(qū)中是否有字符;執(zhí)行該函數(shù)后程序不會停下,而是繼續(xù)執(zhí)行下面的代碼
 
 由于getch()和kbhit()已棄用,
 在編譯時(shí)會產(chǎn)生警告,
 可以用_getch()和_kbhit()替換它們,
 或者在包含頭文件前加上#pragma warning(disable : 4996)關(guān)閉警告
}



*/
#pragma warning(disable : 4996)   //用來關(guān)閉警告
#include<stdio.h>
#include <stdlib.h>
#include <conio.h>   //_kbhit()函數(shù)獲取鍵盤事件
#include <time.h>
#include<Windows.h>


#define WIN_HEIGH  30   //窗口高度
#define WIN_WIDTH 105   //窗口寬度
#define G_HEIGHT  30   //游戲界面高度
#define G_WIDTH 80    //游戲界面寬度
#define STATUS int    //函數(shù)返回狀態(tài)屬性
#define SUCCESS 1    //執(zhí)行成功
#define FAIL 0     //執(zhí)行失敗



typedef struct snake_node{    //蛇的某個(gè)點(diǎn)的信息
 char direct;    //即將前進(jìn)的方向  udlr分別對應(yīng)上下左右,剛吃掉的身體部分方向?yàn)閛
 COORD postion;    //該點(diǎn)所在位置
 struct snake_node* next_node;  //下個(gè)節(jié)點(diǎn)的指針
}*Ps_node,S_node;

typedef struct snake {
 char head_type;   //蛇頭的樣子
 char body_type;   //蛇身的樣子
 WORD color;    //顏色
 int level;    //等級
 int speed;    //速度
 int score;    //成績
 int control;   //控制器 即按wasd進(jìn)行移動,或者按上下左右進(jìn)行移動 
 S_node head;   //蛇頭
}*Psnake,Snake;    //蛇結(jié)構(gòu)



// 0輸出空格 -1輸出#
char canvas[G_HEIGHT][G_WIDTH] ; //畫布
int bean_count;      //已創(chuàng)建食物的數(shù)量
POINT reward_position;    //獎勵的位置
int reward_time = -1000;   //獎勵剩余時(shí)間
int run_snake_threads;    //正在運(yùn)行的蛇的數(shù)量
char keyboard_out[2];    //鍵盤的輸出控制器 keyboard_out[0],代表控制器1,keyboard_out[1],代表控制器2,

int init_snake_speed = 400;   //蛇的初始速度 ,例=400時(shí),蛇0.4s前進(jìn)一步

//關(guān)于顏色取值,請查看help.txt
void gotoxy(int x, int y);           //設(shè)置光標(biāo)到指定位置
void setcolor(WORD wAttributes);         //設(shè)置輸出顏色
void prc_toxy(char c, int x, int y);        //指定位置輸出字符
void prs_toxy(char* str, int x, int y);        //指定位置輸出字符串
void prc_colortoxy(char str, int x, int y, WORD wAttributes);  //在指定位置,以wAttributes顏色輸出字符 
void prs_colortoxy(char* str, int x, int y, WORD wAttributes);  //在指定位置,以wAttributes顏色輸出字符字符串


void one_play_mod();  //進(jìn)入單人模式
void two_play_mod();  //進(jìn)入雙人模式


/***********************

 函數(shù)名:init_system
 功能:
   獲取窗口句柄
   設(shè)置控制臺顏色和大小
   隱藏光標(biāo)顯示

************************/
void init_system();



/***********************
 
 函數(shù)名:init_snode
 功能:初始化新的身體節(jié)點(diǎn)
 輸入?yún)?shù):
  direct:這個(gè)節(jié)點(diǎn)的下一個(gè)運(yùn)動方向;
  snake_x,snake_y:這個(gè)節(jié)點(diǎn)的位置(x,y)
  next_node:下一個(gè)節(jié)點(diǎn)的指針
 返回值:
  Ps_node:返回已初始化的節(jié)點(diǎn)的指針

************************/
Ps_node init_snode(Ps_node n_snode,char drect,int x,int y,Ps_node next_node);


/************************

 函數(shù)名:init_snake
 功能:初始化蛇的相關(guān)參數(shù),并為其創(chuàng)建身體,長度為三
 輸入?yún)?shù):
   she:  要初始化的蛇指針
   color:  蛇的顏色
   head_type:  用該字符顯示蛇的身體
   x,y:  蛇最開始的位置
   direct:  默認(rèn)前進(jìn)方向
   control: 移動蛇的方式:默認(rèn)1為WASD鍵,2為方向鍵盤上下左右鍵
 返回值:初始化后的蛇指針

**************************/
Psnake init_snake(Psnake she ,WORD color,char head_type,char body_type,int x,int y, char direct, int control);  //初始化小蛇


DWORD WINAPI Run_Snake_Thread(LPVOID lpParam);    //線程:運(yùn)行一條蛇
DWORD WINAPI Del_reward_Thread(LPVOID lpParam);    //線程:生成獎勵后,一段時(shí)間內(nèi)不遲到獎勵會消失
DWORD WINAPI Render_Thread(LPVOID lpParam);     //線程:用來渲染,游戲運(yùn)行時(shí),所有的打印顯示由該進(jìn)程完成
DWORD WINAPI Keyboard_Thread(LPVOID lpParam);    //線程:游戲運(yùn)行時(shí),監(jiān)聽按鍵輸入,并設(shè)置keyboard_out




/************************

 函數(shù)名:get_canvas_toxy
 功能: 獲取畫布上該點(diǎn)的值
 輸入?yún)?shù):postion 
 返回值:char類型,畫布上該點(diǎn)的值

************************/
char get_canvas_toxy(COORD postion);



/***********************

 函數(shù)名:snode_gonext
 功能: 蛇身體上的點(diǎn)移動到下個(gè)位置
 輸入?yún)?shù):
  snode:要移動的點(diǎn)
  direct:要移動的方向
 返回值:char ,未移動前,該點(diǎn)要前進(jìn)的方向
************************/
char snode_gonext(Ps_node snode, char direct);



/***********************
 
 函數(shù)名:snake_gonext
 功能: 蛇移動到下個(gè)位置
 輸入?yún)?shù):
  she:要移動的蛇
  direct:蛇頭移動的方向
 返回值:無
************************/
void snake_gonext(Psnake she, char direct);


/********************
 
 函數(shù)名:init_canvas
 功能: 初始化畫布,并為畫布設(shè)置邊框
 輸入?yún)?shù): 無
 返回值: 無

********************/
void init_canvas();


void draw_wall();      //在canvas上設(shè)置邊框位置

 
/***********************

 函數(shù)名:snaketocanvas
 功能:將蛇的坐標(biāo)信息拷貝到畫布canvas上,在canvas上刪除原來的位置信息,
 輸入?yún)?shù):she :要拷貝的蛇的指針

***********************/
void snaketocanvas(Psnake she);

/**************************
 
 函數(shù)名:eat_node
 功能:蛇吃食物,并把它加入蛇身,并增加成績,觸發(fā)升級加速
  (注:加入到蛇身后該點(diǎn)的位置還在原來的地方,需要身體都經(jīng)過那里后長度才會增加)
 輸入?yún)?shù):
   she:吃食物的那條蛇
   position:食物的位置

**************************/
void eat_node(Psnake she, COORD postion);



/**********************
 
 函數(shù)名:create_bean
 功能:在畫布的一個(gè)隨機(jī)位置創(chuàng)建豆

 返回值:
   status:返回是否創(chuàng)建成功
**********************/
STATUS createrand_bean(); 

/**********************
 
 函數(shù)名:free_snake
 功能:釋放小蛇的內(nèi)存
 輸入?yún)?shù):
   she:要釋放內(nèi)存的小蛇

************************/
void free_snake(Psnake she);

void  menu();   //開始菜單, 用來選擇模式,單人或者雙人

void show_menu(int flag);  //根據(jù)不同的flag顯示不同的菜單

HANDLE handle;
int main() {
 init_system();
 menu();
 return 0;
}
void init_system() {
 system("color F0 ");
 handle = GetStdHandle(STD_OUTPUT_HANDLE);//獲取窗口句柄
 char chCmd[32];
 sprintf(chCmd, "mode con cols=%d lines=%d", WIN_WIDTH, WIN_HEIGH);  //設(shè)置控制臺大小
 system(chCmd);
 CONSOLE_CURSOR_INFO cursor_info = { 1,0 };   //設(shè)置光標(biāo)不可見,第一個(gè)值為光標(biāo)厚度,第二個(gè)值為光標(biāo)是否顯示
 SetConsoleCursorInfo(handle, &cursor_info);   // 
 srand((int)time(NULL));        //初始化隨機(jī)數(shù)種子
}
void menu() {
 int ch2, ch3;
 int flag = 1;  //標(biāo)志當(dāng)前選擇模式
 show_menu(flag);
 while (1) {
  ch2 = _getch();
  if (ch2 == 13) {
   printf("此處是進(jìn)入函數(shù)\n");
   if (flag == 1)
    one_play_mod();
   else if (flag == 2)
    two_play_mod();
   else {
    system("cls");
    printf("退出\n");
    break;
   }
  }
  if (ch2==224) {
   ch3 = _getch();
   if (ch3 == 72) {
    flag = (flag + 2)% 3;
   }
   else if (ch3 == 80) {
    flag = (flag + 4) % 3;
   }
  }
  show_menu(flag);
 }
}
void show_menu(int flag) {
 char gamename[30] = "貪      吃      蛇";
 char mod1[20] = "單人模式";
 char mod2[20] = "雙人模式";
 char modexit[20] = "退出";
 int xstr = (WIN_WIDTH - strlen(mod1)) / 2;   //要打印選項(xiàng)的位置x列
 int ystr;           //要打印選項(xiàng)的位置y行
 WORD color[3] = {0xf0,0xf0,0xf0};           //要設(shè)置的顏色
 system("cls");
 setcolor(0xf0);
 prs_toxy(gamename, (WIN_WIDTH - strlen(gamename) )/ 2, 5);
 color[flag] = FOREGROUND_RED | 0xf0;
 prs_colortoxy(mod1, (WIN_WIDTH - strlen(mod1)) / 2, 11, color[1]);
 prs_colortoxy(mod2, (WIN_WIDTH - strlen(mod2)) / 2, 13, color[2]);
 prs_colortoxy(modexit, (WIN_WIDTH - strlen(modexit)) / 2, 15, color[0]);
 if (flag == 1) ystr = 11; else if (flag == 2) ystr = 13; else ystr = 15;  //設(shè)置箭頭位于哪一行
 prs_colortoxy("→", xstr - 4, ystr, color[flag]);
 gotoxy(0, 0);
}
void gotoxy(int x, int y) {
 COORD pos;
 pos.X = x;
 pos.Y = y;
 SetConsoleCursorPosition(handle, pos);
}

void setcolor(WORD wAttributes) {
 SetConsoleTextAttribute(handle, wAttributes);
}
void prc_toxy(char c, int x, int y) {
 gotoxy(x, y);
 printf("%c", c);
}

void prs_toxy(char* str, int x, int y) {
 gotoxy(x, y);
 printf("%s", str);
}
void prc_colortoxy(char c, int x, int y, WORD wAttributes) {
 gotoxy(x, y);
 SetConsoleTextAttribute(handle, wAttributes);
 printf("%c", c);
}
void prs_colortoxy(char* str, int x, int y, WORD wAttributes) {
 gotoxy(x, y);
 SetConsoleTextAttribute(handle, wAttributes);
 printf("%s", str);
}
Ps_node init_snode(Ps_node n_snode, char drect, int x, int y, Ps_node next_node) {
 n_snode->direct = drect;
 n_snode->postion.X = x;
 n_snode->postion.Y = y;
 n_snode->next_node = next_node;
 return n_snode;
}
Psnake init_snake(Psnake she , WORD color, char head_type, char body_type, int x, int y, char direct,int control) {
 int ax=x,ay=y,bx=x,by=y;
 she->head_type = head_type;
 she->body_type = body_type;
 she->color = color;
 she->control = control; 
 she->level = 1;
 she->speed = init_snake_speed;
 she->score = 0;
 Ps_node s1 = (Ps_node)malloc(sizeof(S_node));
 Ps_node s2 = (Ps_node)malloc(sizeof(S_node)); 
 switch (direct)
 {
 case 'l':
  ax = x + 2; bx = x + 1;
  break;
 case 'r':
  ax = x - 2; bx = x - 1;
  break;
 case 'u':
  ay = y + 2; by = y + 1;
  break;
 case 'd':
  ay = y - 2; by = y - 1;
  break;
 default:
  break;
 }
 init_snode(s2, direct, ax, ay, NULL);     //要根據(jù)方向設(shè)置下一個(gè)節(jié)點(diǎn)的位置
 init_snode(s1, direct, bx , by, s2);
 init_snode(&she->head, direct, x, y,s1);
 return she;
}
void one_play_mod() {
 HANDLE hThread;
 HANDLE hThread_render;
 HANDLE hT_getkey;
 Snake xiaoshe;
 system("cls");
 bean_count = 0;
 init_canvas();
 init_snake(&xiaoshe,0xf2, '@','*', G_WIDTH/2, G_HEIGHT/2, 'r', 2);
 snaketocanvas(&xiaoshe);
 createrand_bean();
 run_snake_threads = 1;
 draw_wall();
 hThread = CreateThread(NULL, 0, Run_Snake_Thread,(LPVOID)&xiaoshe, 0, NULL);
 hThread_render = CreateThread(NULL, 0, Render_Thread, (LPVOID)&xiaoshe, 0, NULL);
 hT_getkey= CreateThread(NULL, 0,Keyboard_Thread, NULL, 0, NULL);
 WaitForSingleObject(hThread, INFINITE);
 run_snake_threads = 0;
 WaitForSingleObject(hT_getkey, INFINITE);
 WaitForSingleObject(hThread_render, INFINITE);
 CloseHandle(hThread);
 CloseHandle(hT_getkey);
 CloseHandle(hThread_render);
 gotoxy(G_WIDTH / 2-2, G_HEIGHT / 2);
 printf("游戲結(jié)束\n");
 Sleep(2000);
}
void two_play_mod() {
 HANDLE hThread_a;
 HANDLE hThread_b;
 HANDLE hThread_render;
 HANDLE hT_getkey;
 Snake she[2];
 system("cls");
 bean_count = 0;
 init_canvas();
 init_snake(&she[0], 0xf2, '@', '*', G_WIDTH / 2-4, G_HEIGHT / 2 -4, 'r', 2);
 init_snake(&she[1], 0xE5, 'U', 'S', G_WIDTH / 2, G_HEIGHT / 2, 'l', 1);
 snaketocanvas(&she[0]);
 snaketocanvas(&she[1]);
 draw_wall();
 createrand_bean();
 /*createrand_bean();  //創(chuàng)建多個(gè)食物
 createrand_bean();
 createrand_bean();*/
 run_snake_threads = 2;
 hThread_b = CreateThread(NULL, 0, Run_Snake_Thread, (LPVOID)&she[0], 0, NULL);
 hThread_a = CreateThread(NULL, 0, Run_Snake_Thread, (LPVOID)&she[1], 0, NULL);
 hThread_render= CreateThread(NULL, 0, Render_Thread, (LPVOID)&she, 0, NULL);
 hT_getkey = CreateThread(NULL, 0, Keyboard_Thread, NULL, 0, NULL);
 WaitForSingleObject(hThread_a, INFINITE);
 WaitForSingleObject(hThread_b, INFINITE);
 run_snake_threads = 0;
 WaitForSingleObject(hT_getkey, INFINITE);
 WaitForSingleObject(hThread_render, INFINITE);
 CloseHandle(hThread_a);
 CloseHandle(hThread_b);
 CloseHandle(hT_getkey);
 CloseHandle(hThread_render);
 gotoxy(G_WIDTH / 2, G_HEIGHT / 2);
 printf("游戲結(jié)束\n");
 Sleep(1000);
}
DWORD WINAPI Keyboard_Thread(LPVOID lpParam) {
 int ch2;
 int ch3;
 keyboard_out[0] = 'n'; keyboard_out[1] = 'n';  
 while (run_snake_threads > 0) {
  while (_kbhit())
  {
   ch2 = _getch();
   switch (ch2)
   {
   case 'w':
    keyboard_out[0] = 'u';
    break;
   case 's':
    keyboard_out[0] = 'd';
    break;
   case 'd':
    keyboard_out[0] = 'r';
    break;
   case 'a':
    keyboard_out[0] = 'l';
    break;
   case 224:
    ch3 = _getch();
    switch (ch3)
    {
    case 72:
     keyboard_out[1] = 'u';
     break;
    case 80:
     keyboard_out[1] = 'd';
     break;
    case 77:
     keyboard_out[1] = 'r';
     break;
    case 75:
     keyboard_out[1] = 'l';
     break;
    default:
     break;
    }
    break;
   default:
    break;
   }
  }
  Sleep(50);
 }
}
char get_canvas_toxy(COORD postion) {
 return canvas[postion.Y][postion.X];
}
char snode_gonext(Ps_node snode, char direct) {
 char old_direct = snode->direct;
 snode->direct = direct;
 switch (direct)
 {
 case 'u':
  snode->postion.Y = snode->postion.Y - 1;
  break;
 case 'd':
  snode->postion.Y = snode->postion.Y + 1;
  break;
 case 'l':
  snode->postion.X = snode->postion.X - 1;
  break;
 case 'r':
  snode->postion.X = snode->postion.X + 1;
  break;
 default:
  break;
 }
 return old_direct;
}
void snake_gonext(Psnake she, char direct) {
 Ps_node temp=&she->head;
 Ps_node end = temp;
 char dta=direct;   //方向
 while (temp!=NULL)  //不處理最后一個(gè)節(jié)點(diǎn)
 {
  if(temp->next_node!=NULL && temp->next_node->direct=='n'){
   if (temp->postion.X == temp->next_node->postion.X && temp->postion.Y == temp->next_node->postion.Y) {
    dta = snode_gonext(temp, dta);
    temp->next_node->direct = dta;
   }else
    dta = snode_gonext(temp, dta);
   break;
  }
  dta=snode_gonext(temp, dta);
  temp = temp->next_node;
 }
 snaketocanvas(she);
}
void snaketocanvas(Psnake she) {
 Ps_node temp=&she->head;
 int i, j,x,y;
 char body_type = she->body_type;
 for (i = 1; i < G_HEIGHT - 1; i++)
  for (j = 1; j < G_WIDTH - 1; j++) 
   if (canvas[i][j] == she->head_type || canvas[i][j] == she->body_type)
    canvas[i][j] = '0';
 x = temp->postion.X;
 y = temp->postion.Y;
 while (temp->next_node != NULL) {
  canvas[temp->next_node->postion.Y][temp->next_node->postion.X] = body_type;
  temp = temp->next_node;
 }
 canvas[y][x] = she->head_type;   //單獨(dú)處理蛇頭,放在最后防止被覆蓋
}
void draw_wall() {
 int i, j;
 setcolor(0xf0);
 gotoxy(0, 0);
 for (i = 0; i < G_HEIGHT; i++) {
  gotoxy(0, i);
  for (j = 0; j < G_WIDTH; j++) {
   if (canvas[i][j] == '#')
    printf("#");
   else
    printf(" ");
  }
 }
}
DWORD WINAPI Render_Thread(LPVOID lpParam) {
 Psnake shea = (Psnake)lpParam;
 Psnake sheb = (run_snake_threads==2)?((Psnake)lpParam+1):(shea);
 WORD color;
 char heada = shea->head_type;
 char headb = shea->head_type;
 char pr;
 char pr_score[50];
 char show_time[30];
 int snakes_counts = run_snake_threads;
 int i, j;
 if (snakes_counts == 1) {  //單人模式
  prs_colortoxy("player 1", G_WIDTH + 3, 6, 0xf0);
  prs_colortoxy("↑", G_WIDTH + 15, 5, 0xf0);
  prs_colortoxy("←↓→",G_WIDTH + 13, 6, 0xf0);
 }
 else {
  prs_colortoxy("player 1", G_WIDTH + 3, 6, 0xf0);
  prs_colortoxy("↑", G_WIDTH + 15, 5, 0xf0);
  prs_colortoxy("←↓→", G_WIDTH + 13, 6, 0xf0);

  prs_colortoxy("player 2", G_WIDTH + 3, 19, 0xf0);
  prs_colortoxy("W", G_WIDTH + 14, 18, 0xf0);
  prs_colortoxy("ASD", G_WIDTH + 13, 19, 0xf0);
 }
 while (run_snake_threads != 0)  //根據(jù)snake線程數(shù)結(jié)束循環(huán)
 {
  for (i = 1; i < G_HEIGHT-1; i++) {
   gotoxy(1, i);
   for (j = 1; j < G_WIDTH-1; j++) {
    switch (canvas[i][j])
    {
    case '@':   //蛇頭
     color = (heada == '@') ? shea->color : sheb->color;
     pr = '@';
     break;
    case '*':   //蛇身
     color = (shea->body_type == '*') ? shea->color : sheb->color;
     pr = '*';
     break;
    case 'U':   //蛇頭
     color = (shea->head_type == 'U') ? shea->color : sheb->color;
     pr = 'U';
     break;
    case 'S':   //蛇身
     color = (shea->body_type == 'S') ? shea->color : sheb->color;
     pr = 'S';
     break;
    case '$':   //豆子
     color = 0xf6;
     pr = '$';
     break;
    case '&':   //獎勵
     color = 0xa4;
     pr = '&';
     break;
    case '0':
     color = 0xf0;
     pr = ' ';
     break;
    default:
     break;
    }
    setcolor(color);
    printf("%c", pr);
   }
  }
  sprintf(pr_score, "分?jǐn)?shù):      %d", shea->score);
  prs_colortoxy(pr_score, G_WIDTH + 3, 8, 0xf0);
  if (snakes_counts == 2) {
   sprintf(pr_score, "分?jǐn)?shù):      %d", sheb->score);
   prs_colortoxy(pr_score, G_WIDTH + 3, 21, 0xf0);
  }
  if (reward_time >= 0) {
   sprintf(show_time, "獎勵剩余時(shí)間:%ds  ", reward_time / 1000);
   prs_colortoxy(show_time, G_WIDTH + 5, G_HEIGHT - 3, 0xf4);
  }
  else {
   prs_colortoxy("                    ", G_WIDTH + 5, G_HEIGHT - 3, 0xf4);
  }
  Sleep(50);  //顯示頻率
 }
}

STATUS createrand_bean() {
 int ran;  //canvas的第n個(gè)點(diǎn)為獎勵位置
 int i,j,count,sum=0;
 char c = '$';
 HANDLE delrewarthread;
 
 for (i = 1; i < G_HEIGHT - 1; i++)
  for (j = 1; j < G_WIDTH - 1; j++)
   if (canvas[i][j] == '0') 
    sum++;
 if (sum == 0)
  return FAIL;
 if (bean_count % 5 == 0 && bean_count!=0) {
  ran = rand() % sum;
  count = 0;
  for (i = 1; i < G_HEIGHT - 1; i++)
   for (j = 1; j < G_WIDTH - 1; j++)
    if (canvas[i][j] == '0') {
     if (count == ran) {
      reward_position.x = j;
      reward_position.y = i;
      canvas[i][j] = '&';
      delrewarthread= CreateThread(NULL, 0, Del_reward_Thread, NULL, 0, NULL);
      CloseHandle(delrewarthread);
     }
     count++;
    }
 }
 bean_count++;
 ran = rand() % sum;
 count = 0;
 for (i = 1; i < G_HEIGHT - 1; i++)
  for (j = 1; j < G_WIDTH - 1; j++)
   if (canvas[i][j] == '0') {
    if (count == ran) {
     canvas[i][j] = c;
     return SUCCESS;
    }
    count++;
   }
 return FAIL;
}
void eat_node(Psnake she, COORD postion) {
 Ps_node end = &she->head;
 Ps_node s = (Ps_node)malloc(sizeof(S_node));
 while (end->next_node != NULL)
  end = end->next_node;
 init_snode(s,'n', postion.X, postion.Y, NULL);
 end->next_node = s;
 canvas[postion.Y][postion.X]=she->head_type;
 she->score++;
 if (she->score / 10 >= she->level) {
  she->level++;
  she->speed = (int)(she->speed * 0.75);
 }
}
void free_snake(Psnake she) {
 Ps_node body = she->head.next_node;
 Ps_node temp;
 while (body!=NULL)
 {
  temp = body->next_node;
  free(body);
  body = temp;
 }
}
DWORD WINAPI Run_Snake_Thread(LPVOID lpParam) {
 Psnake pshe = (Psnake)lpParam;
 char direct;
 COORD next_node;   //下一個(gè)蛇頭位置
 char v_canvas;
 boolean end = 0;
 while (!end) {
  direct = pshe->head.direct;
  if (keyboard_out[pshe->control - 1] != 'n') {       //獲取鍵盤輸入的目的是,獲取蛇要前往的下一個(gè)方向
   switch (keyboard_out[pshe->control - 1])  //輸入方向與運(yùn)行方向相反
   {
   case 'u':
    direct = (direct != 'd') ? 'u' : direct;
    break;
   case 'd':
    direct = (direct != 'u') ? 'd' : direct;
    break;
   case 'l':
    direct = (direct != 'r') ? 'l' : direct;
    break;
   case 'r':
    direct = (direct != 'l') ? 'r' : direct;
    break;
   default:
    break;
   }
   keyboard_out[pshe->control - 1] = 'n';
  }
  next_node = pshe->head.postion;
  switch (direct)
  {
  case 'u':
   next_node.Y = next_node.Y - 1;
   break;
  case 'd':
   next_node.Y = next_node.Y + 1;
   break;
  case 'l':
   next_node.X = next_node.X - 1;
   break;
  case 'r':
   next_node.X = next_node.X + 1;
   break;
  default:
   break;
  }
  v_canvas = get_canvas_toxy(next_node);
  switch (v_canvas)
  {
  case '0':      //表示該點(diǎn)安全,沒有東西
   snake_gonext(pshe, direct);
   break;
  case '$':
   eat_node(pshe, next_node);
   snake_gonext(pshe, direct);
   end = !createrand_bean();
   break;
  case '&':      //吃下道具,觸發(fā)減速
   eat_node(pshe, next_node);
   snake_gonext(pshe, direct);
   pshe->speed =(int) (pshe->speed * 1.25);
   break;
  default:
   end = 1;
   break;
  }
  Sleep(pshe->speed);
 }
 free_snake(pshe);  //這里只釋放了蛇的身體其他信息仍保留
 Sleep(500);
 return 0;
}
DWORD WINAPI Del_reward_Thread(LPVOID lpParam) {
 
 reward_time = 10000;
 while (reward_time >=0)
 {
  if (canvas[reward_position.y][reward_position.x] == '&' && run_snake_threads>0) {
   Sleep(1000);
   reward_time = reward_time - 1000;
  }
  else
   break;
 }
 canvas[reward_position.y][reward_position.x] = '0';
 reward_time = -1000;
 return 0;
}
void init_canvas() {
 int i, j;
 for (i = 0; i < G_HEIGHT; i++)
  for (j = 0; j < G_WIDTH; j++) 
   canvas[i][j] = '0';
 for (i = 0; i < G_HEIGHT ; i++) {
  canvas[i][0] = '#';
  canvas[i][G_WIDTH - 1] = '#';
 }
 for (j = 0; j < G_WIDTH; j++) {
  canvas[0][j] = '#';
  canvas[G_HEIGHT  - 1][j] = '#';
 }
}

到此,關(guān)于“C語言怎么實(shí)現(xiàn)控制臺版貪吃蛇游戲”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI