c语言贪吃蛇(极简版,基本能玩)

c语言贪吃蛇

整体逻辑

  1. 界面绘制
  2. 定义结构体以及结构体的初始化
    2.1 一节变三节
  3. 蛇的移动
    3.1 监控键盘
    3.2 蛇的移动
  4. 食物
    4.1 定义
    4.2 初始化
    4.3 食物的绘制
  5. 食物的再生与身体增长、分数
  6. 死亡与结束
  7. 优化
    7.1 getch()函数会返回两个数值,过滤第一个,留下第二个真实键值

界面绘制与主函数

c 复制代码
#include<graphics.h> //图形界面库
#include<stdio.h>
#include<stdlib.h>
int main()
{
	//界面绘制
	initgraph(WIN_WIDTH, WIN_HEIGTH);//初始化窗口
	setbkcolor(RGB(207, 214, 229));//设置背景颜色
	cleardevice();//刷新窗口
    
    //初始化
    GemeInit();
    
    while (1) {
	//绘制
	GameDraw();
	//移动
	GameMove();
	BeginBatchDraw();//双缓存机制,减少闪烁
	//控制键盘
	KeyControl;
	FlushBatchDraw();//刷新双缓冲区
	EatFood();
	Sleep(100);
}

}

定义和初始化

  • c 复制代码
    //定义蛇
    struct Snake {
    	int num; //蛇身长
    	int dir; //方向
    	int score; //分数
    	int size; //蛇的宽和高 定位
    	int speed;//蛇速度
    	//坐标
    	struct Pos coor[MAX_SNAKE];
    }snake;
    // 定位
    struct Pos
    {
    	int x;
    	int y;
    };
  • 食物

    c 复制代码
    //定义食物
    struct Food {
    	int x;
    	int y;
    	bool flag;//判断食物是否存在
    }food;
  • 初始化

    c 复制代码
    //初始化
    void GemeInit() {
    	snake.num = 3;
    	snake.dir = RIGHT;
    	snake.score = 0;
    	snake.size = 15;
    	snake.speed = 10;
    
    	//三节蛇身的初始化
    	snake.coor[0].x = 200;  //修改初始位置,避免蛇身重叠
    	snake.coor[0].y = 200;
    	snake.coor[1].x = 185;
    	snake.coor[1].y = 200;
    	snake.coor[2].x = 170;
    	snake.coor[2].y = 200;
        
        //食物的初始化
    	food.x = rand() % (WIN_WIDTH / 10) * 10;
    	food.y = rand() % (WIN_HEIGTH / 10) * 10;
    	food.flag = true;
    }

根据坐标绘制图形

  • 绘制蛇身、食物、分数

    c 复制代码
    void GameDraw() {
    	cleardevice();//清屏
        
    	//三节蛇身
    	for (int i = 0; i < snake.num; i++)
    	{
    		//蛇的填充色
    		setfillcolor(BLACK);
    		//画矩形
    		fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
    	}
        
        //食物,复用蛇身
    	setfillcolor(BLACK);
    	fillrectangle(food.x, food.y, food.x + 		snake.size, food.y + snake.size);
        
        //分数
        char temp[20] = "";
    	sprintf(temp, "分数%d", snake.score);
    	outtextxy(10, 10, temp);
    }

