纯C控制台应用的贪吃蛇实现

#ifndef __SNAKE_H__
#define __SNAKE_H__

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<Windows.h>

#define WIDE 60		//宽度
#define HIGH 20		//高度
#define initlen 5	//默认蛇的初始长度

//用户按下方向键所得到的坐标值
int kx = 0;
int ky = 0;
int lastX = 0;
int lastY = 0;
int second = 200;

struct BODY {
	int X;
	int Y;
};

//定义蛇对象
struct SNAKE {
	struct BODY body[WIDE*HIGH]; //蛇的身子
	int size;//蛇的长度
}snake;

//定义食物
struct FOOD {
	int x;
	int y;
}food;

//分数
int score = 0;
//声明函数
void initSnake(void);//初始化蛇
void initFood(void);//初始化食物
void initUI();
void initframe();
void playGame();
#endif
#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"

int main(void) 
{
	//去除光标
	CONSOLE_CURSOR_INFO cci;
	cci.bVisible = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);


	_kbhit();
	srand(time(NULL));//播种随机数种子
	initframe();//	边框
	initSnake();//初始化蛇
	initFood();//初始化食物
	initUI(); //画蛇和食物
	playGame();//启动游戏
	system("pause");
	return EXIT_SUCCESS;
}
//初始化蛇
void initSnake(void) {
	snake.size = initlen;							//初始化蛇的长度

	/*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;*/


	for (size_t i = 0; i < snake.size; i++)
	{
		snake.body[i].X = WIDE / 2 - i;
		snake.body[i].Y = HIGH / 2;
	}
	return;
}
//初始化边框
void initframe() {
	COORD coord = { 0 };//光标移动位置
	for (size_t i = 0; i <= WIDE; i++)
	{
		coord.X = i;
		coord.Y = 20;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);  //表示光标移动的位置
		putchar('_');
	}
	for (size_t i = 0; i <= HIGH; i++)
	{
		coord.X = 60;
		coord.Y = i;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);  //表示光标移动的位置
		putchar('|');
	}
	
	//将光标移动到游戏框外
	coord.X = 0;
	coord.Y = HIGH + 4;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);  
}
//初始化界面控件
void initUI() {
	
	COORD coord = { 0 };//光标移动位置
	//画蛇
	for (size_t 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('#');
	return;
}
//初始化食物
void initFood(void) {
	food.x = rand() % WIDE;
	food.y = rand() % HIGH;
	return;
}
//启动游戏
void playGame() {
	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();//画蛇
		initframe();//画墙
		if (_kbhit())
		{
			key = _getch();
		}
		switch (key)
		{
		case 'W':
		case 'w':
		case 72: kx = 0; ky = -1; break;
		case 'S':
		case 's':
		case 80: kx = 0; ky = +1; break;
		case 'A':
		case 'a':
		case 75: kx = -1; ky = 0; break;
		case 'D':
		case 'd':
		case 77: kx = +1; ky = 0; break;
		default:
			break;
		}
		for (size_t i = 1; i < snake.size; i++)//蛇撞身体:蛇头==任意一截身体
		{
			if (snake.body[0].X == snake.body[i].X && snake.body[0].Y == snake.body[i].Y)
			{
				printf("           游戏结束...          \n");
				printf("         您的分数为:%d\n    ", score);
				return;
			}
		}
		if (snake.body[0].X == food.x && snake.body[0].Y == food.y) //蛇头撞到食物
		{
			initFood();		//食物消失
			snake.size++;	//身体增长
			score += 10;	//加分
			if(second>50)
				second -= 50;			//加速
		}
		//存储蛇尾坐标
		lastX = snake.body[snake.size - 1].X;
		lastY = snake.body[snake.size - 1].Y;
		//蛇的移动,前一节身体给后一节身体赋值
		for (size_t 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(second);
		//清屏
		//system("cls");
	}
	printf("           游戏结束!          \n");
	printf("         您的分数为:%d\n    ", score);
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值