小游戏:贪吃蛇

🎁个人主页:我们的五年

🔍系列专栏:贪吃蛇

🌷追光的人,终会万丈光芒

 

 

目录

🏝1.头文件:

 🏝2.实现文件:

🏝3.测试文件 :


 

 前言:这个在学习C语言的对知识点进行巩固的一个小游戏,后面也会持续带来一下小游戏。喜欢的帖子们可以点点关注。

相关系列文章:贪吃蛇
 

🏝1.头文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<locale.h>
#include<windows.h>
#include<time.h>

#define POS_X 24
#define POS_Y 5
#define WALL L'□'
#define BODY L'●'
#define FOOD L'●'

//类型声明

//蛇的方向
enum DIECTION {
	UP = 1,
	DOWN,
	LEFT,
	RIGHT
};

//贪吃蛇的状态
// 正常,撞墙,撞到自己,正常退出。

enum GAME_STATUS
{
	OK,            //正常
	KILL_BY_WALL,  //撞墙
	KILL_BY_SLEF,  //撞到自己
	END_NORMAL     //正常退出
};
//蛇身节点
typedef struct SnakeNode {

	short x;
	short y;
	struct SncakeNode* next;
}SnakeNode,* pSnakeNode;

//贪吃蛇
typedef struct Snake {

	pSnakeNode _pSnake;  //指向蛇头的指针
	pSnakeNode _pFood;   //指向食物的指针
	enum DIRECTION _dir; //蛇的方向
	enum GAME_STATUS _status; //游戏状态
	int _food_weight;    //食物分数
	int _score;          //总成绩
	int _sleep_time;
}Snake,* pSnake;

//函数声明

//函数初始化
void GameStart(pSnake snake);

//欢迎界面打印
void WelcomeToGame();

//初始化蛇
void InitSnake(pSnake ps);

//创建食物
void CreateFood(pSnake ps);

//游戏运行
void GameRun(pSnake ps);

int NextIsFood(pSnakeNode pn, pSnake ps);

void SnakeMove(pSnake ps);

void EatFood(pSnakeNode pn, pSnake ps);

void NotFood(pSnakeNode pn, pSnake ps);

void KillByWall(pSnake ps);

void KillBySelf(pSnake ps);

void Game_End(pSnake ps);

 🏝2.实现文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"

void SetPos(short x, short y)
{
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(houtput, pos);
}
void WelcomeToGame()
{
	SetPos(35, 13);
	wprintf(L"欢迎来到贪吃蛇小游戏\n");
	SetPos(37, 20);
	system("pause");
	system("cls");

	SetPos(35, 8);wprintf(L"按↑向上移动");
	SetPos(35, 9);wprintf(L"按↓向下移动");
	SetPos(35, 10);wprintf(L"按←向左移动");
	SetPos(35, 11);wprintf(L"按→向右移动");
	SetPos(35, 12);wprintf(L"按F3减速");
	SetPos(35, 13);wprintf(L"按F4加速");
	SetPos(35, 14); wprintf(L"加速可以得到更高的分数");
	SetPos(35, 18);
	system("pause");
	system("cls");

}

CreateMap()
{
	//上
	for (int i = 0; i < 29; i++)
		wprintf(L"%lc", L'□');
	//下
	SetPos(0, 26);
	for (int i = 0; i < 29; i++)
		wprintf(L"%lc", L'□');
	//左
	for (int i = 1; i <=25; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc\n", L'□');
	}
	//右
	for (int i = 1; i <= 25; i++)
	{
		SetPos(56, i);
		wprintf(L"%lc\n", L'□');
	}
}

