初学者的贪吃蛇游戏

C语言贪吃蛇游戏制作

初学编程,利用现有的知识编写了一个贪吃蛇小游戏。
目前游戏的制作程度仅限于“能玩”。
还有一定BUG有待改善。
以下是代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<windows.h>

#define SNAKE_MAX_LENGTH 30
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

//snake stepping: dy=-1(up),1(down); dx=-1(left),1(right),0(move)
void snakeMove(int, int);
//put a food randomized on a blank cell
void put_money(void);
//out cells of the grid
void output(void);
//outs when gameover
void gameover(void);
//lengthen the snake
void lengthen(void);


char map[12][23]=
   {"**********************",     //初始状态
    "*                    *",      //直接打表
    "*      welcome!      *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*  press any button  *",
    "*      to start      *",
    "*                    *",
    "*                    *",
    "**********************"};


char map1[12][23] = 
    {"**********************",     //初始状态
    "*XXXXH               *",      //直接打表
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "*                    *",
    "**********************"};


// #define vars for snake, notice name of vars in C
int snakeX[SNAKE_MAX_LENGTH] = {1, 2, 3, 4, 5};   //蛇身和蛇头的坐标
int snakeY[SNAKE_MAX_LENGTH] = {1, 1, 1, 1, 1};
int snakeLength = 5;
int flag = 0;  // gameover为1,否则为0
int tailx, taily; // 用于增加长度
int moneyx, moneyy; // 随机生成money坐标
int moneyflag = 0; // 标识是否已经确定位置放money

void snakeMove(int dy, int dx) { //只要控制蛇头
    tailx = snakeX[0];
    taily = snakeY[0]; // 保存尾部位置增加长度
    int tmp, i;
    tmp = snakeLength;                   

    // 尾部消失
    map[snakeY[0]][snakeX[0]] = ' ';
    //身体重复前一个部分

    for (i = 0; i < tmp - 1; i++) {  // 身体先移动一格
            snakeX[i] = snakeX[i + 1];
            snakeY[i] = snakeY[i + 1];
        }

    // 头部移动
    if (dy == -1)
        snakeY[snakeLength - 1]--;
    if (dy == 1)
        snakeY[snakeLength - 1]++;
    if (dx == 1)
        snakeX[snakeLength - 1]++;
    if (dx == -1)
        snakeX[snakeLength - 1]--;
}

void put_money(void) {
    if (moneyflag == 1)  // 若已经放了食物
        return;
    else {
    srand((unsigned int)time(NULL));  // 产生随机坐标
    moneyx = rand() % 21 + 1;
    moneyy = rand() % 10 + 1;
    // 要将money放在空白处
    if (map[moneyy][moneyx] == ' ') {
        moneyflag = 1;
    } else
    put_money();
    }

    // 得到最终坐标
    map[moneyy][moneyx] = '$';
}

void output(void) {
    int i, j;

    for (i = 0, j = 0; i < snakeLength - 1, j <snakeLength - 1; j++, i++)
        map[snakeY[i]][snakeX[j]] = 'X';  //头部位置
    map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] = 'H'; //身体
    for (i = 0; i < 12; i++) {  // 输出图形
    for (j = 0; j < 23; j++) {
    printf("%c", map[i][j]);}
    printf("\n");
} }

void gameover(void) {
    int i;
    // 判断头部是否出界
    if (snakeX[snakeLength - 1] == 0 || snakeX[snakeLength - 1] == 21
        || snakeY[snakeLength - 1] == 0 || snakeY[snakeLength - 1] == 11)
        flag = 1;
    // 判断头部是否与身体重合
    for (i = 0; i < snakeLength - 1;i++)
        if (snakeX[snakeLength - 1] == snakeX[i] && snakeY[snakeLength - 1] == snakeY[i])
        flag = 1;

}

void lengthen(void) {
    int i;
    snakeLength++;   // 长度+1
    for (i = snakeLength - 1; i > 0; i--) {
        snakeY[i] = snakeY[i - 1];   // 将 所有坐标赋值给下一位,用于增大长度
        snakeX[i] = snakeX[i - 1];
    }
    snakeX[0] = tailx;  // 尾部为增加的部位
    snakeY[0] = taily;
}


int main() {
    char move;
    int i,j, hard;
    for (i = 0; i < 12; i++) {  // 欢迎界面
    for (j = 0; j < 23; j++) {
    printf("%c", map[i][j]);}
    printf("\n");}
    getch();
    system("cls");
    for (i = 0; i < 12; i++)  // 初始化地图
    for (j = 0; j < 23; j++)
        map[i][j]=map1[i][j];
    put_money();  // 初始的食物
    for (i = 0; i < 12; i++) {
    for (j = 0; j < 23; j++) {
    printf("%c", map[i][j]);}
    printf("\n");}
    move = 'D';
    int speed = 300;


    while (1) { // 未gameover则一直输入

        Sleep(speed);
        if (kbhit()!=0) {
            move=getch();
                    }
        switch (move) {   // 对输入的处理
            case 'W':
            snakeMove(-1, 0);
            break;
            case 'S':
            snakeMove(1, 0);
            break;
            case 'A':
            snakeMove(0, -1);
            break;
            case 'D':
            snakeMove(0, 1);
            break;
        }       
        // 若头部与食物重合,即吃到食物 
        if (snakeX[snakeLength - 1] == moneyx && snakeY[snakeLength - 1] == moneyy) {
            moneyflag = 0;  // 食物消去
            put_money();   // 产生新的食物
            lengthen();   // 伸长
            speed -= 20;
        }
        gameover();   // 判断是否gameover
        system("cls");   // 清屏
        output();     // 输出当前地图

    if (flag==1)
    break;

    } printf("GAMEOVER\n");

    return 0;
}

没有用到较复杂的知识点,只是用了二维数组来表示地图。
注意:getch(),kbhit() 需要引用头文件 conio.h
Sleep() 需要引用头文件 windows.h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值