c语言版简易贪吃蛇

本文详细介绍了用C++编写的贪吃蛇游戏,涉及结构体、数组、游戏逻辑(碰撞检测、食物生成、移动机制)、控制台输入输出、光标移动及游戏循环等关键技术和函数设计。
摘要由CSDN通过智能技术生成

目录

项目介绍

1.项目简介

2.主要问题

系统设计

1.框架设计

2函数设计

  3.函数运行


  • 项目介绍

1.项目简介

我们的项目依据诺基亚手机当年附带的小游戏贪吃蛇进行书写。使用竖线与下划线作为边界,使用简单的“@”字符与“*”字符与“#”字符分别构成蛇头蛇身体与食物.蛇,同时蛇具有不同的速度。

2.主要问题

   1.如何保存蛇的位置与食物的位置?

   2.如何更新页面?

   3.如何随机生成食物?

   4如何移动光标,以便更新蛇?

   5.如何移动蛇?形成移动效果?

  • 系统设计

1.框架设计

  1. 定义蛇对象、食物对象,用于保存它们的坐标
  2. 初始化蛇、初始化食物

     3.控制流程:

1)蛇头和墙壁的碰撞

2)蛇头和蛇身体的碰撞

(如果蛇头碰到墙壁或者身体,蛇会死亡)

3)蛇头和食物的碰撞

        1>蛇身增长

        2>食物消失 -- 新食物产生

        3>分数累加

        4> 移动速度增大

4)蛇的移动

        1>自动移动

        2>手动控制移动:ASWD---左下上右

5)显示分数

2函数设计

  1>主函数与各个函数分离,主函数保证代码逻辑,各个辅助函数实现具体功能,通过多次的函数调用来实现所需功能。

2>函数分类:将出了main函数外的函数分为辅助函数,和主要函数

3>函数命名 使用body,snake,wall等具体描述,前缀使用init等

  3.函数运行

     1>开始  在开始界面呈现菜单,使用do while 进入循环,同时选择模式或者退出,由switch case 语句进入

     2>中途  使用wasd与程序进行交互

     3结束游戏  结束游戏后返回,由相应函数呈现分数

  • 关键技术介绍

头文件有

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<math.h>

#include<time.h>

#include<Windows.h>

#include<conio.h>

  1.   使用结构体与数组使用向右向下的x.y坐标的方式确定蛇对象与食物对象的位置
  2.   使用while()循环的嵌套以及相应语句实现对蛇头是否和墙壁的碰撞,蛇头和蛇身体的碰撞,蛇头和食物的碰撞的判断,若蛇与身体或者墙壁碰撞则会break,跳出循环

     3.使用 srand(time(NULL)),使用时间来生成随机数种子,从而随机生成食物的坐标

     4.使用COORD结构体以及

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);

移动光标到coord所储存的位置,并且进行判断,以此来画蛇的头部与身体,以及食物
       5.使用  

CONSOLE_CURSOR_INFO cci;

                     cci.dwSize = sizeof(cci);

                     cci.bVisible = FALSE;

                     SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);

设置光标不可见

6  使用do while循环来实现重复游戏,使得玩家可以先进入菜单页面进行判断,再通过交互输入指令

7.kbhit()非阻塞地响应键盘输入事件,判断键盘是否进行输入,如果输入则返回true,未输入则返回false

8.getch()不回显地接收输入的字符,接收玩家从键盘输入的指令,同时不显示在控制台

9.控制Sleep(),控制程序的休眠时间来呈现贪吃蛇的速度,并且通过相应变量控制贪吃蛇的速度

10.system(“cls”)实现清屏操作

代码实现

头文件,宏,全局变量与结构体定义

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<Windows.h>
#include<conio.h>

#define WIDE 60  //宽
#define HIGH 20  //高

//一个身体的对象
typedef struct BODY
{
	int X;
	int Y;
}BODY;

//定义蛇对象
struct SNAKE
{
	BODY body[WIDE * HIGH];//蛇头body【0】 
	int size;
}snake;

//定义食物对象
struct FOOD
{
	int X;
	int Y;
}food;

int score = 0;