void InitSnake(pSnake ps)
{
	int i = 0;
	pSnakeNode cur = NULL;
	for (; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake::malloc()");
			return;
		}
		cur->next = NULL;
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;

		//头插法
		if (ps->_pSnake==NULL)
		{
			ps->_pSnake = cur;
		}
		else
		{
			cur->next = ps->_pSnake;
			ps->_pSnake = cur;
		}
	}

	cur = ps->_pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	ps->_dir = RIGHT;	//默认向右
	ps->_score = 0;
	ps->_status = OK;
	ps->_food_weight = 10;
	ps->_sleep_time = 200;
	//设置贪吃蛇属性
}
void CreateFood(pSnake ps)
{
	int x = 0;
	int y = 0;

	//生成食物的坐标是2的倍数
	//且在方框里面
again:
	do
	{
		x = rand() % 53 + 2;
		y = rand() % 25 + 1;
	} while (x % 2 != 0);

	//x,y的坐标不能和蛇身冲突
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		if (x==cur->x && y==cur->y)
		{
			goto again;
		}
		cur = cur->next;
	}
	//创建食物的节点
	pSnakeNode pFood=(pSnakeNode)malloc(sizeof(SnakeNode));
	if (pFood == NULL)
	{
		perror("CreateFood()::malloc");
		return;
	}
	pFood->x = x;
	pFood->y = y;
	pFood->next = NULL;

	SetPos(x, y);
	wprintf(L"%lc",FOOD );
	ps->_pFood = pFood;
}

void GameStart(pSnake ps)
{
	//0.设置窗口大小,光标影藏
	system("mode con cols=100 lines=30");//设置窗口大小为100列,30行
	system("title 贪吃蛇");  //设置窗口名字为:贪吃蛇
	//影藏光标
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor;
	GetConsoleCursorInfo(houtput, &cursor);
	cursor.bVisible = false;
	SetConsoleCursorInfo(houtput, &cursor);

	//1.打印欢迎界面
	//功能介绍
	WelcomeToGame();
	
	//2.绘制地图
	CreateMap();

	//3.创建蛇
	InitSnake(ps);

	//4.创建食物
	CreateFood(ps);

	SetPos(64, 13);
	wprintf(L"0.用↑←→↓控制蛇的移动");
	SetPos(64, 14);
	wprintf(L"1.不能穿墙,不能咬到自己");
	SetPos(64, 15);
	wprintf(L"2.F3减速,F4加速");
	SetPos(64, 16);
	wprintf(L"3.exc退出游戏");
	SetPos(64, 17);
	wprintf(L"4.按空格暂停游戏");

}
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
void Pause()
{
	while (1)
	{
		Sleep(100);
		if(KEY_PRESS(VK_SPACE))
			break;
	}
}

void EatFood(pSnakeNode pn, pSnake ps)
{
	//头插
	ps->_pFood->next = ps->_pSnake;
	ps->_pSnake = ps->_pFood;
	//释放下一个节点;
	free(pn);
	pn = NULL;
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc\n", BODY);
		cur = cur->next;
	}
	ps->_score += ps->_food_weight;
	CreateFood(ps);
}


void NotFood(pSnakeNode pn, pSnake ps)
{
	pn->next = ps->_pSnake;
	ps->_pSnake = pn;
	pSnakeNode cur = ps->_pSnake;
	pSnakeNode prev = ps->_pSnake;
	while (cur->next)
	{		
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		prev = cur;
		cur = cur->next;
	}
	prev->next = NULL;
	SetPos(cur->x, cur->y);
	wprintf(L"  ");
	free(cur);
	cur = NULL;
}

int NextIsFood(pSnakeNode pn,pSnake ps)
{
	return (pn->x == ps->_pFood->x && pn->y == ps->_pFood->y);
}

void KillByWall(pSnake ps)
{
	if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56
		|| ps->_pSnake->y == 0 || ps->_pSnake->y == 26)
	{
		ps->_status = KILL_BY_WALL;
	}
}

void KillBySelf(pSnake ps)
{
	pSnakeNode cur = ps->_pSnake->next;
	while (cur)
	{
		
		if (ps->_pSnake->x == cur->x && ps->_pSnake->y == cur->y)
		{
			ps->_status = KILL_BY_SLEF;
			break;
		}
		cur=cur->next;
	}
}
void SnakeMove(pSnake ps)
{
	pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pNextNode == NULL)
	{
		perror("SnakeMove()::malloc");
		return;
	}
	switch (ps->_dir)
	{
	case UP:
		pNextNode->x = ps->_pSnake->x;
		pNextNode->y = ps->_pSnake->y - 1;
		break;
	case DOWN:
		pNextNode->x = ps->_pSnake->x;
		pNextNode->y = ps->_pSnake->y + 1;
		break;
	case LEFT:
		pNextNode->x = ps->_pSnake->x-2;
		pNextNode->y = ps->_pSnake->y;
		break;
	case RIGHT:
		pNextNode->x = ps->_pSnake->x+2;
		pNextNode->y = ps->_pSnake->y;
		break;
	}
	if (NextIsFood(pNextNode,ps))
	{
		EatFood(pNextNode,ps);
	}
	else
	{
		NotFood(pNextNode,ps);
	}

	//撞到自己
	KillByWall(ps);

	//撞墙
	KillBySelf(ps);
}

