当前位置:网站首页>C實現貪吃蛇小遊戲
C實現貪吃蛇小遊戲
2022-07-04 06:03:00 【浪雨123】
貪吃蛇小遊戲可以說是很多小夥伴的遊戲啟蒙之物,今天我們一起來用C語言複刻童年經典遊戲貪吃蛇,在編寫這個遊戲之前,需要了解一些easyx圖形庫的知識,因為遊戲的窗口就是靠此來提供。
這篇文章主要介紹編寫這個遊戲要實現的功能,另外我會再寫一篇關於這個遊戲常見的一些BUG及其解决辦法,如果已經能完成部分的編寫,而困於某些BUG的夥伴可以移步另一篇文章,可能會有你遇到的一些BUG。
實現貪吃蛇遊戲,首先我們需要設置一個遊戲窗口,利用easyx圖形庫,設置一個經典的640*480大小的窗口。窗口設定好了,接下來就可以定義蛇了,我們用結構體來定義蛇的類型,分析一下蛇需要用到那些數據,我們首先需要知道這個蛇有多長,便於遊戲開始時蛇的長度設定,及遊戲結束後蛇長的統計,那我們就用 int n 來錶示蛇的長度。蛇在移動過程中是要有一個移動方向的,因此我們也需要設置一個int direction 來錶示蛇移動的方向,因為方向就四個,我們幹脆就把四個方向枚舉出來,然後蛇的移動方向就用枚舉變量來錶示
//枚舉方向
enum direction
{
up = 72,
down = 80,
left = 75,
right = 77
};
其次我們需要知道蛇的每一節身體的坐標,這樣我們通過坐標來讓蛇移動,以及把蛇繪制到窗口上,因為蛇的身體有很多節,坐標又有x , y兩個值。我們就把坐標單獨定義為結構體,然後身體的每一節都對應著一個坐標,我們用數組來錶示身體
//定義蛇的坐標
struct coor
{
int x;
int y;
}coor;
最終蛇的定義如下
//定義蛇的數據類型
struct snake
{
int n = 3;
direction site;
coor szb[NUM];
}snake;
//其中NUM是該數組的最大值即蛇的身體最長長度,自行定義
定義完蛇的類型,接下來我們就把蛇初始化以下,寫一個初始化函數, initsnake() 假設蛇剛開始長度為3, 方向向左, 坐標依次為
snake.n = 3;
snake.site = left;
snake.szb[0].x = 320;
snake.szb[0].y = 240;
snake.szb[1].x = 310;
snake.szb[1].y = 240;
snake.szb[2].x = 300;
snake.szb[2].y = 240;
初始化完成後,我們就把蛇繪制到窗口上,寫一個 Drawsnake() 函數,其實就是一個循環,以蛇的長度為判定條件,從蛇頭的坐標開始依次繪制,畫矩形或者圓都可,這裏我用的是矩形
void Drawsnake()
{
for (int i = 0; i < snake.n; i++)
{
rectangle(snake.szb[i].x, snake.szb[i].y, snake.szb[i].x+10, snake.szb[i].y+10);
}
}
繪制完成之後,接下來就要讓蛇動起來了,這點很關鍵,如何實現讓蛇動起來,分析可知,蛇移動的原理是讓蛇頭的坐標朝向某個方向不斷的改變,身體再跟著蛇頭一起改變,坐標每變換一次就重新繪制蛇的身體,因為這個過程足够快,我們將其處理的速度用Sleep()再延緩一點,就能形成我們眼睛所能識別的幀率,從而看著蛇是連續移動的。既然要不斷的變換蛇頭的坐標,並且重新繪制蛇的身體,那就要將這兩個函數放到循環裏面,蛇的移動我們編寫一個Movesnake()。
int main()
{
initgraph(640, 480);
initgame();
while (ture)
{
cleardevice();
Movesnake();
Drawsnake();
Sleep(100);
}
}
那麼如何讓蛇的坐標不斷朝著某個方向改變呢?接下來我們就仔細解决Movesnake(),首先我們要判斷具體往哪個方向移動,還記得在定義蛇的時候,設置了一個方向變量site嘛,現在它派上用場了。我們在初始化的時候,將這個變量初始化向左移動,然後程序將蛇頭坐標的x减少10,即向左改變了10個像素點,因為在循環裏,只要site的值不變,蛇頭就一直向左移動,第二節身體的坐標移動到原先蛇頭的比特置,其他節身體的坐標依次移動到它上一節身體的坐標處,這樣就實現了蛇的移動,別忘了加上一個cleardevice()函數,清除上一次繪制的圖形。
switch (snake.site)
{
case up:
snake.szb[0].y-=10;
break;
case down:
snake.szb[0].y+=10;
break;
case left:
snake.szb[0].x-=10;
break;
case right:
snake.szb[0].x+=10;
break;
}
for (int i = snake.n - 1; i > 0; i--) //將蛇的每一節身體的坐標替換成上一節身體的坐標
{
snake.szb[i].x = snake.szb[i - 1].x;
snake.szb[i].y = snake.szb[i - 1].y;
}
蛇的移動完成之後,接下來就是蛇在移動的時候,方向的改變,如果不讓蛇的方向改變,那也沒法玩呢,首先我們只有在按下方向鍵的時候蛇頭的方向才會改變,那就先設置一個變量用來接收我們按下的方向鍵,然後再把這個方向鍵賦值給蛇頭的方向變量,我們就編寫一個Chdirection()函數來實現
void Chdirection()
{
char key;
key = _getch();
switch(key)
{
case up:
if (snake.site != down)
{
snake.site = up;
}
break;
case down:
if (snake.site != up)
{
snake.site = down;
}
break;
case left:
if (snake.site != right)
{
snake.site = left;
}
break;
case right:
if (snake.site != left)
{
snake.site = right;
}
break;
}
}
這裏為什麼要在每一個分支後面加上 if 判斷語句呢,其實就是為了防止蛇直接就調頭了,這和現實是不符的,顯示中的掉頭要繞圈子的。
其實,直接掉頭也是可以的,還蠻有意思的,像火車一樣兩頭開,哈哈,感興趣可以試試。
轉向的問題搞定了,但是程序怎麼知道什麼時候轉向呢?因為這個程序是放在循環裏的,我們不妨加一個判斷語句,用kbhit()函數來檢測玩家是否按下了按鍵,如果按下了就返回真值,進入轉向函數,並在其內部判斷該轉向哪裏,沒有按下就為假,不進入轉向函數。
int main()
{
initgraph(640, 480);
initgame();
while (ture)
{
cleardevice();
Movesnake();
Drawsnake();
Sleep(100);
if ( kbhit() )
{
Chdirection();
}
}
}
小蛇能跑起來了,接下就是吃食物了,那吃食物的效果又該如何實現呢?同樣,我們要給食物定義一個數據類型,首先就是食物的坐標,其次是食物此刻的狀態,是被吃了還是沒被吃,狀態我們就用bool變量
//定義食物的數據類型
struct food
{
int x;
int y;
bool state;
}food;
接著我們回到初始化函數處,給第一個食物的狀態設定一下,定義為true,錶示被吃了,為何設定為被吃了,等會解釋,我們接著編寫Createfood(),用來創造食物,就是給食物的坐標附上隨機值,隨機值就用隨機值生成種子,一旦我們創建一個食物,那創建的瞬間,需要將食物的狀態改成false,錶示未被吃。
void Creatfood()
{
while (1)
{
food.x = rand() % 62 * 10;
food.y = rand() % 46 * 10;
if (food.x >= 20 && food.y >= 20)
{
food.state = false;
break;
}
}
}
//這裏我加循環是不想讓食物生成到邊界點
那麼什麼時候生成食物呢,那當然是食物的狀態為true錶示被吃了的時候,這也是為什麼我們要在開頭處將食物的狀態設置為true,就是為了開局就生成一個食物。同樣要用到一個判斷語句
int main()
{
initgraph(LENGTH, WIDTH);
initgame();
while (1)
{
if (food.state)
{
Creatfood();
}
cleardevice();
Movesnake();
Drawsnake();
Drawfood();
Sleep(100);
EndBatchDraw();
if (_kbhit())
{
Chdirection();
}
}
食物創建好了,現在就剩下最後一步了,那就是實現吃的過程,就編寫個Eatfood(),當蛇頭的坐標與食物的坐標重合時就可以吃了,然後食物的狀態改為true,蛇的身長加1.
void Eatfood()
{
if (snake.szb[0].x == food.x && snake.szb[0].y == food.y)
{
snake.n++;
food.state = true;
}
}
就這樣,簡易的貪吃蛇就完成了,還有一個繪制食物,這個蠻簡單的,各比特夥伴自己實現吧。
int main()
{
initgraph(LENGTH, WIDTH);
initgame();
while (1)
{
if (food.state)
{
Creatfood();
}
cleardevice();
Movesnake();
Drawsnake();
Drawfood();
Eatfood();
Sleep(100);
if (_kbhit())
{
Chdirection();
}
}
getchar();
}
边栏推荐
- 509. Fibonacci number, all paths of climbing stairs, minimum cost of climbing stairs
- Take you to quickly learn how to use qsort and simulate qsort
- [microservice] Nacos cluster building and loading file configuration
- Configure cross compilation tool chain and environment variables
- Steady! Huawei micro certification Huawei cloud computing service practice is stable!
- How to avoid JVM memory leakage?
- Luogu deep foundation part 1 Introduction to language Chapter 5 array and data batch storage
- Leakage detection relay jy82-2p
- Json Web token - jwt vs. Traditional session login Authentication
- Overview of relevant subclasses of beanfactorypostprocessor and beanpostprocessor
猜你喜欢
19. Framebuffer application programming
ES6 模块化
Detailed explanation of common APIs for component and container containers: frame, panel, scrollpane
QT get random color value and set label background color code
Practical gadget instructions
buuctf-pwn write-ups (8)
win10清除快速访问-不留下痕迹
【无标题】
Kubernets first meeting
JS how to convert seconds into hours, minutes and seconds display
随机推荐
实用的小工具指令
Detailed explanation of common APIs for component and container containers: frame, panel, scrollpane
如何展开Collapse 的所有折叠面板
2022.7.2-----leetcode.871
4G wireless all network solar hydrological equipment power monitoring system bms110
Learning multi-level structural information for small organ segmentation
手动对list进行分页(参数list ,当前页,页面大小)
Uninstall Google drive hard drive - you must exit the program to uninstall
1480. Dynamic sum of one-dimensional array
[microservice] Nacos cluster building and loading file configuration
Tutle clock improved version
Invalid revision: 3.18.1-g262b901-dirty
Kubernets first meeting
Functions in C language (detailed explanation)
JS扁平化数形结构的数组
js arguments参数使用和详解
【微服务】Nacos集群搭建以及加载文件配置
Notes and notes
[excel] PivotChart
fastjson