IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言贪吃蛇 -> 正文阅读

[C++知识库]C语言贪吃蛇

参考视频:C/C++游戏项目教程:C语言经典贪吃蛇!零基础小白看完一个半小时就能制作出经典游戏,最详细解析!_哔哩哔哩_bilibili

1. 任务分析

? ? ? ? 需要图形库:easyx,官方文档:EasyX 文档 - 使用教程

任务的几个步骤:

(1)界面的设置

(2)对蛇的设置

(3)按键对蛇进行操作

(4)增加食物模块

(5)游戏规则添加

本次只完成游戏的基本功能
注意:绘制图形后,重新绘制的图形会在原来的基础上进行绘制,需要使用 ?cleardevice() ?将之前的图形擦除

2. 界面设置

#define WIN_WIDTH	640				// 窗口宽度
#define WIN_HIGH	480				// 窗口高度  

    // 创建绘图窗口,大小为 640x480 像素,EW_SHOWCONSOLE显示控制台
	// initgraph(640, 480, EW_SHOWCONSOLE);
	initgraph(WIN_WIDTH, WIN_HIGH);

	// 设置背景颜色
	setbkcolor(RGB(28, 115, 119));
	cleardevice();        // 画完后需要加一条该命令,可当做刷新屏幕

3. 蛇的设置

? ? ? ? 蛇的参数包括:身体节数、方向、坐标、速度,设置一个结构体

#define SNAKE_NUM	500				// 蛇的最大节数
#define	SNAKE_COLOR	RED             // 蛇的颜色
#define SNAKE_BODY	5				// 蛇身体的半径

enum DIR							// 蛇的方向
{
	up, down, right, left
};

// 蛇的结构
struct Snake {
	int size;						// 蛇的节数
	int dir;						// 方向
	int speed;						// 速度
	POINT coor[SNAKE_NUM];			// 坐标
};

/* POINT是库里就带有的结构体
typedef struct _POINTL      
    LONG  x;
    LONG  y;
} POINTL, *PPOINTL;
*/

? ? ? ? 对蛇进行初始化

// 蛇的初始化
void snake_init(void)
{
	snake.size = 3;
	snake.dir = right;
	snake.speed = 10;
	for (int i = 0; i < snake.size; i++)
	{
		snake.coor[i].x = 200 - 10 * i;
		snake.coor[i].y = 200;
	}
}

4.按键实现蛇的移动

? ? ? ? 通过按键改变蛇的方向

// 通过按键改变蛇的方向
void keyControl(void)
{
	// 判断有没有按键,有按键返回真
	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() == ' ')
				{
					break;
				}
			}
			break;
		default:
			break;
		}

	}
}

? ? ? ? 蛇的移动,蛇的移动可以只关注第一节身体,其余身体的下一次移动为上一节身体的坐标

// 蛇的移动
void snake_move(void)
{

	for (int i = snake.size - 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 right:
		snake.coor[0].x += 10;
		break;
	case left:
		snake.coor[0].x -= 10;
		break;
	case up:
		snake.coor[0].y -= 10;
		break;
	case down:
		snake.coor[0].y += 10;
		break;
	}
}

5. 增加食物模块

? ? ? ? 定义一个食物的结构体

#define FOOD_COLOR	YELLOW			// 蛇和食物的颜色
#define FOOD_SIZE	5				// 食物半径
// 食物结构
struct Food {
	POINT coor;
	int r;
	bool flag;						// 食物是否被吃
};

? ? ? ? 对食物模块进行初始化

void food_init(void)
{
	// 一般将时间作为种子
	srand((unsigned int)time(NULL));
	food.coor.x = rand() % WIN_WIDTH;
	food.coor.y = rand() % WIN_HIGH;
	food.flag = true;
}

? ? ? ? 判断是否吃了食物

// 判断是否吃了食物
void EatFood(void)
{
	if (food.flag &&
		snake.coor[0].x >= food.coor.x - SNAKE_BODY - FOOD_SIZE &&
		snake.coor[0].x <= food.coor.x + SNAKE_BODY + FOOD_SIZE &&
		snake.coor[0].y >= food.coor.y - SNAKE_BODY - FOOD_SIZE &&
		snake.coor[0].y <= food.coor.y + SNAKE_BODY + FOOD_SIZE
		)
	{
		food.flag = false;
		snake.size++;
	}
	if (!food.flag)
	{
		food.coor.x = rand() % (WIN_WIDTH - 2 * FOOD_SIZE) + FOOD_SIZE;
		food.coor.y = rand() % (WIN_HIGH - 2 * FOOD_SIZE) + FOOD_SIZE;
		food.flag = true;
	}
}

6. 源码

// snake.h
#define _CRT_SECURE_NO_WARNINGS       // visual studio不支持scanf,需要在头文件前添加该宏定义

#ifndef _SNAKE_H_
#define _SNAKE_H_


#include<stdio.h>
#include<easyx.h>
#include<conio.h>   // _getch()的头文件
#include<time.h>
/*
	图形库:easyx
	文件后缀要改成.cpp,使用c语言编译器会出错

	1.设置界面
		界面初始化
	2.设置蛇
		对蛇进行初始化,进行移动
	3.按键对蛇进行操作
		按照游戏规则对代码进行修改,撞击,移动等。
	4.增加食物模块

*/
#define WIN_WIDTH	640				// 窗口宽度
#define WIN_HIGH	480				// 窗口高度  