void Game_End(pSnake ps)
{
	SetPos(24, 12);
	switch (ps->_status)
	{
	case KILL_BY_SLEF:
		printf("你撞到了自己,游戏结束\n");
		break;
	case KILL_BY_WALL:
		printf("你撞到墙了,游戏结束\n");
		break;
	case END_NORMAL:
		printf("你主动结束了游戏\n");
		break;
	}
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		pSnakeNode del = cur;
		cur = cur->next;
		free(del);
	}
}
void GameRun(pSnake ps)
{
	//打印帮助信息
	do
	{
		//打印总分数和食物的分值
		SetPos(64, 8);
		wprintf(L"总分数:%3d\n",ps->_score);
		SetPos(64, 9);
		wprintf(L"当前食物分数:%2d",ps->_food_weight);
		if (KEY_PRESS(VK_UP)&&ps->_dir!=DOWN)
		{
			ps->_dir = UP;
		}
		else if (KEY_PRESS(VK_DOWN) && ps->_dir != UP)
		{
			ps->_dir = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->_dir != RIGHT)
		{
			ps->_dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->_dir != LEFT)
		{
			ps->_dir = RIGHT;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			//暂停
			Pause();
		}
		else if (KEY_PRESS(VK_F3))
		{
			//减速
			if (ps->_sleep_time < 320)
			{
				ps->_sleep_time += 30;
				ps->_food_weight -= 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			//加速
			if (ps->_sleep_time > 80)
			{
				ps->_sleep_time -= 30;
				ps->_food_weight += 2;
			}
		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			//退出
			ps->_status = END_NORMAL;
		}
	//贪吃蛇走一步
	SnakeMove(ps);
	Sleep(ps->_sleep_time);
	} while (ps->_status == OK);
}

🏝3.测试文件 :

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"

//完成的是对游戏的测试
void test()
{
	int ch;
	do
	{
		//创建贪吃蛇
		Snake snake = { 0 };

		//初始化游戏
		GameStart(&snake);

		//运行游戏
		GameRun(&snake);

		//结束游戏—善后工作
		Game_End(&snake);
		SetPos(20, 13);
		printf("游戏结束,再来一局吗?Y/N");
		SetPos(20, 14);
		ch=getchar();
		while(getchar()!='\n');
	} while (ch == 'y' || ch == 'Y');
	SetPos(0, 26);
}
int main()
{
	//设置适配本地环境
	setlocale(LC_ALL, "");
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

 

相关推荐

  1. 贪吃游戏

    2024-04-23 08:24:02       35 阅读
  2. 贪吃游戏

    2024-04-23 08:24:02       27 阅读
  3. 贪吃web游戏

    2024-04-23 08:24:02       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-23 08:24:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-23 08:24:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-23 08:24:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-23 08:24:02       20 阅读

热门阅读

  1. internet.getUserEncryptKey提示错误

    2024-04-23 08:24:02       13 阅读
  2. 从零开始:UniApp 项目搭建指南

    2024-04-23 08:24:02       16 阅读
  3. uniapp picker组件实现二级联动

    2024-04-23 08:24:02       16 阅读
  4. Linux搭建NFS服务器

    2024-04-23 08:24:02       14 阅读
  5. 特殊类的设计、C++四种类型转换

    2024-04-23 08:24:02       16 阅读
  6. 2024系统架构师---论软件系统架构评估

    2024-04-23 08:24:02       15 阅读
  7. 狠不狠?做个标签累不累?

    2024-04-23 08:24:02       14 阅读
  8. wow-socket文件说明

    2024-04-23 08:24:02       17 阅读
  9. 3D抓取算法中的PointNet++网络介绍

    2024-04-23 08:24:02       13 阅读