c语言游戏开发之贪吃蛇

一、建立背景

这里可以运用界面函数initgraph(a,b)来建立,其头文件为<grapgics.h>。

注意:为了防止卡退需要使用while(1){ }来一直循坏。

#include<stdio.h>
#include<graphics.h>

//首先定义一个图形界面
int main() {
    initgraph(1000, 600);
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    while (1) {
        
    }
}

如图:

二、定义蛇

由于蛇需要有节数大小、速度、方向、坐标,所以用结构体来定义蛇。

struct Point {
    int x;
    int y;
}; //蛇的坐标分为横坐标纵坐标

typedef enum {
    up,
    down,
    left,
    right
}; //通过枚举分别列出蛇的四个方向

struct Snake {
    int size;//节数
    int dir;//方向
    int speed;//速度
    struct Point point[100];//坐标
}snake;

由于还未初始化,这时界面任然未发生变化。

三、初始化蛇

蛇的轮廓定义完成之后,需要考虑蛇的身体,这里可以使用retrange()矩形函数或者solidcircle()画一个实心圆来表示蛇,其函数头文件为<conio.h>。也就是所谓“画蛇”drawsnake。由于画蛇需要蛇的节数,所以我们先初始化蛇。

初始化蛇的身体,如蛇的节数、速度、初始位置等等。

void initsnake() {

    snake.size = 4;//设置蛇的初始节数为4
    snake.speed = 10;//设置蛇的速度为10
    snake.dir = right;//设置蛇的初始方向为向右移动
    for (int i = 0; i < snake.size; i++) {
        snake.point[i].x = 40 - 10 * i;//由于设置的是四节蛇,这样设置使每节相隔10
        snake.point[i].y = 10;//使初始蛇的纵坐标统一固定在同一水平线
    }
}
void drawsnake() {
    
    for (int i = 0; i < snake.size; i++) {
        rectangle(snake.point[i].x, snake.point[i].y, snake.point[i].x + 10, snake.point[i].y + 10);
       //画矩形,也可以用solidcircle(snake.point[i].x, snake.point[i].y,5)
    }
}

总代码如下:注意不要忘了函数头文件,以及在main函数中调用已写好的函数。

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
struct Point {
    int x;
    int y;
}; //蛇的坐标分为横坐标纵坐标

typedef enum {
    up,
    down,
    left,
    right
}; //通过枚举分别列出蛇的四个方向

struct Snake {
    int size;//节数
    int dir;//方向
    int speed;//速度
    struct Point point[100];//坐标
}snake;

void initsnake() {

    snake.size = 4;//设置蛇的初始节数为4
    snake.speed = 10;//设置蛇的速度为10
    snake.dir = right;//设置蛇的初始方向为向右移动
    for (int i = 0; i < snake.size; i++) {
        snake.point[i].x = 40 - 10 * i;//由于设置的是四节蛇,这样设置使每节相隔10
        snake.point[i].y = 10;//使初始蛇的纵坐标统一固定在同一水平线
    }
}
void drawsnake() {

    for (int i = 0; i < snake.size; i++) {
        rectangle(snake.point[i].x, snake.point[i].y, snake.point[i].x + 10, snake.point[i].y + 10);
        //画矩形,也可以用solidcircus(snake.point[i].x, snake.point[i].y,5)
    }
}
//首先定义一个图形界面
int main() {
    initgraph(1000, 600);
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    initsnake();
    while (1) {
        drawsnake();
    }
}

这时的运行结果:

四、移动蛇

由于是简易版的贪吃蛇,所以设置了“穿墙”设定。


void movesnake() {
    
    for (int i = snake.size-1; i > 0;i--) {
        snake.point[i] = snake.point[i-1];
       //从蛇尾开始,蛇尾等于上一个蛇身,即每一个点等于它上一个点的坐标
    }
    switch (snake.dir) {
    case right: snake.point[0].x = snake.point[0].x + snake.speed;
        if (snake.point[0].x + snake.speed >= 1000) 
        {
            snake.point[0].x = 0;//穿墙
        }break;
    case left:
        snake.point[0].x = snake.point[0].x - snake.speed;
        if (snake.point[0].x - snake.speed <= 0)
        {
            snake.point[0].x = 1000;//穿墙
        }
        break;
    case up:
        snake.point[0].y = snake.point[0].y - snake.speed;
        if (snake.point[0].y - snake.speed <= 0)
        {
            snake.point[0].y = 600;//穿墙
        }
        break;
    case down:
        snake.point[0].y = snake.point[0].y + snake.speed;//或者snake.point[0].y += snake.speed;
        if (snake.point[0].y + snake.speed >= 600)
        {
            snake.point[0].y = 0;//穿墙
        }
        break;
    default:
        break;
    
    }
}

