C語言開發(fā)實(shí)現(xiàn)貪吃蛇小游戲
小時(shí)候相信大家都玩過貪吃蛇,但是自從學(xué)了編程以后我都想自己實(shí)現(xiàn)一下,苦于沒有契機(jī)。
首先看一下游戲效果把:
接下來我們先分析一下貪吃蛇的需求有哪些:
- 用合適的數(shù)據(jù)結(jié)構(gòu)表示蛇、食物
- 地圖的初始化
- 蛇的移動(dòng)、食物的隨機(jī)生成
- 蛇的顯示、食物的顯示
- 貪吃蛇的規(guī)則確定(碰到食物邊長、碰到邊界和自己死亡等……)
主要功能需求就是上面這些,接下來我直接上C語言代碼,這個(gè)游戲相信沒做過的人看完之后會(huì)覺得非常簡單,因?yàn)槠渲袥]什么技術(shù)點(diǎn)可言,最重要的就是下面這幾句代碼,用于控制光標(biāo)的位置。
#include<Windows.h> COORD cor; cor.X = 0; cor.Y =2; //光標(biāo)位置更新到(0,2) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor);
源碼:
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<Windows.h> #include<conio.h> #define WIDE 60 # define HIGH 20 //1設(shè)置地圖邊界 //2初始化蛇的初始坐標(biāo)、以及事務(wù) //3、將蛇和食物顯示 //4 蛇的移動(dòng)(WASD) /* 規(guī)則: 蛇碰到強(qiáng)死掉 蛇碰到自己死掉 蛇碰到食物,身體增長,增加分?jǐn)?shù) */ //5.蛇死掉顯示分?jǐn)?shù) //存儲(chǔ)蛇的每一節(jié)的坐標(biāo) typedef struct _body { int x; int y; }BODY; typedef struct _snake { //存儲(chǔ)蛇的身體 BODY list[WIDE * HIGH];//身體的每一節(jié)坐標(biāo) int size;//記錄身體長度 BODY food;//食物的位置 int dx;//x移動(dòng)方向 int dy;//y移動(dòng)方向 //記錄設(shè)尾位置 int lastx; int lasty; }SNAKE; //初始化食物坐標(biāo) void initFood(SNAKE* s) { srand(time(NULL)); s->food.x = rand() % WIDE; s->food.y = rand() % HIGH; } //初始化蛇 void initSnake(SNAKE* s) { //頭部 s->list[0].x = WIDE / 2; s->list[0].y = HIGH / 2; //第一節(jié) s->list[1].x = WIDE / 2-1; s->list[1].y = HIGH / 2; //記錄身體大小 s->size = 2; //初始化食物的坐標(biāo) initFood(s); //默認(rèn)向右移動(dòng) s->dx = 1; s->dy = 0; } //顯示蛇 void showUi(SNAKE* s) { /* 每次顯示都要設(shè)置光標(biāo)的位置 */ //顯示蛇 COORD cor; for (int i = 0; i < s->size; ++i) { //設(shè)置光標(biāo)的位置 cor.X = s->list[i].x; cor.Y = s->list[i].y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cor); //蛇頭 if (i == 0) { printf("@"); continue; } printf("*"); } //顯示食物 cor.X = s->food.x; cor.Y = s->food.y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cor); printf("#"); //清除掉蛇尾 cor.X = s->lastx; cor.Y = s->lasty; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor); printf(" "); } //更新的蛇的坐標(biāo) void moveSnake(SNAKE* s) { //記錄下蛇尾的位置 s->lastx = s->list[s->size - 1].x; s->lasty = s->list[s->size - 1].y; for (int i = s->size-1; i >0; --i) { s->list[i].x = s->list[i - 1].x; s->list[i].y = s->list[i - 1].y; } s->list[0].x += s->dx; s->list[0].y += s->dy; } void controlSnake(SNAKE* s) { char key=0; //判斷按鍵 while (_kbhit()) { key = _getch(); } switch (key) { case 'a': s->dx = -1; s->dy = 0; break; case 's': s->dx = 0; s->dy = 1; break; case 'd': s->dx = 1; s->dy = 0; break; case 'w': s->dx = 0; s->dy = -1; break; default: break; } } //游戲結(jié)束 void gameEnd(SNAKE* s) { COORD cor; cor.X = 0; cor.Y = HIGH + 1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor); printf("游戲結(jié)束,最終得分為%d\n", (s->size - 2) * 10); //直接退出程序 exit(0); } //蛇吃到自己 void snakeEatSelf(SNAKE* s) { for (int i = 1; i < s->size; ++i) { if (s->list[0].x == s->list[i].x && s->list[0].y == s->list[i].y) { gameEnd(s); } } } //吃到食物 void snakeEatFood(SNAKE* s) { if (s->list[0].x == s->food.x && s->list[0].y == s->food.y) { //食物重置 initFood(s); //蛇加長 s->size++;//增加后的坐標(biāo)在移動(dòng)的時(shí)候會(huì)自己進(jìn)行加長 } } //開始游戲 void startGame(SNAKE* s) { //每次對(duì)蛇頭是否碰墻進(jìn)行判斷 while (s->list[0].x<WIDE&&s->list[0].x>=0&&s->list[0].y<HIGH&&s->list[0].y>0) { //控制方向 controlSnake(s); //更新蛇的坐標(biāo) moveSnake(s); //system("cls");//清屏 //蛇移動(dòng) showUi(s); //判斷蛇是否碰到自己 snakeEatSelf(s); //吃到食物 snakeEatFood(s); //蛇的速度可以通過睡眠時(shí)間進(jìn)行調(diào)整 Sleep(200); } gameEnd(s); } //初始化邊界 void initWall() { COORD cor; for (int i = 0; i <= WIDE; ++i) { for (int j = 0; j <= HIGH; ++j) { if (i == 0 || i == WIDE||j==0||j==HIGH) { COORD cor; cor.X = i; cor.Y = j; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor); printf("+"); } } } } //隱藏光標(biāo) void hideCursor() { CONSOLE_CURSOR_INFO cursor; cursor.bVisible = FALSE; cursor.dwSize = sizeof(cursor); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorInfo(handle, &cursor); } int main() { //隱藏光標(biāo) hideCursor(); //初始化地圖 initWall(); //蛇類型定義 SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE)); //初始化蛇和食物 initSnake(snake); //顯示蛇 showUi(snake); //開始游戲 startGame(snake); free(snake); //程序在HIGH+1行后面輸出 COORD cor; cor.X = 0; cor.Y =HIGH+2; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cor); return 0; }
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言中如何實(shí)現(xiàn)單鏈表刪除指定結(jié)點(diǎn)
這篇文章主要介紹了C語言中如何實(shí)現(xiàn)單鏈表刪除指定結(jié)點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07C++ 數(shù)據(jù)結(jié)構(gòu)之布隆過濾器
這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)之布隆過濾器的相關(guān)資料,需要的朋友可以參考下2017-06-06Qt串口通信開發(fā)之Qt串口通信模塊QSerialPort開發(fā)完整實(shí)例(串口助手開發(fā))
這篇文章主要介紹了Qt串口通信開發(fā)之Qt串口通信模塊QSerialPort開發(fā)完整實(shí)例(串口助手開發(fā)),需要的朋友可以參考下2020-03-03String底層函數(shù)的實(shí)現(xiàn)方式詳解
這篇文章主要介紹了String底層函數(shù)的實(shí)現(xiàn)方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09C++數(shù)據(jù)結(jié)構(gòu)之鏈表的創(chuàng)建
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之鏈表的創(chuàng)建的相關(guān)資料,希望通過本文幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10