蛇的移动

  • 监控键盘

    c 复制代码
    void KeyControl() {
    	//只有按键按下时才处理
    	if (_kbhit()) {
    		char key = _getch();//接收getch()函数的第一个返回值
    		char key2 = _getch();//接收getch()函数的第二个返回值,即真实键值
    		if (key == -32) {
    			switch (key2) {
    			case 72:
    				if (snake.dir != DOWN) {
    					snake.dir = UP;
    					printf("↑\n");
    				}
    				break;
    			case 75:
    				if (snake.dir != RIGHT) {
    					snake.dir = LEFT;
    					printf("←\n");
    				}
    				break;
    			case 77:
    				if (snake.dir != LEFT) {
    					snake.dir = RIGHT;
    					printf("→\n");
    				}
    				break;
    			case 80:
    				if (snake.dir != UP) {
    					snake.dir = DOWN;
                        printf("↓\n");
    				}
    				break;
    			}
    		}
    	}
    }
  • 蛇的移动

    c 复制代码
    void GameMove() {
    	//从蛇尾开始覆盖,a,b,c三节考虑。
    	for (int i = snake.num - 1; i > 0; i--) {
    		snake.coor[i].x = snake.coor[i - 1].x;
    		snake.coor[i].y = snake.coor[i - 1].y;
    	}
    
    	switch (snake.dir) {
    	case UP:
    		snake.coor[0].y -= snake.speed;
    		break;
    	case DOWN:
    		snake.coor[0].y += snake.speed;
    		break;
    	case LEFT:
    		snake.coor[0].x -= snake.speed;
    		break;
    	case RIGHT:
    		snake.coor[0].x += snake.speed;
    		break;
    	}
    }

吃食物

  • 消失与再生

    c 复制代码
    //吃食物
    void EatFood() {
    	if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) {
    		food.flag = false;
    		snake.num++;
    		snake.score += 10;
    	}
    	CreateFood();
    }
    
    //生成食物
    void CreateFood() {
    	if (!food.flag) {
    		food.x = rand() % (WIN_WIDTH / 10) * 10;
    		food.y = rand() % (WIN_HEIGTH / 10) * 10;
    		food.flag = true;
    	}
    }

完整代码

c 复制代码
/*
1. 界面绘制
2. 定义结构体以及结构体的初始化
	2.1 一节变三节,绘制蛇身
3. 蛇的移动
	3.1 监控键盘
	3.2 蛇的移动
4. 绘制食物
	4.1 定义
	4.2 初始化
	4.3 食物的绘制
5. 食物的再生与身体增长、分数
6. 死亡与结束
7. 优化
	7.1 getch()函数会返回两个数值,过滤第一个,留下第二个真实键值
*/

#include<graphics.h> //图形界面库
#include<stdio.h>
#include <conio.h> //键盘监控
#include<stdlib.h>

#define MAX_SNAKE 500
#define WIN_WIDTH 640
#define WIN_HEIGTH 480




// 定位
struct Pos
{
	int x;
	int y;
};

// 蛇的结构体
struct Snake {
	int num; //蛇身长
	int dir; //方向
	int score; //分数
	int size; //蛇的宽和高 定位
	int speed;//蛇速度
	//坐标
	struct Pos coor[MAX_SNAKE];
}snake;

struct Food {
	int x;
	int y;
	bool flag;//判断食物是否存在
}food;

//枚举类型定义方向
enum DIR {
	UP,
	DOWN,
	LEFT,
	RIGHT
};

//初始化
void GemeInit() {
	snake.num = 3;
	snake.dir = RIGHT;
	snake.score = 0;
	snake.size = 15;
	snake.speed = 10;

	//三节蛇身
	snake.coor[0].x = 200;  //修改初始位置,避免蛇身重叠
	snake.coor[0].y = 200;
	snake.coor[1].x = 185;
	snake.coor[1].y = 200;
	snake.coor[2].x = 170;
	snake.coor[2].y = 200;

	//食物
	food.x = rand() % (WIN_WIDTH / 10) * 10;
	food.y = rand() % (WIN_HEIGTH / 10) * 10;
	food.flag = true;

}

// 绘制三节蛇身、食物、分数
void GameDraw() {
	cleardevice();//
	for (int i = 0; i < snake.num; i++)
	{
		//蛇的填充色
		setfillcolor(BLACK);
		//画矩形
		fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
	}

	//食物的填充色
	setfillcolor(BLACK);
	//画矩形
	fillrectangle(food.x, food.y, food.x + snake.size, food.y + snake.size);

	char temp[20] = "";
	sprintf(temp, "分数%d", snake.score);
	outtextxy(10, 10, temp);
}

