視頻地址:C語言必學項目:貪吃蛇!
貪吃蛇游戲框架
├── 基礎框架
│ ├── 頭文件引入
│ ├── 常量和宏定義
│ └── 窗口初始化
│
├── 數據結構系統
│ ├── Pos結構體(位置和顏色)
│ ├── Snake結構體(蛇的屬性)
│ ├── Food結構體(食物屬性)
│ └── DIR枚舉(方向控制)
│
├── 初始化系統
│ ├── 隨機種子設置
│ ├── 蛇屬性初始化
│ ├── 蛇身位置初始化
│ └── 食物生成
│
├── 繪制系統
│ ├── 清屏操作
│ ├── 蛇身繪制
│ ├── 食物繪制
│ └── 分數顯示
│
├── 控制系統
│ ├── 鍵盤輸入檢測
│ ├── 方向鍵處理
│ └── 防反向移動邏輯
│
├── 移動系統
│ ├── 蛇身跟隨算法
│ └── 蛇頭方向移動
│
├── 食物系統
│ ├── 食物生成算法
│ ├── 碰撞檢測
│ ├── 分數增加
│ └── 蛇身增長
│
└── 游戲循環
├── 繪制→移動→輸入→檢測
└── 速度控制
游戲實現步驟分析
1. 基礎框架搭建
// 1. 包含必要的頭文件
#include <graphics.h> // EasyX圖形庫
#include <conio.h> // 控制臺輸入輸出
#include <iostream> // 標準輸入輸出
using namespace std;// 2. 定義游戲窗口大小和常量
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500
2. 數據結構設計
// 3. 定義位置結構體
struct Pos {int x;int y;DWORD color;
};// 4. 定義蛇結構體
struct Snake {int num; // 蛇節數int dir; // 方向int score; // 分數int size; // 尺寸int speed; // 速度Pos coor[MAX_SNAKE]; // 坐標數組
};// 5. 定義食物結構體
struct Food {int x;int y;DWORD color;bool flag; // 是否存在
};// 6. 定義方向枚舉
enum DIR { UP, DOWN, LEFT, RIGHT };
3. 游戲初始化
void GameInit() {// 初始化隨機種子srand(GetTickCount());// 設置蛇的初始屬性snake.num = 3;snake.dir = RIGHT;snake.score = 0;snake.size = 10;snake.speed = 10;// 初始化蛇身位置和顏色snake.coor[0].x = 20;snake.coor[0].y = 0;snake.coor[0].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 隨機生產顏色snake.coor[1].x = 10;snake.coor[1].y = 0;snake.coor[1].color = RGB(rand() % 256, rand() % 256, rand() % 256);snake.coor[2].x = 0;snake.coor[2].y = 0;snake.coor[2].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 初始化食物createFood();
}
4. 游戲繪制系統
void GameDraw() {cleardevice(); // 清屏// 繪制蛇身for (int i = 0; i < snake.num; i++) {setfillcolor(snake.coor[i].color);fillrectangle(snake.coor[i].x, snake.coor[i].y,snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);}// 繪制食物if (food.flag) {setfillcolor(food.color);solidellipse(food.x, food.y, food.x + 10, food.y + 10);}// 繪制分數char temp[20] = "";sprintf(temp, "分數: %d", snake.score);outtextxy(10, 10, temp);
}
5. 輸入控制系統
void GameController() {if (_kbhit()) {char key = _getch();switch (key) {case 72: if (snake.dir != DOWN) snake.dir = UP; break;case 80: if (snake.dir != UP) snake.dir = DOWN; break;case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;}}
}
6. 移動邏輯實現
void GameMove() {// 蛇身跟隨移動for (int i = snake.num - 1; i > 0; i--) {snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}// 蛇頭移動switch (snake.dir) {case UP: snake.coor[0].y -= snake.speed; break;case DOWN: snake.coor[0].y += snake.speed; break;case LEFT: snake.coor[0].x -= snake.speed; break;case RIGHT: snake.coor[0].x += snake.speed; break;}
}
7. 食物系統
void createFood() {food.x = rand() % (WIDTH / 10) * 10;food.y = rand() % (HEIGHT / 10) * 10;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.flag = true;
}void EatFood() {if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) {food.flag = false;snake.num++;snake.score += 10;snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);createFood();}
}
8. 游戲主循環
int main() {initgraph(WIDTH, HEIGHT);setbkcolor(RGB(207, 214, 229));GameInit();while (true) {GameDraw(); // 繪制GameMove(); // 移動if(_kbhit()) { // 輸入檢測GameController();}EatFood(); // 食物檢測Sleep(100); // 控制速度}return 0;
}
9. 完整代碼
// 導入圖形界面庫 EasyX
#include <graphics.h>
//控制鍵盤的頭文件
#include<conio.h>
#include<iostream>
using namespace std;// 定義游戲區域大小
const int WIDTH = 640;
const int HEIGHT = 480;
#define MAX_SNAKE 500 // 常量struct Pos{int x;int y;DWORD color;//DWORD 是 Windows API 中定義的數據類型
};struct Snake{int num; // 蛇身體的節數int dir; // 蛇的方向int score; // 分數int size; // 蛇的寬和高int speed; // 蛇的速度// 記錄蛇的坐標數組struct Pos coor[MAX_SNAKE];
};struct Snake snake;//結構體變量struct Food{int x;int y;DWORD color;bool flag; // 是否被吃掉
} food;enum DIR
{UP,DOWN,LEFT,RIGHT
};// 初始化一下數據
void GameInit() {//蛇的身體的顏色隨機變化srand(GetTickCount());snake.num = 3;snake.dir = RIGHT;snake.score = 0;snake.size = 10;snake.speed = 10;// 初始化蛇身位置和顏色for (int i = 0; i < snake.num; i++) {snake.coor[i].x = 20 - i * 10;snake.coor[i].y = 0;snake.coor[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);}// 初始化食物 顏色隨機變化createFood();
}// 畫蛇 畫食物 畫分數
void GameDraw() {cleardevice();for (int i = 0; i < snake.num; i++){// 填充一下顏色setfillcolor(snake.coor[i].color);// 畫矩形(修正后的)fillrectangle(snake.coor[i].x, snake.coor[i].y,snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);}// 繪制食物if (food.flag){setfillcolor(food.color);solidellipse(food.x, food.y, food.x + 10, food.y + 10);}// 繪制分數char temp[20] = "";sprintf(temp, "分數: %d", snake.score);outtextxy(10, 10, temp);
}//控制蛇的方向
void GameController() {// 獲取鍵盤char key = _getch();// 控制蛇不能往回走switch (key) {case 72: if (snake.dir != DOWN) snake.dir = UP; break;case 80: if (snake.dir != UP) snake.dir = DOWN; break;case 75: if (snake.dir != RIGHT) snake.dir = LEFT; break;case 77: if (snake.dir != LEFT) snake.dir = RIGHT; break;}//cout << (int)key << endl;
}// 讓蛇動起來
void GameMove() {// 循環部分 - 控制蛇身移動for (int i = snake.num - 1; i > 0; i--){snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}// switch部分 - 控制蛇頭移動 [蛇頭控制方向,蛇身跟隨前一個位置]switch (snake.dir) {case UP:snake.coor[0].y -= snake.speed;break;case DOWN:snake.coor[0].y += snake.speed;break;case LEFT:snake.coor[0].x -= snake.speed;break;case RIGHT:snake.coor[0].x += snake.speed;break;}
}// 創建新食物的函數
void createFood() {food.x = rand() % (WIDTH / 10) * 10;food.y = rand() % (HEIGHT / 10) * 10;food.color = RGB(rand() % 256, rand() % 256, rand() % 256);food.flag = true;
}void EatFood() {// 碰撞檢測if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y){// 吃到了food.flag = false;snake.num++;snake.score += 10;snake.coor[snake.num - 1].color = RGB(rand() % 256, rand() % 256, rand() % 256);// 吃完了 在重新創建一個新的食物createFood();}
}
int main() {// 初始化圖形窗口initgraph(WIDTH, HEIGHT);// 設置背景色為淺藍灰色setbkcolor(RGB(207, 214, 229));//清屏再重新繪制所有內容cleardevice();// 初始化蛇的數據GameInit();// 游戲主循環while (true) {GameDraw();GameMove();// 如果按了鍵盤就會執行if(_kbhit()){GameController();}EatFood();Sleep(100);}return 0;
}
10. 改進建議
- 添加碰撞檢測 - 檢測撞墻和自身碰撞
- 改進輸入處理 - 使用Windows API處理方向鍵
- 添加游戲狀態 - 游戲開始、暫停、結束狀態優化
- 食物生成 - 避免食物生成在蛇身上添
- 加音效 - 吃食物和游戲結束的音效