VS编写c++贪吃蛇(控制台版)

我的第一个c++贪吃蛇游戏(控制台版)
首先说明这是我看了别人的文章,编译成功后,写下自己的理解,仅供参考。
原文章为:https://blog.csdn.net/everlasting_20141622/article/details/52252098

贪吃蛇游戏需要有地图食物积分
1.地图:可以分为四方的墙壁和中间的空地。
2.蛇:控制的主体,分为头部、身体、尾部和前进的方向。
3.食物:随机出现,判断是否和蛇有接触(即是否被吃)。
4.积分:每当食物被吃,积分应该增加并显示。

首先贴出用到的函数。
gotoxy函数,获取括号中x,y的坐标。

void gotoxy(int y, int x) {
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

color函数,选择颜色。

void color(int a) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
	/*
	字
	1 	深蓝色
	2 	深绿色
	3 	深青色
	4 	深红色
	5 	深粉色
	6	深黄色
	7 	深白色
	8 	灰色
	9 	浅蓝色
	10 	浅绿色
	11 	浅青色
	12	浅红色
	13	浅粉色
	14	浅黄色
	15	浅白色


	背景
	1~15		黑色
	16~31		深蓝色
	32~47		深绿色
	48~63		深青色
	64~79		深红色
	80~95		深粉色
	96~111		深黄色
	112~127 	深白色
	128~143 	灰色
	144~159 	浅蓝色
	160~175 	浅绿色
	176~191 	浅青色
	192~207 	浅红色
	208~223 	浅粉色
	224~239 	浅黄色
	240~255 	浅白色
	*/
}

那么一步步来制作
1.画地图:
将画地图的过程封装成map_view方法

void map_view()
{
	for (int i = 0; i <= 21; i++)		//打印地图顶部的边框□,表示边界,不能触碰
	{
		color(11);
		cout << "□";
	}
	cout << endl;					//回车到下一行进行打印
	for (int i = 1; i <=20; i++)		//从第二行开始打印,到20行为止
	{
		color(11);				//格子的颜色,color函数中,下面展示
		cout << "□";				//打印每行的左边第一个格子
		for (int j = 1; j <=20; j++)	//循环打印每行除第一个和末尾的格子,打印为■,表示空地可以穿过
		{
			color(10);			//换颜色加以和边框区分
			cout << "■";
		}
		color(11);				//再换回边框的颜色
		cout << "□"<<endl;		//打印每行最后一个格子,打印完后换行,知道打印完全部19行
	}
	for (int i = 0; i <= 21; i++)		//打印最后一行
	{
		color(11);
		cout << "□";
	}
}

上面的代码使地图打印完毕,接下来进行蛇的编写。
编写一个蛇的结构snake

struct snake
{
	int x, y;
};

x,y代表蛇的每一个部分的坐标,通过坐标的改变进行蛇的移动和增加
蛇包括蛇身,头部,尾部。食物位置也需坐标表示,所以也用蛇的结构体

snake s[110], food, tail;		//s是蛇的身体的坐标 food是食物坐标  tail是尾部坐标,你要在移动后将它覆盖
int len = 3, face = 4;		//len是蛇的初始长度  face是朝向
int speed = 0, Min = 0;		//speed是蛇的移动速度(游戏的刷新速度)  Min是移动速度上限
int score = 0;				//游戏得分
bool eat=true;			//判断食物是否被吃的状态

初始化蛇的函数 init_snake

void init_sanke()
{
	s[1].x = 10;
	s[1].y = 11;
	s[2].x = 10;
	s[2].y = 10;
	s[3].x = 10;
	s[3].y = 9;
	tail.x = 10;
	tail.y = 8;
}

蛇构造好了,接下来是食物和积分的显示,需要显示在主界面上。