//蛇的移动
void GameMove() {
	//从蛇尾开始覆盖,a,b,c三节考虑。
	for (int i = snake.num - 1; i > 0; i--) {
		snake.coor[i].x = snake.coor[i - 1].x;
		snake.coor[i].y = snake.coor[i - 1].y;
	}

	switch (snake.dir) {
	case UP:
		snake.coor[0].y -= snake.speed;
		break;
	case DOWN:
		snake.coor[0].y += snake.speed;
		break;
	case LEFT:
		snake.coor[0].x -= snake.speed;
		break;
	case RIGHT:
		snake.coor[0].x += snake.speed;
		break;
	}
}

//监控键盘
void KeyControl() {
	//只有按键按下时才处理
	if (_kbhit()) {
		char key = _getch();//接收getch()函数的第一个返回值
		char key2 = _getch();//接收getch()函数的第二个返回值,即真实键值
		if (key == -32) {
			switch (key2) {
			case 72:
				if (snake.dir != DOWN) {
					snake.dir = UP;
					printf("↑\n");
				}
				break;
			case 75:
				if (snake.dir != RIGHT) {
					snake.dir = LEFT;
					printf("←\n");
				}
				break;
			case 77:
				if (snake.dir != LEFT) {
					snake.dir = RIGHT;
					printf("→\n");
				}
				break;
			case 80:
				if (snake.dir != UP) {
					snake.dir = DOWN;
                    printf("↓\n");
				}
				break;
			}
		}
	}
}

//生成食物
void CreateFood() {
	if (!food.flag) {
		food.x = rand() % (WIN_WIDTH / 10) * 10;
		food.y = rand() % (WIN_HEIGTH / 10) * 10;
		food.flag = true;
	}
}

//吃食物
void EatFood() {
	if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) {
		food.flag = false;
		snake.num++;
		snake.score += 10;
	}
	CreateFood();
}

int main()
{
	//界面绘制
	initgraph(WIN_WIDTH, WIN_HEIGTH);//初始化窗口
	setbkcolor(RGB(207, 214, 229));//设置背景颜色
	cleardevice();//刷新窗口

	GemeInit();

	while (1) {
		//绘制
		GameDraw();
		//移动
		GameMove();
		BeginBatchDraw();//双缓存机制,减少闪烁
		//控制键盘
		KeyControl;
		FlushBatchDraw();//刷新双缓冲区
		EatFood();
		Sleep(100);
	}
}
相关推荐
Sammyyyyy13 分钟前
Node.js 做 Web 后端优势为什么这么大?
开发语言·前端·javascript·后端·node.js·servbay
ST.J30 分钟前
webpack笔记
前端·笔记·webpack
27^×41 分钟前
Java 内存模型与垃圾回收机制详解
java·开发语言
计算机编程小央姐43 分钟前
数据安全成焦点:基于Hadoop+Spark的信用卡诈骗分析系统实战教程
大数据·hadoop·python·spark·毕业设计·课程设计·dash
研梦非凡1 小时前
CVPR 2025|无类别词汇的视觉-语言模型少样本学习
人工智能·深度学习·学习·语言模型·自然语言处理
max5006001 小时前
本地部署开源数据生成器项目实战指南
开发语言·人工智能·python·深度学习·算法·开源
q567315231 小时前
手把手教你用Go打造带可视化的网络爬虫
开发语言·爬虫·信息可视化·golang
Bling_Bling_11 小时前
面试常考:js中 Map和 Object 的区别
开发语言·前端·javascript
l1t1 小时前
美团龙猫利用expat库实现的保存xml指定范围数据到csv的C程序
xml·c语言·解析器·expat
姚瑞南1 小时前
【AI产品思路】AI 原型设计工具横评:产品经理视角下的 v0、Bolt 与 Lovable
人工智能·经验分享·笔记·aigc·产品经理