#define SNAKE_NUM	500				// 蛇的最大节数
#define	SNAKE_COLOR	RED
#define FOOD_COLOR	YELLOW			// 蛇和食物的颜色
#define SNAKE_BODY	5				// 蛇身体的半径
#define FOOD_SIZE	5				// 食物半径

enum DIR							// 蛇的方向
{
	up, down, right, left
};

// 蛇的结构
struct Snake {
	int size;						// 蛇的节数
	int dir;						// 方向
	int speed;						// 速度
	POINT coor[SNAKE_NUM];			// 坐标
};

// 食物结构
struct Food {
	POINT coor;
	int r;
	bool flag;						// 食物是否被吃

};

void Game_init(void);				// 游戏初始化
void snake_init(void);				// 蛇的初始化
void food_init();					// 食物初始化
void Game_draw(void);				// 绘制函数
void snake_move(void);				// 蛇的移动
void keyControl(void);				// 通过按键改变蛇的方向
void EatFood(void);					// 判断食物是否被吃
void Snake_life(void);				// 判断蛇是否活着
#endif 
// main.cpp

#include"snake.h"

int main(void)
{
	// 初始化界面
	Game_init();

	// 绘图
	Game_draw();

	while (1)
	{
		Sleep(80);
		keyControl();
		snake_move();
		Snake_life();
		EatFood();
		cleardevice();
		Game_draw();
	}

	while (1);
	return 0;
}
// init.cpp

#include"snake.h"

extern struct Food food;
extern struct Snake snake;

void Game_init(void)
{
	// 创建绘图窗口,大小为 640x480 像素,EW_SHOWCONSOLE显示控制台
	// initgraph(640, 480, EW_SHOWCONSOLE);
	initgraph(WIN_WIDTH, WIN_HIGH);

	// 设置背景颜色
	setbkcolor(RGB(28, 115, 119));
	cleardevice();

	snake_init();
	food_init();
}

void food_init(void)
{
	// 一般将时间作为种子
	srand((unsigned int)time(NULL));
	food.coor.x = rand() % WIN_WIDTH;
	food.coor.y = rand() % WIN_HIGH;
	food.flag = true;
}


// 蛇的初始化
void snake_init(void)
{
	snake.size = 3;
	snake.dir = right;
	snake.speed = 10;
	for (int i = 0; i < snake.size; i++)
	{
		snake.coor[i].x = 200 - 10 * i;
		snake.coor[i].y = 200;
	}
}

// 判断是否吃了食物
void EatFood(void)
{
	if (food.flag &&
		snake.coor[0].x >= food.coor.x - SNAKE_BODY - FOOD_SIZE &&
		snake.coor[0].x <= food.coor.x + SNAKE_BODY + FOOD_SIZE &&
		snake.coor[0].y >= food.coor.y - SNAKE_BODY - FOOD_SIZE &&
		snake.coor[0].y <= food.coor.y + SNAKE_BODY + FOOD_SIZE
		)
	{
		food.flag = false;
		snake.size++;
	}
	if (!food.flag)
	{
		food.coor.x = rand() % (WIN_WIDTH - 2 * FOOD_SIZE) + FOOD_SIZE;
		food.coor.y = rand() % (WIN_HIGH - 2 * FOOD_SIZE) + FOOD_SIZE;
		food.flag = true;
	}
}
// game.cpp

#include"snake.h"

struct Food food;
struct Snake snake;

void Game_draw(void)
{
	// 双缓冲绘图
	BeginBatchDraw();

	// 设置蛇的颜色,绘制蛇
	setfillcolor(SNAKE_COLOR);
	for (int i = 0; i < snake.size; i++)
	{
		solidcircle(snake.coor[i].x, snake.coor[i].y, SNAKE_BODY);
	}

	// 绘制食物
	setfillcolor(FOOD_COLOR);
	if (food.flag)
	{
		solidcircle(food.coor.x, food.coor.y, FOOD_SIZE);
	}

	EndBatchDraw();
}


// 通过按键改变蛇的方向
void keyControl(void)
{
	// 判断有没有按键,有按键返回真
	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() == ' ')
				{
					break;
				}
			}
			break;
		default:
			break;
		}

	}
}

// 蛇的移动
void snake_move(void)
{

	for (int i = snake.size - 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 right:
		snake.coor[0].x += 10;
		break;
	case left:
		snake.coor[0].x -= 10;
		break;
	case up:
		snake.coor[0].y -= 10;
		break;
	case down:
		snake.coor[0].y += 10;
		break;
	}
}

// 检测蛇是否死亡
void Snake_life(void)
{
	if (snake.coor[0].x > WIN_WIDTH || snake.coor[0].y<0 || snake.coor[0].y>WIN_HIGH || snake.coor[0].y < 0)
	{
		outtextxy(WIN_WIDTH / 2, WIN_HIGH / 2, "撞墙了,游戏结束!");
		getchar();
	}

	for (int i = 1; i < snake.size; i++)
	{
		if (snake.coor[0].x < snake.coor[i].x + 2 * SNAKE_BODY &&
			snake.coor[0].x > snake.coor[i].x - 2 * SNAKE_BODY &&
			snake.coor[0].y < snake.coor[i].y + 2 * SNAKE_BODY &&
			snake.coor[0].y > snake.coor[i].y - 2 * SNAKE_BODY)
		{
			outtextxy(WIN_WIDTH / 2, WIN_HIGH / 2, "咬到了自己,游戏结束!");
			getchar();
		}
	}
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:40:56  更:2022-05-10 11:42:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 20:40:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码