当前位置: 首页 > article >正文

【C++项目实战】贪吃蛇小游戏

一、引言

        贪吃蛇,这款经典的电子游戏,自1976年诞生以来,一直受到全球玩家的喜爱。它的规则简单,玩法直观,但同时也充满了挑战性。在这篇文章中,我们将一起探索如何开发一个贪吃蛇游戏,无论是作为编程新手的练手项目,还是作为游戏开发爱好者的娱乐之作,都是一个不错的选择。

二、贪吃蛇游戏基本规则

游戏规则

  1. 游戏目标:控制一条蛇在屏幕上移动,吃掉出现的食物,每吃一个食物,蛇的长度就会增加一节。
  2. 控制方式:通过键盘的上下左右键控制蛇的移动方向。
  3. 游戏结束条件:蛇撞到屏幕边界或者自己的身体时,游戏结束。

基本思路

  • 使用数组或链表来表示蛇的身体。
  • 通过改变蛇头的位置来控制蛇的移动。
  • 使用随机数来生成食物的位置。
  • 检测蛇头与食物、墙壁和自身身体的碰撞。

三、代码

首先绘制一个范围,确定面积多大

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

//设置地图边界
#define  W  120
#define  H  30



//测试Ui界面多大
void text_ui()
{
	for (int i = 0;i < H; i++)
	{
		for (int j = 0;j < W; j++)
		{
			printf("=");
		}
		printf("\n");
	}
}


int main()
{
    text_ui();
    return 0;


}

得到结果如下:

 整个游戏复制以下代码运行即可:

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

//设置地图边界
#define  W  120
#define  H  30

//设置贪吃蛇结构体
typedef struct _body
{
	int x;    //坐标x
	int y;    //坐标y
}BODY;

typedef struct snake
{
	BODY list[W*H];     //贪吃蛇最大沾满整个地图
	int size;           //实际身体个数。蛇头 @,蛇身 *
	BODY food;          //食物 #
	COORD coord;        //定位光标
	int dx;             //移动方向
	int dy;             //移动方向
	BODY tail;          //记录蛇尾(用于清除蛇尾痕迹)
	int score;          //记录分数
}SNAKE;

//食物函数
void init_food(BODY* food)
{
	//设置随机数种子
	srand(time(NULL));
	//设置食物坐标
	food->x = rand() % (W - 1) +1;
	food->y = rand() % (H - 1) +1;
}

//初始化蛇的函数
void init_snake(SNAKE *snake)
{
	//设置蛇头与蛇尾的位置
	snake->list[0].x = W / 2;
	snake->list[0].y = H / 2;
	snake->list[1].x = W / 2  - 1;
	snake->list[1].y = H / 2  - 1;
	snake->size = 2;

	//设置移动方向
	snake->dx = 1;
	snake->dy = 0;

	snake->score = 0;

	//设置食物位置
	init_food(&(snake->food));
}
//展示UI函数
void show_ui(SNAKE* snake)
{
	//显示蛇
	for (int i = 0;i < snake->size;i++)
	{
		snake->coord.X = snake->list[i].x;
		snake->coord.Y = snake->list[i].y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
		if (i == 0) //显示蛇头
		{
			printf("@");
		}
		else
		{
			printf("*");
		}
	}
	//显示食物
	snake->coord.X = snake->food.x;
	snake->coord.Y = snake->food.y;
	//定位光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("#");

	//清除蛇尾痕迹
	snake->coord.X = snake->tail.x;
	snake->coord.Y = snake->tail.y;
	//定位光标位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf(" ");

}
void show_wall()
{
	for (int i = 0;i <= H; i++)
	{
		for (int j = 0;j <= W; j++)
		{
			if (i == 0 || j == 0 || i == H || j == W)
			{
				printf("+");
			}
			else
			{
				printf(" ");
			}
		}
		printf("\n");
	}
}
/*
测试Ui界面多大
void text_ui()
{
	for (int i = 0;i < H; i++)
	{
		for (int j = 0;j < W; j++)
		{
			printf("=");
		}
		printf("\n");
	}
}
*/

void hide_cur()//隐藏光标
{
	CONSOLE_CURSOR_INFO cci;
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}

void move_snake(SNAKE* snake)   //移动函数
{
	snake->tail = snake->list[snake->size - 1];
	for (int i = snake->size - 1; i > 0; i--)
	{
		snake->list[i] = snake->list[i - 1];
	}
	snake -> list[0].x += snake->dx;
	snake -> list[0].y += snake->dy;
}


