呂橙
摘要:運用EasyX和C語言在Visual Studio 2019 平臺上設(shè)計開發(fā)了一款貪吃蛇游戲。通過游戲的開發(fā),達到學(xué)習(xí)C語言和熟悉軟件開發(fā)流程的目的。
關(guān)鍵詞:EasyX;Visual Studio 2019;貪吃蛇游戲
中圖分類號:TP311.52? ? ? 文獻標識碼:A
文章編號:1009-3044(2021)03-0118-04
Abstract: Using EasyX and C language, a snake game is designed and developed on the platform of visual studio 2019. Through the development of the game, to achieve the purpose of learning C language and familiar with the software development process.
Key words: EasyX; Visual Studio 2019; Snake Game
1 背景
經(jīng)典的貪吃蛇游戲是一款休閑益智類游戲,有PC和手機等多平臺版本。該游戲通過控制蛇頭方向吃食物,從而使得蛇變得越來越長,游戲通過鍵盤操作,簡單方便,老少皆宜。
文獻[1]利用C#開發(fā)環(huán)境,開發(fā)實現(xiàn)了貪吃蛇游戲。文獻[2]基于 HTML5 技術(shù),采用 JavaScript 語言編程實現(xiàn)了簡單的貪吃蛇游戲。文獻[3]利用Protues 設(shè)計軟件并仿真電路,制作了相應(yīng)的PCB板,從硬件和軟件兩方面模擬了貪吃蛇游戲。文獻[4]采用VS2010介紹了C++版的雙人貪吃蛇游戲設(shè)計思想,文獻[5]采用OpenGL實現(xiàn)了多人在線貪吃蛇游戲,可供多人多終端同步游戲。
貪吃蛇游戲常用于學(xué)生課設(shè)、實驗等實踐環(huán)節(jié),本文用EasyX和Visual Studio 2019軟件實現(xiàn)貪吃蛇游戲。
2 貪吃蛇游戲功能分析
2.1 游戲規(guī)則分析
一條蛇出現(xiàn)在封閉空間中,通過鍵盤控制,蛇可以向上下左右四個方向移動。隨機產(chǎn)生食物,如果蛇頭撞到食物,食物消失,蛇身體長增加一節(jié),得分加100,刷新食物。游戲可以設(shè)置蛇移動的速度。如果蛇在前進過程中撞到墻或自己身體,則游戲結(jié)束。
2.2 游戲功能分析
游戲功能設(shè)計為3個模塊:
1)初始化模塊,主要包括初始化地圖、難度設(shè)置、初始化蛇的屬性、初始化食物等;
2)游戲控制模塊,主要包括產(chǎn)生食物、移動蛇、按鍵控制、死亡判斷;
3)統(tǒng)計模塊,主要包括實時顯示玩家積分,玩家積分每超過500,自動升級到下一個難度級別,隨機出現(xiàn)的食物增加1個。
貪吃蛇游戲功能如圖1所示。
3 貪吃蛇游戲詳細設(shè)計
3.1 初始化模塊
功能主要包括初始化地圖、難度設(shè)置、初始化蛇、初始化食物等。其中,難度設(shè)置,難度I每次產(chǎn)生一個食物,難度Ⅱ每次產(chǎn)生兩個食物,難度Ⅲ每次產(chǎn)生三個食物,依次類推,最多每次產(chǎn)生食物不超過10個。
坐標點、蛇、食物的結(jié)構(gòu)體如下:
// 坐標屬性
struct point
{
int x;
int y;
};
// 蛇的屬性
struct Snake
{
vector
point next;? ? ?// 為下一節(jié)預(yù)留的位置
vector
int num;? ? ? ? ?// 長度
int position;? ? ? ? // 方向
}snake;
// 食物的屬性
struct Food
{
point fdxy[10];? ?// 坐標
int grade;? ? // 分數(shù)
int num = 1;? ? ? ?// 食物總數(shù)
COLORREF color[10];? // 食物顏色
}food;
enum position { up, down, left, right };? // 枚舉蛇的方向
3.2 游戲控制模塊
游戲執(zhí)行過程中,通過按鍵控制蛇的走向,移動蛇,不停地產(chǎn)生食物,吃掉食物后,玩家積分增加,如果超過一定積分,難度升級,每次同時產(chǎn)生多個食物,判斷是否撞墻或撞到自己,如果撞到了游戲結(jié)束。
游戲流程如圖2所示。
3.3 統(tǒng)計模塊
游戲過程中,蛇每吃掉一個食物,累積積分100,積分每超過500自動升級到下一個難度級別,系統(tǒng)實時顯示玩家積分。
4 貪吃蛇游戲代碼實現(xiàn)
4.1 游戲中的坐標系
以左上角(0,0)為游戲界面的原點,沿水平方向向右是x軸,逐漸增加,沿垂直方向向下是y軸,逐漸增加。游戲界面設(shè)計原理如圖3所示。
4.2 初始化模塊代碼實現(xiàn)
初始化模塊,主要是初始化游戲界面,初始化蛇,初始化食物。主要代碼如下:
初始化游戲設(shè)置函數(shù):設(shè)置游戲界面尺寸,設(shè)置背景顏色,初始化隨機數(shù)種子,設(shè)置文字前景色和背景色。
initgraph(800, 600);
setbkcolor(RGB(95, 183, 72));
srand((unsigned)time(NULL));
settextcolor(BLUE);
setbkmode(TRANSPARENT);? ?// 設(shè)置文字輸出模式為透明
degree_dif= 1;? ? ? ? ? ? ? ? ? ? ? // 設(shè)置游戲難度
初始化蛇函數(shù):初始化蛇頭位置,蛇身顏色,蛇身字節(jié)數(shù)量。
// 初始化蛇
void initSnake()
{
point xy;
xy.x = 20;
xy.y = 0;
snake.xy.push_back(xy);
snake.color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256)); // 設(shè)置一個隨機顏色
xy.x = 10;
xy.y = 0;
snake.xy.push_back(xy);
snake.color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256)); // 設(shè)置一個隨機顏色
xy.x = 0;
xy.y = 0;
snake.xy.push_back(xy);
snake.color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256)); // 設(shè)置一個隨機顏色
snake.num = 3;
snake.position = right;
}
初始化食物函數(shù):初始化食物位置,食物隨機產(chǎn)生到蛇身處理判斷。
// 初始化食物
void initFood(int num /* 食物編號 */)
{
int i;
food.fdxy[num].x = rand() % 80 * 10;
food.fdxy[num].y = rand() % 60 * 10;
for (i = 0; i < snake.num; i++)
if (food.fdxy[num].x == snake.xy[i].x && food.fdxy[num].y == snake.xy[i].y)? // 避免食物生成在蛇身上
{
food.fdxy[num].x = rand() % 80 * 10;
food.fdxy[num].y = rand() % 60 * 10;
}
}
4.3 游戲控制模塊代碼實現(xiàn)
該模塊需要進行按鍵控制,移動蛇,產(chǎn)生食物,死亡判斷等操作。主要代碼如下:
按鍵控制函數(shù):根據(jù)用戶按鍵,進行判斷,“w”“s”“a”“d”分別表示“上”“下”“左”“右”四個方向。
// 按鍵控制
void keyDown()
{
char userKey = _getch();
if (userKey == -32)? ?// 表明這是方向鍵
userKey = -_getch();? ? ?// 獲取具體方向,并避免與其他字母的 ASCII 沖突
switch (userKey)
{
case 'w':
case 'W':
if (snake.position != down)
snake.position = up;
break;
case 's':
case 'S':
if (snake.position != up)
snake.position = down;
break;
case 'a':
case 'A':
if (snake.position != right)
snake.position = left;
break;
case 'd':
case 'D':
if (snake.position != left)
snake.position = right;
break;
}
}
產(chǎn)生食物函數(shù):吃掉一個食物,積分增加100,積分每得500分,增加一個食物,游戲難度加一。
void createFood()
{
int i;
for (i = 0; i <= food.num - 1; i++)
if (snake.xy[0].x == food.fdxy[i].x && snake.xy[0].y == food.fdxy[i].y)
{
snake.num++;
snake.xy.push_back(snake.next);? // 新增一個節(jié)到預(yù)留位置
snake.color.push_back(food.color[i]); // 將新增節(jié)的顏色設(shè)置為當(dāng)前吃掉食物的顏色
food.grade += 100;
initFood(i);
if (food.num < 10 && food.grade % 500 == 0 && food.grade != 0)
{
food.num++;? // 每得 500 分,增加一個食物,但食物總數(shù)不超過 10 個
degree_dif++;
initFood(food.num - 1); // 初始化新增加的食物
}
break;
}
}
移動蛇函數(shù):蛇頭帶領(lǐng)蛇身移動,不能反向移動,蛇頭可以“上”“下”“左”“右”方向變化。
// 移動蛇
void moveSnake()
{
int i;
// 將預(yù)留節(jié)設(shè)置為未移動前的尾節(jié)
snake.next = snake.xy[snake.num - 1];
// 將除蛇頭以外的節(jié)移動到它的前面一節(jié)
for (i = snake.num - 1; i >= 1; i--)
snake.xy[i] = snake.xy[i - 1];
// 根據(jù)當(dāng)前移動方向移動蛇頭
switch (snake.position)
{
case right:
snake.xy[0].x += 10;
break;
case left:
snake.xy[0].x -= 10;
break;
case up:
snake.xy[0].y -= 10;
break;
case down:
snake.xy[0].y += 10;
}
}
死亡判斷函數(shù):蛇撞到自己或撞到墻,游戲結(jié)束。
// 游戲結(jié)束
bool snakeStatus()
{
// 撞墻,將墻向外擴展一圈(否則蛇無法到達地圖邊緣)
if (snake.xy[0].y <= -10 && snake.position == up)? return true;
if (snake.xy[0].y + 10 >= 610 && snake.position == down) return true;
if (snake.xy[0].x <= -10 && snake.position == left)? return true;
if (snake.xy[0].x + 10 >= 810 && snake.position == right) return true;
// 撞自己
for (int i = 1; i < snake.num; i++)
{
if (snake.xy[0].x <= snake.xy[i].x + 10 && snake.xy[0].x >= snake.xy[i].x && snake.xy[0].y == snake.xy[i].y && snake.position == left)
return true;
if (snake.xy[0].x + 10 >= snake.xy[i].x && snake.xy[0].x + 10 <= snake.xy[i].x + 10 && snake.xy[0].y == snake.xy[i].y && snake.position == right)
return true;
if (snake.xy[0].y <= snake.xy[i].y + 10 && snake.xy[0].y >= snake.xy[i].y && snake.xy[0].x == snake.xy[i].x && snake.position == up)
return true;
if (snake.xy[0].y + 10 >= snake.xy[i].y && snake.xy[0].y + 10 <= snake.xy[i].y + 10 && snake.xy[0].x == snake.xy[i].x && snake.position == down)
return true;
}
return false;
}
4.4 統(tǒng)計功能代碼實現(xiàn)
該模塊的代碼主要是實時統(tǒng)計并顯示玩家積分,積分累加每超過500,自動升級進入到下一個難度級別。
5 系統(tǒng)測試與結(jié)果
游戲?qū)崿F(xiàn)了貪吃蛇游戲基本功能,可以通過操縱“w”“s”“a”“d”實現(xiàn)蛇頭的上下左右轉(zhuǎn)動,運行界面如圖4所示。
游戲功能還可以進一步完善。比如:
1)通過標準鍵盤的方向鍵(left、right、down、up)控制貪吃蛇的移動。
2)游戲界面設(shè)置暫停和啟動功能鍵。
6 結(jié)束語
本文以貪吃蛇游戲為原型,利用EasyX完成了游戲的基本運行,包括游戲的初始化設(shè)置、游戲控制模塊和統(tǒng)計模塊,游戲操作簡單,運行準確,反應(yīng)速度快,基本上滿足了學(xué)生課設(shè)要求,提高學(xué)生的興趣,帶給學(xué)生具有挑戰(zhàn)度的游戲類編程體驗。
參考文獻:
[1] 商利華.C#版貪吃蛇游戲的設(shè)計與實現(xiàn)[J].電腦與電信,2015(11):65-67.
[2] 施瑤.基于HTML5的貪吃蛇游戲設(shè)計與實現(xiàn)[J].福建電腦,2018,34(7):118-119.
[3] 汪源,李宛聰,黃文敏,等.一種基于LabVIEW的貪吃蛇游戲的設(shè)計[J].信息與電腦(理論版),2018(9):102-103,106.
[4] 李嘉誠.基于VS2010的雙人貪吃蛇設(shè)計與實現(xiàn)[J].數(shù)字技術(shù)與應(yīng)用,2015(4):164.
[5] 沈旭,孟巍,彭正超.多人在線版貪吃蛇3D游戲App設(shè)計與開發(fā)[J].計算技術(shù)與自動化,2019,38(4):126-132.
【通聯(lián)編輯:謝媛媛】