总代码:

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
struct Point {
    int x;
    int y;
}; //蛇的坐标分为横坐标纵坐标

typedef enum {
    up=72,
    down=80,
    left=75,
    right=77
}; //通过枚举分别列出蛇的四个方向

struct Snake {
    int size;//节数
    int dir;//方向
    int speed;//速度
    struct Point point[100];//坐标
}snake;

void initsnake() {

    snake.size = 4;//设置蛇的初始节数为4
    snake.speed = 10;//设置蛇的速度为10
    snake.dir = right;//设置蛇的初始方向为向右移动
    snake.point[0].x = 10;
    snake.point[0].y = 10;
    for (int i = 0; i < snake.size; i++) {
        snake.point[i].x = 40 - 10 * i;//由于设置的是四节蛇,这样设置使每节相隔10
        snake.point[i].y = 10;//使初始蛇的纵坐标统一固定在同一水平线
    }
}
void drawsnake() {
   
    for (int i = 0; i < snake.size; i++) {
        rectangle(snake.point[i].x, snake.point[i].y, snake.point[i].x + 10, snake.point[i].y + 10);
       //画矩形,也可以用solidcircle(snake.point[i].x, snake.point[i].y,5)
    }
}
void movesnake() {
    
    for (int i = snake.size-1; i > 0;i--) {
        snake.point[i] = snake.point[i-1];
       //从蛇尾开始,蛇尾等于上一个蛇身,即每一个点等于它上一个点的坐标
    }
    switch (snake.dir) {
    case right: snake.point[0].x = snake.point[0].x + snake.speed;
        if (snake.point[0].x + snake.speed >= 1000) {
            snake.point[0].x = 0;
        }break;
    case left:
        snake.point[0].x = snake.point[0].x - snake.speed;
        if (snake.point[0].x - snake.speed <= 0)
        {
            snake.point[0].x = 1000;
        }
        break;
    case up:
        snake.point[0].y = snake.point[0].y - snake.speed;
        if (snake.point[0].y - snake.speed <= 0)
        {
            snake.point[0].y = 600;
        }
        break;
    case down:
        snake.point[0].y = snake.point[0].y + snake.speed;//或者snake.point[0].y += snake.speed;
        if (snake.point[0].y + snake.speed >= 600)
        {
            snake.point[0].y = 0;
        }
        break;
    default:
        break;
    
    }
}

//首先定义一个图形界面
int main() {
    initgraph(1000, 600);
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    initsnake();
    while (1) {
        drawsnake();
        movesnake();
        Sleep(80);//延时
    }
    return 0;
}

这里发现一个问题,蛇的轨迹并没有去除

最后发现,是代码setbkcolor(RGB(28, 1115, 119));与cleardevice();的问题,需要放到循坏while(1)内部,或者放到“画蛇”里。

错误代码:

int main() {
    initgraph(1000, 600);
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    while (1) {
      
    }
    return 0;
}

正确代码:

int main() {
    initgraph(1000, 600);
    while (1) {
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    }
    return 0;
}

或者

void drawsnake() {
    setbkcolor(RGB(28, 1115, 119));//设置背景颜色
    cleardevice();//用该颜色清除图形屏幕,也就是填充背景
    }
}

四、键盘输入控制蛇的方向

通过键盘wsad键,或者上下左右键控制蛇的运动方向。

