呂橙



摘要:運用EasyX和C語言在Visual Studio 2019 平臺上設計開發了一款貪吃蛇游戲。通過游戲的開發,達到學習C語言和熟悉軟件開發流程的目的。
關鍵詞: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 背景
經典的貪吃蛇游戲是一款休閑益智類游戲,有PC和手機等多平臺版本。該游戲通過控制蛇頭方向吃食物,從而使得蛇變得越來越長,游戲通過鍵盤操作,簡單方便,老少皆宜。
文獻[1]利用C#開發環境,開發實現了貪吃蛇游戲。文獻[2]基于 HTML5 技術,采用 JavaScript 語言編程實現了簡單的貪吃蛇游戲。文獻[3]利用Protues 設計軟件并仿真電路,制作了相應的PCB板,從硬件和軟件兩方面模擬了貪吃蛇游戲。文獻[4]采用VS2010介紹了C++版的雙人貪吃蛇游戲設計思想,文獻[5]采用OpenGL實現了多人在線貪吃蛇游戲,可供多人多終端同步游戲。
貪吃蛇游戲常用于學生課設、實驗等實踐環節,本文用EasyX和Visual Studio 2019軟件實現貪吃蛇游戲。
2 貪吃蛇游戲功能分析
2.1 游戲規則分析
一條蛇出現在封閉空間中,通過鍵盤控制,蛇可以向上下左右四個方向移動。隨機產生食物,如果蛇頭撞到食物,食物消失,蛇身體長增加一節,得分加100,刷新食物。游戲可以設置蛇移動的速度。如果蛇在前進過程中撞到墻或自己身體,則游戲結束。
2.2 游戲功能分析
游戲功能設計為3個模塊:
1)初始化模塊,主要包括初始化地圖、難度設置、初始化蛇的屬性、初始化食物等;
2)游戲控制模塊,主要包括產生食物、移動蛇、按鍵控制、死亡判斷;
3)統計模塊,主要包括實時顯示玩家積分,玩家積分每超過500,自動升級到下一個難度級別,隨機出現的食物增加1個。
貪吃蛇游戲功能如圖1所示。
3 貪吃蛇游戲詳細設計
3.1 初始化模塊
功能主要包括初始化地圖、難度設置、初始化蛇、初始化食物等。其中,難度設置,難度I每次產生一個食物,難度Ⅱ每次產生兩個食物,難度Ⅲ每次產生三個食物,依次類推,最多每次產生食物不超過10個。
坐標點、蛇、食物的結構體如下:
// 坐標屬性
struct point
{
int x;
int y;
};
// 蛇的屬性
struct Snake
{
vector
point next;? ? ?// 為下一節預留的位置
vector
int num;? ? ? ? ?// 長度
int position;? ? ? ? // 方向
}snake;
// 食物的屬性
struct Food
{
point fdxy[10];? ?// 坐標
int grade;? ? // 分數
int num = 1;? ? ? ?// 食物總數
COLORREF color[10];? // 食物顏色
}food;
enum position { up, down, left, right };? // 枚舉蛇的方向
3.2 游戲控制模塊
游戲執行過程中,通過按鍵控制蛇的走向,移動蛇,不停地產生食物,吃掉食物后,玩家積分增加,如果超過一定積分,難度升級,每次同時產生多個食物,判斷是否撞墻或撞到自己,如果撞到了游戲結束。
游戲流程如圖2所示。
3.3 統計模塊
游戲過程中,蛇每吃掉一個食物,累積積分100,積分每超過500自動升級到下一個難度級別,系統實時顯示玩家積分。
4 貪吃蛇游戲代碼實現
4.1 游戲中的坐標系
以左上角(0,0)為游戲界面的原點,沿水平方向向右是x軸,逐漸增加,沿垂直方向向下是y軸,逐漸增加。游戲界面設計原理如圖3所示。
4.2 初始化模塊代碼實現
初始化模塊,主要是初始化游戲界面,初始化蛇,初始化食物。主要代碼如下:
初始化游戲設置函數:設置游戲界面尺寸,設置背景顏色,初始化隨機數種子,設置文字前景色和背景色。
initgraph(800, 600);
setbkcolor(RGB(95, 183, 72));
srand((unsigned)time(NULL));
settextcolor(BLUE);
setbkmode(TRANSPARENT);? ?// 設置文字輸出模式為透明
degree_dif= 1;? ? ? ? ? ? ? ? ? ? ? // 設置游戲難度
初始化蛇函數:初始化蛇頭位置,蛇身顏色,蛇身字節數量。
// 初始化蛇
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)); // 設置一個隨機顏色
xy.x = 10;
xy.y = 0;
snake.xy.push_back(xy);
snake.color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256)); // 設置一個隨機顏色
xy.x = 0;
xy.y = 0;
snake.xy.push_back(xy);
snake.color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256)); // 設置一個隨機顏色
snake.num = 3;
snake.position = right;
}
初始化食物函數:初始化食物位置,食物隨機產生到蛇身處理判斷。
// 初始化食物
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 游戲控制模塊代碼實現
該模塊需要進行按鍵控制,移動蛇,產生食物,死亡判斷等操作。主要代碼如下:
按鍵控制函數:根據用戶按鍵,進行判斷,“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;
}
}
產生食物函數:吃掉一個食物,積分增加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);? // 新增一個節到預留位置
snake.color.push_back(food.color[i]); // 將新增節的顏色設置為當前吃掉食物的顏色
food.grade += 100;
initFood(i);
if (food.num < 10 && food.grade % 500 == 0 && food.grade != 0)
{
food.num++;? // 每得 500 分,增加一個食物,但食物總數不超過 10 個
degree_dif++;
initFood(food.num - 1); // 初始化新增加的食物
}
break;
}
}
移動蛇函數:蛇頭帶領蛇身移動,不能反向移動,蛇頭可以“上”“下”“左”“右”方向變化。
// 移動蛇
void moveSnake()
{
int i;
// 將預留節設置為未移動前的尾節
snake.next = snake.xy[snake.num - 1];
// 將除蛇頭以外的節移動到它的前面一節
for (i = snake.num - 1; i >= 1; i--)
snake.xy[i] = snake.xy[i - 1];
// 根據當前移動方向移動蛇頭
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;
}
}
死亡判斷函數:蛇撞到自己或撞到墻,游戲結束。
// 游戲結束
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 統計功能代碼實現
該模塊的代碼主要是實時統計并顯示玩家積分,積分累加每超過500,自動升級進入到下一個難度級別。
5 系統測試與結果
游戲實現了貪吃蛇游戲基本功能,可以通過操縱“w”“s”“a”“d”實現蛇頭的上下左右轉動,運行界面如圖4所示。
游戲功能還可以進一步完善。比如:
1)通過標準鍵盤的方向鍵(left、right、down、up)控制貪吃蛇的移動。
2)游戲界面設置暫停和啟動功能鍵。
6 結束語
本文以貪吃蛇游戲為原型,利用EasyX完成了游戲的基本運行,包括游戲的初始化設置、游戲控制模塊和統計模塊,游戲操作簡單,運行準確,反應速度快,基本上滿足了學生課設要求,提高學生的興趣,帶給學生具有挑戰度的游戲類編程體驗。
參考文獻:
[1] 商利華.C#版貪吃蛇游戲的設計與實現[J].電腦與電信,2015(11):65-67.
[2] 施瑤.基于HTML5的貪吃蛇游戲設計與實現[J].福建電腦,2018,34(7):118-119.
[3] 汪源,李宛聰,黃文敏,等.一種基于LabVIEW的貪吃蛇游戲的設計[J].信息與電腦(理論版),2018(9):102-103,106.
[4] 李嘉誠.基于VS2010的雙人貪吃蛇設計與實現[J].數字技術與應用,2015(4):164.
[5] 沈旭,孟巍,彭正超.多人在線版貪吃蛇3D游戲App設計與開發[J].計算技術與自動化,2019,38(4):126-132.
【通聯編輯:謝媛媛】