C++第12天

1.模块设计

在这里插入图片描述

在这里插入图片描述

2.总述

在这里插入图片描述

3.定义蛇对象,食物对象

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

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

//身体对象
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; //分数

4.初始化蛇,食物

在这里插入图片描述

//蛇对象初始化
void initSnake(void)
{
	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;

	return;
}
//食物对象初始化
void initFood(void)
{
	food.X = rand() % WIDE; //0-59
	food.Y = rand() % HIGH; //0-19

	return;
}

snake.h

#ifndef __SNAKE_H__
#define __SNAKE_H__

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

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

//身体对象
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; //分数

void initSnake(void);
void initFood(void);


#endif

main.c

#include "snake.h"

int main(void)
{
	srand(time(NULL)); //播种随机数种子

	initSnake(); //初始化蛇
	initFood(); //初始化食物

	printf("snake 头:x=%d,y=%d\n", snake.body[0].X, snake.body[0].Y);
	printf("snake 身:x=%d,y=%d\n", snake.body[1].X, snake.body[1].Y);

	printf("food x=%d,y=%d\n", food.X, food.Y);

	return 0;
}

//蛇对象初始化
void initSnake(void)
{
	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;

	return;
}

//食物对象初始化
void initFood(void)
{
	food.X = rand() % WIDE; //0-59
	food.Y = rand() % HIGH; //0-19

	return;
}

5.修改控制台光标位置

在这里插入图片描述

在这里插入图片描述

#include <conio.h>
#include <Windows.h>

6.画出蛇和食物

在这里插入图片描述

void initUI(void)
{
	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('#');
}

7.蛇的移动控制

在这里插入图片描述

在这里插入图片描述

int kx = 0; //用户按下 aswd 任意一个按键所得到的坐标值
int ky = 0;

8.开始游戏

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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();

		//接收用户按键输入 asdw
		if (_kbhit()) //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 (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)
			{
				return; //游戏结束
			}
		}

		//蛇头撞食物
		if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
		{
			initFood(); //食物消失
			snake.size++; //身体增长
			score += 10; //加分
			sleepSecond -= 10; //加速
		}

		//存储蛇尾坐标
		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(sleepSecond);
		//清屏
		//system("cls");
	}
	return;
}

9.画墙

在这里插入图片描述

void initWall(void)
{
	for (size_t i = 0; i <= HIGH; i++)
	{
		for (size_t j = 0; j <= WIDE; j++)
		{
			if (j == WIDE)
			{
				printf("|");
			}
			else if (i == HIGH)
			{
				printf("_");
			}
			else
			{
				printf(" ");
			}
		}
		printf("\n");
	}
}

10.去除蛇尾

在这里插入图片描述

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

11.去除光标

在这里插入图片描述

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

在这里插入图片描述

12.显示分数,加速

在这里插入图片描述

void showScore(void)
{
	COORD coord;
	//将光标默认位置移动至不干扰游戏的任意位置
	coord.X = 0;
	coord.Y = HIGH + 2;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

	printf("Game over!!!\n");
	printf("成绩为:%d\n\n\n", score);
}

snake.h

#ifndef __SNAKE_H__
#define __SNAKE_H__

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>

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

//身体对象
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; //分数
int sleepSecond = 400;

int kx = 0; //用户按下 aswd 任意一个按键所得到的坐标值
int ky = 0;

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

void initSnake(void);
void initFood(void);
void initUI(void);
void initWall(void);
void playGame(void);
void showScore(void);

#endif

main.c

#include "snake.h"

int main(void)
{
	//去除光标
	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(); //打印分数

	return 0;
}

//蛇对象初始化
void initSnake(void)
{
	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;

	return;
}

//食物对象初始化
void initFood(void)
{
	food.X = rand() % WIDE; //0-59
	food.Y = rand() % HIGH; //0-19

	return;
}

void initWall(void)
{
	for (size_t i = 0; i <= HIGH; i++)
	{
		for (size_t j = 0; j <= WIDE; j++)
		{
			if (j == WIDE)
			{
				printf("|");
			}
			else if (i == HIGH)
			{
				printf("_");
			}
			else
			{
				printf(" ");
			}
		}
		printf("\n");
	}
}

void initUI(void)
{
	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('#');
}

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();

		//接收用户按键输入 asdw
		if (_kbhit()) //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 (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)
			{
				return; //游戏结束
			}
		}

		//蛇头撞食物
		if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
		{
			initFood(); //食物消失
			snake.size++; //身体增长
			score += 10; //加分
			sleepSecond -= 10; //加速
		}

		//存储蛇尾坐标
		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(sleepSecond);
		//清屏
		//system("cls");
	}
	return;
}

void showScore(void)
{
	COORD coord;
	//将光标默认位置移动至不干扰游戏的任意位置
	coord.X = 0;
	coord.Y = HIGH + 2;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

	printf("Game over!!!\n");
	printf("成绩为:%d\n\n\n", score);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值