字符遊戲——貪喫蛇的設計思路

“貪喫蛇”作爲一款經典的小遊戲承載了我們的童年回憶。這次我們試着用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) 但還是一次有趣的嘗試啦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章