void contorl_snake(SNAKE *snake)
{
	char key=0;
	while (_kbhit()) //判断是否按下按键,按下不等于0
	{
		key = _getch();
	}

	switch (key)
	{
	case'w':
		snake -> dy = -1;
		snake -> dx = 0;
		break;
	case's':
		snake->dy = 1;
		snake->dx = 0;
		break;
	case'a':
		snake->dy = 0;
		snake->dx = -1;
		break;
	case'd':
		snake->dy = 0;
		snake->dx = 1;
		break;

	}

}

void snake_eat_food(SNAKE* snake)   //吃食物函数
{
	if (snake->list[0].x== snake->food.x && snake->list[0].y == snake->food.y)
	{
		snake->size++;
		init_food(&(snake->food));
		snake->score += 10;
	}
}

void game_over(SNAKE *snake)
{
	snake->coord.X = 110;
	snake->coord.Y = 65;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("游戏结束,总分数:%d\n", snake->score);
}

void start_game(SNAKE *snake)
{
	while (snake->list[0].x>0 && snake->list[0].x<W &&
		snake->list[0].y>0 && snake->list[0].y < H)
	{
		show_ui(snake);    //显示蛇和食物
		
		contorl_snake(snake);  //控制蛇

		snake_eat_food(snake);  //判断是否吃到食物

		move_snake(snake);   //移动蛇

		Sleep(100);     //延时100毫秒
	}
	game_over(snake);
}

int main(int argc, char* argv[])
{
	hide_cur();        //隐藏光标
	//text_ui();
	SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));
	init_snake(snake); //初始化
	show_wall();       //显示墙
	
	start_game(snake);

	free(snake);
	while (1);
	return 0;
}

代码解析

  1. 头文件包含

    • stdio.h:标准输入输出头文件。
    • string.h:字符串操作头文件。
    • stdlib.h:标准库头文件,包含内存分配等函数。
    • time.h:时间操作头文件,用于生成随机数。
    • windows.h:Windows API 头文件,用于控制台操作。
    • conio.h:控制台输入输出头文件,用于非缓冲输入。
  2. 宏定义

    • W 和 H 分别定义了游戏地图的宽度和高度。
  3. 结构体定义

    • BODY:用于存储蛇的身体部分的坐标。
    • SNAKE:包含蛇的身体、食物、方向、分数等信息。
  4. 函数定义

    • init_food:初始化食物的位置。
    • init_snake:初始化蛇的位置和方向。
    • show_ui:显示蛇和食物。
    • show_wall:显示游戏的边界。
    • hide_cur:隐藏控制台光标。
    • move_snake:根据蛇的方向移动蛇的身体。
    • contorl_snake:通过键盘输入控制蛇的移动方向。
    • snake_eat_food:判断蛇是否吃到食物,并更新蛇的长度和分数。
    • game_over:游戏结束时显示分数。
    • start_game:游戏的主循环,控制游戏的流程。
  5. 主函数

    • main:程序的入口点,初始化游戏,隐藏光标,显示边界,并开始游戏循环。

http://www.kler.cn/a/464834.html

相关文章:

  • Pytorch使用手册-空间变换网络指南(专题十五)
  • Excel 面试 02 逻辑函数 AND
  • JUC学习
  • mysql报错2059
  • IT运维的365天--024 闲置路由器关闭了dhcp,如何知道它的IP是啥
  • 【Infineon AURIX】AURIX缓存(CACHE)变量访问指南
  • 大数据组件(二)快速入门数据集成平台SeaTunnel
  • 建造者模式 Builder Pattern
  • docker下载redis,zookeeper,kafka超时time out
  • 软件工程大复习(五) 需求工程与需求分析
  • Linux系统安装es详细教程
  • 【IEEE冠名会议】2025年IEEE第二届深度学习与计算机视觉国际会议(DLCV 2025)
  • Go recover的执行时机
  • 剪映--关键帧教程:制作视频文字说明,文字动态划线,透明文字,虚拟触控,画面旋转缩小退出
  • TCP IP 网络协议基础入门 1
  • 加速开发体验:为 Android Studio 设置国内镜像源
  • VSCode函数调用关系图插件开发(d3-graphviz)
  • Git核心概念总结
  • 2022浙江大学信号与系统笔记
  • 小程序租赁系统的优势与应用探索