while (1) {
	Sleep(speed);
	if (eat == true) {							//吃过食物
		srand(unsigned(time(NULL)));			//当srand()的参数值固定的时候,rand()获得的数也是固定的,所以一般srand的参数用time(NULL)
		food.x = rand() % 20 + 1;		//随机生成食物的x,y坐标
		food.y = rand() % 20 + 1;
		eat = false;								//eat的状态变为false
		for (int i = 1; i <= len; i++) {
			if (s[i].x == food.x && s[i].y == food.y) {			//当吃到食物
				eat = true;
				break;
			}
		}
		if (eat == true) {
			continue;
		}
	}

		gotoxy(food.x, food.y * 2);		//食物坐标
		color(12);
		cout << "●";			//打印食物
		color(14);
		gotoxy(9, 24 * 2);		//显示得分坐标
		cout << "目前得分:" << score << endl;
		color(14);
		gotoxy(10, 24 * 2);		//显示速度坐标
		cout << "当前速度:" << speed << "(越小越快)" << endl;

注意上面的代码里while循环并没有结束,因为还有生成蛇和移动蛇等代码
1.判断蛇是否和自身相撞,不相撞就打印蛇身

for (int i = 1; i <= len; i++) {
	if (i != 1 && s[1].x == s[i].x && s[1].y == s[i].y) {		//当头与身体相撞
		system("cls");		//清除屏幕
		putchar(7);		//结束后,终端回响
		system("cls");
		cout << "您最后的得分为:" << score << endl;
		system("pause");
		return 0;
	}
	gotoxy(s[i].x, s[i].y * 2);
	color(14);
	cout << "★";		//★表示蛇身
}

2.刷新窗体

gotoxy(tail.x, tail.y * 2);
	color(10);
	cout << "■";

	gotoxy(0, 0);
	color(11);
	cout << "□";			//(0,0)处会刷新一个■,需要覆盖掉

3.键盘事件

if (kbhit()) {						//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
	char c;
	c = getch();					//获取到键盘输入的值
	if (c == 'w' && face != 2) {		//按下w且朝向不为下
		face = 1;			
	}
	if (c == 's' && face != 1) {		//按下s且朝向不为上
		face = 2;
	}
	if (c == 'a' && face != 4) {		//按下a且朝向不为左
		face = 3;
	}
	if (c == 'd' && face != 3) {		//按下a且朝向不为右
		face = 4;
	}
}

4.生成蛇

snake x;					//生成一条蛇
if (face == 1) {					//蛇朝上
	x.x = s[1].x - 1;			//头部往上移动一行,y值不变,x-1为向上
	x.y = s[1].y;
}
if (face == 2) {					//蛇朝下
	x.x = s[1].x + 1;			//头部往下移动一行,y值不变,x+1
	x.y = s[1].y;
}
if (face == 3) {					//蛇朝左
	x.x = s[1].x;				//头部往左移动一行,x值不变,y-1
	x.y = s[1].y - 1;
}
if (face == 4) {					//蛇朝右
	x.x = s[1].x;				//头部往右移动一行,x值不变,y+1
	x.y = s[1].y + 1;
}

5.判断是否撞墙和是否接触食物事件

if (s[1].x == food.x && s[1].y == food.y) {				//蛇头部触碰到食物
	score++;											//分数+1
	eat = true;											//eat为true
	len++;
	speed -= 5;											//速度减少5,刷新速度加快
			if (speed < Min)speed = Min;					//锁定速度,当为最小速度时不再减小
			continue;
}

if (s[1].x > 20) {										//当触碰到底部格子时
	system("cls");
	putchar(7);
	break;
}
if (s[1].x < 1) {										//当触碰到顶部格子时
	system("cls");
	putchar(7);
	break;
}
if (s[1].y > 20) {										//当触碰到右边格子时
	system("cls");
	putchar(7);
	break;
}
if (s[1].y < 1) {										//当触碰到左边格子时
	system("cls");
	putchar(7);
	break;
}

6.蛇身向前推进

for (int i = 1; i <= len; i++) {					//格子逐个替换,向前推进
	swap(x.x, s[i].x);							//swap(x,y),交换x,y
	swap(x.y, s[i].y);
}
tail.x = x.x;
tail.y = x.y;

上面的6个单独的代码需要放入表示主界面的while循环中,注意结尾再加一个“ } ”结束循环。
循环结束后可以将写入一个返回类型为int的方法中调用,也可以直接写入main中。

main函数体

int main()
{
	main_view();
	system("cls");
	init_sanke();
	map_view();
	op();					//op为封装了while循环的方法
	system("cls");
	cout << "您最后的得分为:" << score << endl;
	system("pause");
	return 0;
}

还得加入头文件和命名空间

#include "stdlib.h"
#include <iostream>
#include<windows.h>
#include<conio.h>
#include<time.h>
using namespace std;
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值