控制台玩贪吃蛇(C++语言)

疫情期在家,开学遥遥无期,为了打发无聊的时间,我写了一个贪吃蛇小游戏来打发时间。当然,这也是受朋友启发 用JS实现贪吃蛇小游戏,我也想用C++写一个。当然,本蒟蒻刚学C++没多久,代码会有些凌乱,不足之处望各位dalao指出来

1.游戏规则

通过上下左右控制蛇的移动,来吃到随机生成的食物,吃到食物后蛇的长度会增加,并且获得一定的分数,蛇头不能碰到墙壁。

2.设计思路

1.画出地图
2.需要构造两个类,一个是蛇,另一个是食物
3.读取上下左右的输入
4.一些人机交互的信息

3.具体实现

预先准备
包含的头文件

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdlib>
#include <ctime>
#include <cstdio>

需要的函数

void gotoxy(int x, int y)
{
	HANDLE hout;
	COORD coord;
	coord.X = x;
	coord.Y = y;
	hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout, coord);
}//将光标移动到x,y,命令行左上角为(0,0),向下为y轴正向,向右为x轴正向


蛇具有头部和身体,可以用不同的字符来表示,需要实现的功能有:移动,变长,吃食物等。 综合考虑这些特点,用链表来实现蛇更方便操作。蛇类如下:


typedef struct Node{
	int x;
	int y;//蛇每个节点的坐标
	struct Node *p;
}Node;//这是蛇的节点
class snake{
	private:
		Node *head;
		char Head;//头部字符
		char Body;//身体字符
	public:
		void set(char c1, char c2){
			Head = c1;
			Body = c2;
		}//设置蛇的样式
		snake(){
			Node *node = new Node;
			node->p = NULL;
			head = node;
			head->x=10;
			head->y=10;
			add();
		}//蛇的初始化,即添加上头部和一个身体节点
		void move();//移动
		void add();//增加一个身体节点
		void print();//显示蛇
		void read();//读取键盘操作(可能放在这里不合适,不过影响不大)
		bool eat(int x, int y);//吃食物
		bool die();//死亡
};

蛇类里各种功能的实现,有难度的是蛇的移动,后来才想到,其实每一个节点都是头节点的复制。所以把前一个节点的坐标复制给后面一个节点就行了。
下面是蛇功能的具体实现:

void snake::move()
{
	Node* temp=new Node;
	Node* temp2=new Node;
	*temp = *head;
	Node* t = head->p;
	if(!kbhit())
	{
		if(head->x==t->x&&head->y<t->y)
			head->y --;
		if(head->x==t->x&&head->y>t->y)
			head->y ++;
 		if(head->y==t->y&&head->x<t->x)
			head->x --;
 		if(head->y==t->y&&head->x>t->x)
			head->x ++;
	}else{
		read();
	}//这个if-else是头节点的变动,也可单独写成一个函数
	 //没输入时就按原方向,有输入就按输入改变
	while(t!=NULL)
	{
		gotoxy(t->x, t->y);
		cout<<" ";//这是清除前面节点的方法,在相应位置输出空格
		*temp2 = *t;
		t->x = temp->x;
		t->y = temp->y;
		t = t->p;
		*temp = *temp2;
	}
}
void snake::add()
{
	Node *t = head;
	while(t->p!=NULL)
		t = t->p;//遍历到最后一个节点,然后在最后加一个节点
	Node *q = new Node;
	q->x = t->x-1;//要把最后节点的坐标赋值(这里不完整,可能看上去有点别扭)
	q->y = head->y;
	q->p = NULL;
	t->p = q;
}
void snake::print()
{
	gotoxy(head->x,head->y);
	cout<<Head;
	Node *t = head->p;
	while(t!=NULL)
	{
		gotoxy(t->x,t->y);
		cout<<Body;
		t = t->p;
	}
}
void snake::read()//读入键盘上下左右方向键的输入
{
	    char ch = getch();
      	 if (ch == -32)
        {
            ch = getch();
            switch (ch)
            {
            case 72:
                head->y--;
                break;
            case 80:
                head->y++;
                break;
            case 75:
                head->x--;
                break;
            case 77:
                head->x++;
                break;
            }
        }
}
bool snake::eat(int x, int y)
{
	if(head->x == x&&head->y == y)
	{
				add();
		return true;
	}
	return false;
}
bool snake::die()
{
	if(head->x<=0||head->x>=50)
		return true;
	if(head->y<=0||head->y>=25)
		return true;
	return false;
}

食物:
这个比较简单,只需要有食物的坐标,并且会产生随机数就行

class food{
	private:
		int x;
		int y;//食物坐标
	public:
		int create();
		int getX();
		int getY();
};
//*********下面是实现*********
int food::create()//返回的是每个食物对应的分数
{
	srand(time(NULL));//对随机数函数初始化
	x = rand()%49+1;//要保证产生的食物在地图里面
	y = rand()%14+1;
	gotoxy(x,y);
	int ret = 1+x*y%9;
	cout<<ret;//在屏幕上显示食物
	return ret;
}
int food::getX()
{
	return x;
}
int food::getY()
{
	return y;
}

地图和人机交互界面比较容易实现,可以根据自己的兴趣实现
最后,在主函数里进行调用就行
下面是全部代码:

