用C代码写贪吃蛇游戏--打印食物

本文介绍了使用C语言编写贪吃蛇游戏中食物生成的逻辑,包括如何利用C语言产生随机数创建食物,将食物生成封装为函数,以及在蛇吃掉食物后如何处理食物再生和蛇身增长的问题。同时,文章讨论了优化清屏代码以避免食物消失的bug,并展示了基本功能实现后的代码效果。

贪吃蛇游戏创建食物:

1、食物的产生要求是随机的
2、蛇吃掉食物后会长大
3、蛇吃掉食物后会再次产生食物

因为食物的产生是随机的,要求用C产生随机数:

产生1-610个随机数
int main(void)
{
    int i = 0;

    for(i=0;i<10;i++)
    {
        printf("%d ",rand()%6+1);
    }
    printf("\n");

    return 0;
}

然后我把创建食物封装成一个函数:


void creatFood()
{
    int x = rand() % WIDTH;//在长、宽范围内产生随机数x,y
    int y = rand() % HIGTH;
    COORD pos;
    pos.X = x;//x.y赋值给坐标
    pos.Y = y;
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hout,pos);
    printf("o");//在随机坐标上打印食物o
}

吃掉食物后,蛇身加一,并且再次产生一个食物

if(snakeBodyPosition[0].X == foodPos.X
        &&snakeBodyPosition[0].Y == foodPos.Y)  //当食物坐标与蛇头坐标相同时,蛇变长,再次产生一个食物
    {
        creatFood();
        snakeLen++;
    }

优化清屏代码

清屏的目的是为了让前一段蛇身消失,如果每次都清屏,食物也会消失,这个BUG需要解决,通过改变产生蛇的代码来实现:

void showSnake(int showOrDisapear)
{

    int i = 0;
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    for(i = 0;i < snakeLen;i++)
    {
        SetConsoleCursorPosition(hout,snakeBodyPosition[i]);
        if( showOrDisapear == SHOW)
        {
            printf("*");
        }

        if(showOrDisapear == DISAPEAR)//打印空格来覆盖蛇身
        {
            printf(" ");
        }
    }

}

到这里基本功能就已经全部实现了,下面是代码:


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>

#define SNAKELEN    10
#define SNAKEMAX    10
#define INITSNAKELEN    3


#define RIGHT   1
#define LEFT    2
#define DOWN    3
#define UP      4

#define WIDTH   40
#define HIGTH   20

#define SHOW    8
#define DISAPEAR 9

COORD snakeBodyPosition[SNAKELEN];
void showSnake(int showOrDisapear);
void creatFood();
int snakeLen = 3;
COORD foodPos;

/*-------------初始化蛇,创建一条蛇----------------------*/

void initSnake(COORD snakeHeadPosition )
{   
    int i = 0;

    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);//获取控制台
    COORD tmp = snakeHeadPosition;

    for(i = 0;i < INITSNAKELEN;i++)//打印蛇身
    {
        snakeBodyPosition[i] = tmp;
        SetConsoleCursorPosition(hout,tmp);
        printf("*");
        tmp.X--;

    }
    snakeLen = INITSNAKELEN;
}


/*------------------蛇移动----------------------------------*/

void move(int direction)
{
    Sleep(100);
    //system("cls");
    showSnake(DISAPEAR);

    int i = 0;

    for(i = 0;i < snakeLen - 1;i++)
    {
        snakeBodyPosition[snakeLen -1-i] = snakeBodyPosition[snakeLen - 2-i];   
    }

    switch(direction)
    {
    case RIGHT:
        {
            snakeBodyPosition[0].X++;
            break;
        }
    case LEFT:
        {
            snakeBodyPosition[0].X--;
            break;
        }
    case DOWN:
        {
            snakeBodyPosition[0].Y++;
            break;
        }
    case UP:
        {
            snakeBodyPosition[0].Y--;
            break;
        }
        default:
        {
            break;
        }
    }

    if(snakeBodyPosition[0].X == foodPos.X
        &&snakeBodyPosition[0].Y == foodPos.Y)  //当食物坐标与蛇头坐标相同时,蛇变长,再次产生一个食物
    {
        creatFood();
        snakeLen++;
    }

    showSnake(SHOW);
}


/*------------------打印或者取消蛇身----------------------------*/

void showSnake(int showOrDisapear)
{

    int i = 0;
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    for(i = 0;i < snakeLen;i++)
    {
        SetConsoleCursorPosition(hout,snakeBodyPosition[i]);
        if( showOrDisapear == SHOW)
        {
            printf("*");
        }

        if(showOrDisapear == DISAPEAR)
        {
            printf(" ");
        }
    }

}


/*
实现逻辑:
1、加入按键控制
2、判断是否有按键
3、按照按键来进行移动
4、没有按键,按照固定方向移动

    */

/*-------------按键控制蛇移动--------------*/

void keyboard()//按键控制
{
    char ch = 'd';
    int direction = RIGHT;//前面宏定义RIGHT,UP等是int类型

    while(1)
    {
        move(direction);//调用move函数
        switch(ch)
        {
        case 'w':
            {
                direction = UP;//比如前面定义UP是4,这里把4赋值给direction
                break;
            }
        case 'a':
            {
                direction = LEFT;
                break;
            }
        case 's':
            {
                direction = DOWN;
                break;
            }
        case 'd':
            {
                direction = RIGHT;
                break;
            }   
        default:
            {
                move(direction);//优化之后解决蛇按下其他键或者不按键也能保持原来的移动方向
                break;
            }
        }

        if(kbhit())//如果有按键
        {
            ch = getch();//把getch获取到的按键赋值给ch
        }

    }   
}

/*------------产生食物-----------------------*/

void creatFood()
{
    int x = rand() % WIDTH;//在长、宽范围内产生随机数x,y
    int y = rand() % HIGTH;
    foodPos.X = x;//把x.y赋值给坐标
    foodPos.Y = y;
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hout,foodPos);
    printf("o");//在随机坐标上打印食物o
}

/*--------主函数------------------------*/

int main(int argc, char* argv[])
{
    int i = 0;
    COORD   pos = {0,0};
    initSnake(pos);
    creatFood();
    keyboard();
    printf("\n");
    return 0;
}

实现效果:

这里写图片描述

后面还可以陆续给它加规则,比如弄一个边框,改变蛇身颜色,或者设置障碍物,穿墙等等

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值