C語言開發(fā)實現(xiàn)貪吃蛇小游戲
小時候相信大家都玩過貪吃蛇,但是自從學了編程以后我都想自己實現(xiàn)一下,苦于沒有契機。
首先看一下游戲效果把:

接下來我們先分析一下貪吃蛇的需求有哪些:
- 用合適的數(shù)據(jù)結(jié)構(gòu)表示蛇、食物
- 地圖的初始化
- 蛇的移動、食物的隨機生成
- 蛇的顯示、食物的顯示
- 貪吃蛇的規(guī)則確定(碰到食物邊長、碰到邊界和自己死亡等……)
主要功能需求就是上面這些,接下來我直接上C語言代碼,這個游戲相信沒做過的人看完之后會覺得非常簡單,因為其中沒什么技術(shù)點可言,最重要的就是下面這幾句代碼,用于控制光標的位置。
#include<Windows.h> COORD cor; cor.X = 0; cor.Y =2; //光標位置更新到(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初始化蛇的初始坐標、以及事務(wù)
//3、將蛇和食物顯示
//4 蛇的移動(WASD)
/*
規(guī)則:
蛇碰到強死掉
蛇碰到自己死掉
蛇碰到食物,身體增長,增加分數(shù)
*/
//5.蛇死掉顯示分數(shù)
//存儲蛇的每一節(jié)的坐標
typedef struct _body
{
int x;
int y;
}BODY;
typedef struct _snake
{
//存儲蛇的身體
BODY list[WIDE * HIGH];//身體的每一節(jié)坐標
int size;//記錄身體長度
BODY food;//食物的位置
int dx;//x移動方向
int dy;//y移動方向
//記錄設(shè)尾位置
int lastx;
int lasty;
}SNAKE;
//初始化食物坐標
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;
//初始化食物的坐標
initFood(s);
//默認向右移動
s->dx = 1;
s->dy = 0;
}
//顯示蛇
void showUi(SNAKE* s)
{
/*
每次顯示都要設(shè)置光標的位置
*/
//顯示蛇
COORD cor;
for (int i = 0; i < s->size; ++i)
{
//設(shè)置光標的位置
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(" ");
}
//更新的蛇的坐標
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++;//增加后的坐標在移動的時候會自己進行加長
}
}
//開始游戲
void startGame(SNAKE* s)
{
//每次對蛇頭是否碰墻進行判斷
while (s->list[0].x<WIDE&&s->list[0].x>=0&&s->list[0].y<HIGH&&s->list[0].y>0)
{
//控制方向
controlSnake(s);
//更新蛇的坐標
moveSnake(s);
//system("cls");//清屏
//蛇移動
showUi(s);
//判斷蛇是否碰到自己
snakeEatSelf(s);
//吃到食物
snakeEatFood(s);
//蛇的速度可以通過睡眠時間進行調(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("+");
}
}
}
}
//隱藏光標
void hideCursor()
{
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible = FALSE;
cursor.dwSize = sizeof(cursor);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle, &cursor);
}
int main()
{
//隱藏光標
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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出
上期我們講完了排序算法下,不知道小伙伴們有沒有發(fā)現(xiàn)一個問題,快速排序和歸并排序我們都是用遞歸來實現(xiàn)的,可能有小伙伴會問,如果說數(shù)據(jù)量很多話,棧區(qū)空間會不會不夠用呢?這期我們就來解決使用遞歸實現(xiàn)的排序?qū)е聴R绯鋈绾谓鉀Q2022-04-04
C語言驅(qū)動開發(fā)之內(nèi)核使用IO/DPC定時器詳解
本章將繼續(xù)探索驅(qū)動開發(fā)中的基礎(chǔ)部分,定時器在內(nèi)核中同樣很常用,在內(nèi)核中定時器可以使用兩種,即IO定時器,以及DPC定時器,感興趣的可以了解一下2023-04-04
C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法
用來映射Unicode字符串的WideCharToMultiByte函數(shù)經(jīng)常被用來進行UTF-8編碼的轉(zhuǎn)換,以下我們將看到C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法,首先先來對WideCharToMultiByte作一個詳細的了解:2016-06-06
你知道如何自定義sort函數(shù)中的比較函數(shù)
這篇文章主要介紹了如何自定義sort函數(shù)中的比較函數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