void KeyControl()
{
   // 判断有没有按键;
    if (_kbhit())//检测有没有按键,如果有就返回真,否则返回假;
    {
        //72 80 75 77上下左右键值;
        switch (_getch())
        {
        case 'w':
        case 'W':
        case 72:
            if (snake.dir != down)
            {
                snake.dir = up;
            }
            break;
        case 's':
        case 'S':
        case 80:
            if (snake.dir != up)
            {
                snake.dir = down;
            }
            break;
        case 'a':
        case 'A':
        case 75:
            if (snake.dir != right)
            {
                snake.dir = left;
            }
            break;
        case 'd':
        case 'D':
        case 77:
            if (snake.dir != left)
            {
                snake.dir = right;
            }
            break;
        case ' ':
            while (1)
            {
                if (_getch() == ' ');
                return;
            }
           
        }
    }
}

总码:

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
struct Point {
    int x;
    int y;
}; //蛇的坐标分为横坐标纵坐标

typedef enum {
    up=72,
    down=80,
    left=75,
    right=77
}; //通过枚举分别列出蛇的四个方向

struct Snake {
    int size;//节数
    int dir;//方向
    int speed;//速度
    struct Point point[100];//坐标
}snake;

void initsnake() {

    snake.size = 4;//设置蛇的初始节数为4
    snake.speed = 10;//设置蛇的速度为10
    snake.dir = right;//设置蛇的初始方向为向右移动
    snake.point[0].x = 10;
    snake.point[0].y = 10;
    for (int i = 0; i < snake.size; i++) {
        snake.point[i].x = 40 - 10 * i;//由于设置的是四节蛇,这样设置使每节相隔10
        snake.point[i].y = 10;//使初始蛇的纵坐标统一固定在同一水平线
    }
}
void drawsnake() {
   
    for (int i = 0; i < snake.size; i++) {
        rectangle(snake.point[i].x, snake.point[i].y, snake.point[i].x + 10, snake.point[i].y + 10);
       //画矩形,也可以用solidcircle(snake.point[i].x, snake.point[i].y,5)
    }
}
void movesnake() {
    
    for (int i = snake.size-1; i > 0;i--) {
        snake.point[i] = snake.point[i-1];
       //从蛇尾开始,蛇尾等于上一个蛇身,即每一个点等于它上一个点的坐标
    }
    switch (snake.dir) {
    case right: snake.point[0].x = snake.point[0].x + snake.speed;
        if (snake.point[0].x + snake.speed >= 1000) {
            snake.point[0].x = 0;
        }break;
    case left:
        snake.point[0].x = snake.point[0].x - snake.speed;
        if (snake.point[0].x - snake.speed <= 0)
        {
            snake.point[0].x = 1000;
        }
        break;
    case up:
        snake.point[0].y = snake.point[0].y - snake.speed;
        if (snake.point[0].y - snake.speed <= 0)
        {
            snake.point[0].y = 600;
        }
        break;
    case down:
        snake.point[0].y = snake.point[0].y + snake.speed;//或者snake.point[0].y += snake.speed;
        if (snake.point[0].y + snake.speed >= 600)
        {
            snake.point[0].y = 0;
        }
        break;
    default:
        break;
    
    }
}


void KeyControl()
{
   // 判断有没有按键;
    if (_kbhit())//检测有没有按键,如果有就返回真,否则返回假;
    {
        //72 80 75 77上下左右键值;
        switch (_getch())
        {
        case 'w':
        case 'W':
        case 72:
            if (snake.dir != down)
            {
                snake.dir = up;
            }
            break;
        case 's':
        case 'S':
        case 80:
            if (snake.dir != up)
            {
                snake.dir = down;
            }
            break;
        case 'a':
        case 'A':
        case 75:
            if (snake.dir != right)
            {
                snake.dir = left;
            }
            break;
        case 'd':
        case 'D':
        case 77:
            if (snake.dir != left)
            {
                snake.dir = right;
            }
            break;
        case ' ':
            while (1)
            {
                if (_getch() == ' ');
                return;
            }
           
        }
    }
}
//首先定义一个图形界面
int main() {
    initgraph(1000, 600);
    initsnake();
    while (1) {
        setbkcolor(RGB(28, 1115, 119));//设置背景颜色
        cleardevice();//用该颜色清除图形屏幕,也就是填充背景
        drawsnake();
        movesnake();
        KeyControl();
        Sleep(80);//延时

    }
    return 0;
}

最终结果

吃食物还没解决,下节继续哈~

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值