“貪喫蛇”作爲一款經典的小遊戲承載了我們的童年回憶。這次我們試着用C語言製作一個簡單的貪喫蛇字符小遊戲。
首先,我們用自頂向下的思路去考慮這個問題,先做一個可以在一定範圍內通過鍵盤控制來移動的“蛇”。
用僞代碼來表示這個過程, 就是:
輸出字符矩陣
WHILE not 遊戲結束 DO
ch=等待輸入
CASE ch DO
‘A’:左前進一步,break
‘D’:右前進一步,break
‘W’:上前進一步,break
‘S’:下前進一步,break
END CASE
輸出字符矩陣
END WHILE
輸出 Game Over!!!
遊戲結束的標誌是貪喫蛇的頭部撞到了“牆”。
經過這樣的分析,我們的遊戲已經有了一定的框架。下面我們套用這個框架完成遊戲的設計吧。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#define head 'H'
#define body 'X'
#define blank_char ' '
這是整個程序的頭部。
遊戲的對象“蛇”的屬性包括位置和長度,用一個結構體來定義:
struct SNAKE
{
int x[100];
int y[100];
int lenth ;
}snake;
定義兩個參數分別控制遊戲的進程和方向:
int gamerun = 1;
char ch;
採用字符型式打印出遊戲的界面:
char map[10][11] =
{
"**********",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"* *",
"**********" };
以下是實現遊戲的幾個重要步驟:
void PrintMap ()
{
int i=0;
system("cls");
for ( i=0; i<10; i++ ) {
printf("%s\n", map[i]);
}
}
void GameOver ()
{
gamerun = 0;
printf("GAME OVER!\n");
}
void InitGame()
{
snake.y[0] = snake.y[1] = snake.y[2] = snake.y[3] = 1;
snake.x[0] = 5;
snake.x[1] = 4;
snake.x[2] = 3;
snake.x[3] = 2;
snake.lenth = 4;
map[snake.y[0]][snake.x[0]] = head;
map[snake.y[1]][snake.x[1]] = body;
map[snake.y[2]][snake.x[2]] = body;
map[snake.y[3]][snake.x[3]] = body;
map[snake.y[4]][snake.x[4]] = body;
gamerun = 1;
PrintMap();
}
void MoveSnake ()
{
int i = 0;
ch = _getch();
map[snake.y[snake.lenth-1]][snake.x[snake.lenth-1]] = blank_char;
map[snake.y[0]][snake.x[0]] = body;
for( i=snake.lenth-1; i; i-- )
{
snake.x[i] = snake.x[i-1];
snake.y[i] = snake.y[i-1];
}
switch(ch)
{
case 'w': snake.y[0]--; break;
case 'a': snake.x[0]--; break;
case 's': snake.y[0]++; break;
case 'd': snake.x[0]++; break;
}
if(map[snake.y[0]][snake.x[0]] != blank_char ) GameOver();
else map[snake.y[0]][snake.x[0]] = head;
}
其中 system(“cls”); 指令不斷的清空屏幕上的內容,接下來的指令再進行反覆地填充。
void InitGame() 初始化整個遊戲的對象。
map[snake.y[snake.lenth-1]][snake.x[snake.lenth-1]] = blank_char;
則是實現了蛇改變方向時“頭尾互換”的操作。
遊戲通過鍵盤上的小寫‘w’,’a’,’s’,’d’控制蛇的移動。
int main()
{
InitGame() ;
while (gamerun)
{
MoveSnake();
PrintMap();
}
return 0;
}
一條會動的蛇,就完成啦!
下面我們僅需要做一些簡單的改動,就可以讓它實現“會喫”的功能了。
在定義頭部時加上食物:
#define food_char '$'
對象“食物”的屬性是它的位置:
struct FOOD
{
int x;
int y;
}food;
主程序中加上一步 SpawnFood();
int main()
{
InitGame() ;
while (gamerun)
{
srand(time(NULL));
MoveSnake();
if(!IsFood) SpawnFood ();
PrintMap();
}
return 0;
}
void SpawnFood ()
{
food.x = rand() % 8 + 1;
food.y = rand() % 9 + 1;
while(map[food.y][food.x] != blank_char) {
food.x = rand() % 8 + 1;
food.y = rand() % 9 + 1;
}
map[food.y][food.x] = food_char;
IsFood = 1;
}
.......
if(map[snake.y[0]][snake.x[0]] != blank_char && map[snake.y[0]][snake.x[0]] != food_char) GameOver();
if(map[snake.y[0]][snake.x[0]] == food_char )
{
map[snake.y[0]][snake.x[0]] = head;
snake.lenth++;
IsFood = 0;
}
else map[snake.y[0]][snake.x[0]] = head;
}
即貪喫蛇的頭部位置與隨機位置出現的食物位置相同時長度加一。
儘管這次製作的小遊戲界面簡陋,玩法單一,(移動起來還略顯zhizhang) 但還是一次有趣的嘗試啦~