int kx = 0;
int ky = 0; //用户按下键得到的坐标值

int lastX = 0;//蛇尾坐标 
int lastY = 0;
 
int sleeptime = 260;

初始化函数 与分数展示函数

void initsnake()//蛇初始化
{
	snake.size = 2;

	snake.body[0].X = WIDE / 2;//初始化蛇头
	snake.body[0].Y = HIGH / 2;

	snake.body[1].X = WIDE / 2 - 1;
	snake.body[1].Y = HIGH / 2;
}

void initfood()
{
	food.X = rand() % WIDE;
	food.Y = rand() % HIGH;

	return;
}

void initui(void)
{
	//画蛇
	COORD coord;
	for(int i = 0; i < snake.size; i++)
	{
		coord.X = snake.body[i].X;
		coord.Y = snake.body[i].Y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);  //光标移动的位置 
		
		if(i ==0)putchar('@');
		else putchar('*');
	}
	//去除蛇尾
	coord.X = lastX;
	coord.Y = lastY; 
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord); 
	putchar(' '); 

	//画食物 
	coord.X = food.X;
	coord.Y = food.Y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord); 
	putchar('#');
	}
void initwall(void)
{
	for(int i = 0; i <= HIGH; i++)
	{
		for(int j = 0; j <= WIDE;j++)
		{
			if(j == WIDE)
			{
				printf("|");
			}
			else if(i == HIGH)
			{
				printf("_");
			}
			else 
			{
				printf(" ");
			}
		}
		printf("\n");
	}
}
void showScore()
{
	//把光标移动到不妨碍的地方 
	COORD coord;
	coord.X = 0;
	coord.Y = HIGH + 2;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
	
	printf("Game Over!!!\n");
	printf("你的成绩为: %d\n",score);
}
	
	

游戏逻辑函数和主函数

void playgame(void)
{
	char key = 'd';
	//撞墙 
	while(snake.body[0].X >= 0 && snake.body[0].X < WIDE
	&& snake.body[0].Y >= 0 && snake.body[0].Y < HIGH)
	{
		initui(); //更新蛇 
	
		//接收用户按键输入awds
		if(kbhit())
		{
			key = getch();
		 } 
		
		switch(key)
		 {
		 	case'w':kx = 0; ky = -1;break;
		 	case's':kx = 0; ky = +1;break;
		 	case'd':kx = +1; ky = 0;break;
		 	case'a':kx = -1; ky = 0;break;
		 	default:
		 		break;
		 }
		//撞身体 
		for(int i = 1; i < snake.size; i++)
		{
			if(snake.body[0].X == snake.body[i].X
			&& snake.body[0].Y == snake.body[i].Y)
			{
				return;
			}
		}
		//撞食物
		if(snake.body[0].X == food.X && snake.body[0].Y == food.Y) 
		{
			//食物消失
			initfood();
			//身体增长
			snake.size++;
			//加分
			score+= 10;
			//加速 
			if(sleeptime > 100)
			{
				sleeptime -= 20;
			}
		}
		
		lastX = snake.body[snake.size - 1].X;
		lastY = snake.body[snake.size - 1].Y;
		
		//蛇移动,后一节赋给前一节 
		for(int i = snake.size - 1; i > 0; i--)
		{
			snake.body[i].X = snake.body[i-1].X; 
			snake.body[i].Y = snake.body[i-1].Y; 
		}
		
		snake.body[0].X += kx;
		snake.body[0].Y += ky;
		
		Sleep(sleeptime);
		//清屏
		//system("cls"); 
	}
}

int main()
{
	CONSOLE_CURSOR_INFO cci;//设置光标不可见 
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
	
	
	srand(time(NULL));//随机数种子

	initsnake();//初始化蛇 
	initfood();//初始化食物 
	initwall();//画墙 
	initui();//画蛇和食物 
	playgame();//启动游戏 

	showScore();
	system("pause");
	return 0;
}

 整体呈现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<Windows.h>
#include<conio.h>

#define WIDE 60  //宽
#define HIGH 20  //高

//一个身体的对象
typedef struct BODY
{
	int X;
	int Y;
}BODY;