#include <iostream>
#include <windows.h>
#include <conio.h>
#include <cstdlib>
#include <ctime>
#include <cstdio>
using namespace std;
typedef struct Node{
	int x;
	int y;
	struct Node *p;
}Node;
void gotoxy(int x, int y);
void printMap();
class snake{
	private:
		Node *head;
		char Head;
		char Body;
	public:
		void set(char c1, char c2){
			Head = c1;
			Body = c2;
		}
		snake(){
			Node *node = new Node;
			node->p = NULL;
			head = node;
			head->x=10;
			head->y=10;
			add();
		}
		void move();
		void add();
		void print();
		void read();
		bool eat(int x, int y);
		bool die();
};
class food{
	private:
		int x;
		int y;
	public:
		int create();
		int getX();
		int getY();
};
int main()
{
	start:
	system("cls");
	cout<<"按任意键开始游戏"<<endl;
	getchar();
	system("cls");
	printMap();
	snake s;
	s.set('@', '#');
	s.print();
	food f;
	int i=f.create();
	int score=0;
	while(1)
	{
		Sleep(200);
		s.move();
		if(s.die())
		{
			system("cls");
			gotoxy(50,9);
			cout<<"Game Over!"<<endl;
			gotoxy(50,10);
			cout<<"Your Score:"<<score<<endl;
			getchar();
			goto start;
		}
		s.print();
		if(s.eat(f.getX(),f.getY()))
		{
				score+=i;
				 i = f.create();
				 if(score>=100)
				{
					system("cls");
					gotoxy(50,9);
					cout<<"You WIN!!!"<<endl;
					gotoxy(50,10);
					cout<<"你赢了!!"<<endl;
					gotoxy(50,11);
					cout<<"你得了"<<score<<"分!"<<endl;
					gotoxy(50,12);
					cout<<"按任意键重新开始"<<endl;
					getchar();
					goto start;
				}
		}
	}
	return 0;
}
void snake::move()
{
	Node* temp=new Node;
	Node* temp2=new Node;
	*temp = *head;
	Node* t = head->p;
	if(!kbhit())
	{
		if(head->x==t->x&&head->y<t->y)
			head->y --;
		if(head->x==t->x&&head->y>t->y)
			head->y ++;
 		if(head->y==t->y&&head->x<t->x)
			head->x --;
 		if(head->y==t->y&&head->x>t->x)
			head->x ++;
	}else{
		read();
	}
	while(t!=NULL)
	{
		gotoxy(t->x, t->y);
		cout<<" ";
		*temp2 = *t;
		t->x = temp->x;
		t->y = temp->y;
		t = t->p;
		*temp = *temp2;
	}
}
void snake::add()
{
	Node *t = head;
	while(t->p!=NULL)
		t = t->p;
	Node *q = new Node;
	q->x = t->x-1;
	q->y = head->y;
	q->p = NULL;
	t->p = q;
}
void snake::print()
{
	gotoxy(head->x,head->y);
	cout<<Head;
	Node *t = head->p;
	while(t!=NULL)
	{
		gotoxy(t->x,t->y);
		cout<<Body;
		t = t->p;
	}
}
void snake::read()
{
	    char ch = getch();
      	 if (ch == -32)
        {
            ch = getch();
            switch (ch)
            {
            case 72:
                head->y--;
                break;
            case 80:
                head->y++;
                break;
            case 75:
                head->x--;
                break;
            case 77:
                head->x++;
                break;
            }
        }
}
bool snake::eat(int x, int y)
{
	if(head->x == x&&head->y == y)
	{
				add();
		return true;
	}
	return false;
}
bool snake::die()
{
	if(head->x<=0||head->x>=50)
		return true;
	if(head->y<=0||head->y>=25)
		return true;
	return false;
}
void gotoxy(int x, int y)
{
	HANDLE hout;
	COORD coord;
	coord.X = x;
	coord.Y = y;
	hout = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hout, coord);
}
void printMap()
{
	for(int i=0; i<51; i++)
		cout<<"-";
	cout<<endl;
	for(int j = 0; j<15; j++)
	{
		if(j%2==0)
			cout<<"."<<endl;
		for(int i=0; i<51; i++)
		{
			if(i==0||i==50)
				cout<<"|";
			else
				cout<<" ";
		}
		cout<<endl;
	}
	for(int i=0; i<51; i++)
		cout<<"-";
	cout<<endl;
}
int food::create()
{
	srand(time(NULL));
	x = rand()%49+1;
	y = rand()%14+1;
	gotoxy(x,y);
	int ret = 1+x*y%9;
	cout<<ret;
	return ret;
}
int food::getX()
{
	return x;
}
int food::getY()
{
	return y;
}

运行效果如下:
在这里插入图片描述

4.总结

用到的比较重要的知识:
1.学会对链表的操作,增加,删除,遍历,复制
2.一些Windows api的使用,如控制光标,这些可百度
3.代码还可以进一步优化,使游戏更加美观

呼~终于写完了,最后,希望大家一起来学习,指出代码中的不足之处!!

发布了28 篇原创文章 · 获赞 38 · 访问量 7179

猜你喜欢

转载自blog.csdn.net/weixin_45543556/article/details/105528475