//定义蛇对象
struct SNAKE
{
	BODY body[WIDE * HIGH];//蛇头body【0】 
	int size;
}snake;

//定义食物对象
struct FOOD
{
	int X;
	int Y;
}food;

int score = 0;

int kx = 0;
int ky = 0; //用户按下键得到的坐标值

int lastX = 0;//蛇尾坐标 
int lastY = 0;
 
int sleeptime = 260;
 
void initsnake()//蛇初始化
{
	snake.size = 2;

	snake.body[0].X = WIDE / 2;//初始化蛇头
	snake.body[0].Y = HIGH / 2;

	snake.body[1].X = WIDE / 2 - 1;
	snake.body[1].Y = HIGH / 2;
}

void initfood()
{
	food.X = rand() % WIDE;
	food.Y = rand() % HIGH;

	return;
}

void initui(void)
{
	//画蛇
	COORD coord;
	for(int i = 0; i < snake.size; i++)
	{
		coord.X = snake.body[i].X;
		coord.Y = snake.body[i].Y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);  //光标移动的位置 
		
		if(i ==0)putchar('@');
		else putchar('*');
	}
	//去除蛇尾
	coord.X = lastX;
	coord.Y = lastY; 
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord); 
	putchar(' '); 

	//画食物 
	coord.X = food.X;
	coord.Y = food.Y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord); 
	putchar('#');
	
	
	
}
void playgame(void)
{
	char key = 'd';
	//撞墙 
	while(snake.body[0].X >= 0 && snake.body[0].X < WIDE
	&& snake.body[0].Y >= 0 && snake.body[0].Y < HIGH)
	{
		initui(); //更新蛇 
	
		//接收用户按键输入awds
		if(kbhit())
		{
			key = getch();
		 } 
		
		switch(key)
		 {
		 	case'w':kx = 0; ky = -1;break;
		 	case's':kx = 0; ky = +1;break;
		 	case'd':kx = +1; ky = 0;break;
		 	case'a':kx = -1; ky = 0;break;
		 	default:
		 		break;
		 }
		//撞身体 
		for(int i = 1; i < snake.size; i++)
		{
			if(snake.body[0].X == snake.body[i].X
			&& snake.body[0].Y == snake.body[i].Y)
			{
				return;
			}
		}
		//撞食物
		if(snake.body[0].X == food.X && snake.body[0].Y == food.Y) 
		{
			//食物消失
			initfood();
			//身体增长
			snake.size++;
			//加分
			score+= 10;
			//加速 
			if(sleeptime > 100)
			{
				sleeptime -= 20;
			}
		}
		
		lastX = snake.body[snake.size - 1].X;
		lastY = snake.body[snake.size - 1].Y;
		
		//蛇移动,后一节赋给前一节 
		for(int i = snake.size - 1; i > 0; i--)
		{
			snake.body[i].X = snake.body[i-1].X; 
			snake.body[i].Y = snake.body[i-1].Y; 
		}
		
		snake.body[0].X += kx;
		snake.body[0].Y += ky;
		
		Sleep(sleeptime);
		//清屏
		//system("cls"); 
	}
}
void initwall(void)
{
	for(int i = 0; i <= HIGH; i++)
	{
		for(int j = 0; j <= WIDE;j++)
		{
			if(j == WIDE)
			{
				printf("|");
			}
			else if(i == HIGH)
			{
				printf("_");
			}
			else 
			{
				printf(" ");
			}
		}
		printf("\n");
	}
}
void showScore()
{
	//把光标移动到不妨碍的地方 
	COORD coord;
	coord.X = 0;
	coord.Y = HIGH + 2;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
	
	printf("Game Over!!!\n");
	printf("你的成绩为: %d\n",score);
}
int main()
{
	CONSOLE_CURSOR_INFO cci;//设置光标不可见 
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
	
	
	srand(time(NULL));//随机数种子

	initsnake();//初始化蛇 
	initfood();//初始化食物 
	initwall();//画墙 
	initui();//画蛇和食物 
	playgame();//启动游戏 

	showScore();
	system("pause");
	return 0;
}

大致效果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值