精华内容
下载资源
问答
  • devc++贪吃蛇 源码

    2021-06-14 21:22:58
    devc++贪吃蛇源码,经典贪吃蛇代码,包括众多模式,开始游戏,游戏说明,结束游戏等模块。
  • vs2019 C++ 贪吃蛇
  • C++贪吃蛇游戏源码

    2015-01-22 22:58:00
    C++贪吃蛇游戏源码 @或直接从这里寻找@ http://download.csdn.net/user/cleopard/album @更多@ http://cleopard.download.csdn.net/ 福利 http://xuemeilaile.com 17份软件测试文档 ...
  • 贪吃蛇C++源码

    2018-04-19 20:28:32
    个人利用空闲时间做的一个贪吃蛇C++小程序,欢迎大家下载,有问题的话可以找我交流。
  • C++贪吃蛇源码

    2013-11-03 20:10:05
    使用c++标准库所写!
  • c++贪吃蛇游戏程序源码,详细编写,适合c及c++初学者学习与临摹!
  • Dev-C++贪吃蛇

    2018-02-11 23:48:35
    【原创】用Dev-C++编译器编译。不用改编译器任何设置,代码可以直接编译!可用!上下左右键控制,回车暂停、选中。
  • C++贪吃蛇源代码

    2015-12-14 13:20:38
    C++贪吃蛇源代码,游戏共设两关,按食物累计计算是否通关,有兴趣的朋友可以下载参考。
  • 贪吃蛇c++源码

    2012-04-27 17:49:50
    c++源码贪吃蛇,想做游戏的c++朋友可以剖析一下,代码绝对经典
  • 控制台贪吃蛇C++源码

    2017-12-29 11:08:33
    基于控制台的贪吃蛇C++源码,,回调函数处理消息,直接利用windowsAPI(GDI)进行控制台窗口绘图,完整的计分关卡机制,带有游戏说明
  • C++贪吃蛇源码及程序

    2011-11-05 15:01:51
    C++ 贪吃蛇 源码 课程设计 算法实现简单,注释也很完整
  • win32版贪吃蛇源码C++,值得新手学习,框架清晰,方便添加功能,可以帮助熟练掌握stl关于容器的使用,以及对学习win32的铁子帮助很大,可以添加很多新功能,值得新手学习,如有发现bug,欢迎指正交流,一起进步
  • C++控制台应用程序,贪吃蛇源码,包含碰撞,穿墙,食物等,wasd控制方向,主要锻炼二维数组的使用。
  • c/c++贪吃蛇源码

    2013-05-02 20:55:46
    c/c++贪吃蛇源码,帮助新手了解贪吃蛇程序流程,!
  • C++实现贪吃蛇源码(EasyX图形库)

    千次阅读 多人点赞 2021-04-04 19:43:48
    这个贪吃蛇源码实现了以下的功能: ** (1)需要能在界面指定位置(x,y)直接输出对应内容 (2)需要动态数组储存蛇的身体节点 (3)需要能接收键盘指令对贪吃蛇运动方向进行调整 (4)需要随机生成食物 (5)判断蛇...

    如果你不知道怎么安装EasyX图形库
    链接: 点击这里.
    这个作者的安装教程很好,当时本人也是看这个一步一步做的
    另外如果你想要一个写的思路,可以直接看我的源码,一步一步的推敲,也可以直接看这个作者的文章点击查看.
    可能你在写的时候会遇到一部分函数使用错误的问题,主要是这个函数outtextxy(),请这样做:vs2019的情况 :项目属性——》配置属性——》高级——》字符集——》使用多字节字符集.就可以了。

    这个贪吃蛇源码实现了以下的功能:
    **
    (1)需要能在界面指定位置(x,y)直接输出对应内容
    (2)需要动态数组储存蛇的身体节点
    (3)需要能接收键盘指令对贪吃蛇运动方向进行调整
    (4)需要随机生成食物
    (5)判断蛇是否撞到墙或者自己的身体
    (6)在你的计算机的C盘生成一个C:/snakeTemp/score.txt的路径的一个文本文件,在你不再玩的时候请记得删除这个文件,这个文本是用来记录你的历史最高得分

    **

    #include<cstring>
    #include<string>
    #include<iostream>
    #include<iomanip>
    #include<graphics.h>
    #include<easyx.h>
    #include<conio.h>
    #include<windows.h>
    #include<time.h>
    #include<cstdlib>
    #include<fstream>
    #include<io.h>
    #include <direct.h>
    using namespace std;
    
    //项目启动于2021.1.31日
    //author:芽孢子
    //本次修改时间:2021.2.6日
    //实现:按下p暂停,添加了箭头操作,
    //本次修改时间:2021.2.5日
    //增加了蛇会咬死自己,成功的实现了蛇的加长(不要给我乱删指针),处理好了文件操作,优化了界面显示
    //本次修改时间:2021.2.4日
    //实现:修整了第三个地图的bug,优化了蛇的死亡的判断,增加了最高分数的的显示功能(使用了文件读取)
    //本次修改时间:2021.2.3日
    //实现:修改一个蛇身的加长的bug,做了第二张地图,初始界面,死亡动画,做了第三个地图
    //本次修改时间:2021.2.2日
    //实现:食物生成,分数统计,蛇身加长,控制蛇
    //另:
    //2021.1.31已经实现默认的传参修改能够修改地图中网格的大小
    //2021.2.2减少了代码的冗余,实现了能够操控蛇的移动
    
    //生成食物的函数
    void setfood();
    //判断蛇的死活
    void snakeAlive();
    //显示玩家的分数
    void getScore();
    //显示玩家已经死亡
    void dead();
    //开始的界面
    void be();
    //生成新的蛇的方法每次的移动都是蛇的刷新与生成
    void createsnake(int direction);
    //分数文件的读取
    int readScore();
    //分数文件的写入
    void writeScore(int score);
    
    struct snake {
    	int x = 1;
    	int y = 1;
    	snake* next = NULL;
    }*p;
    
    //对于这个数据当前的坐标为横56,宽24,这个数据中边界地部分是不可以使用地
    //坐标的范围是会随着方块地长度和间隔地变化而变化的,所以不要给我随便修改
    const int JFramx = 1400, JFramy = 600, length = 20, interval = 5, sum = length + interval;
    const int snakespeed = 95;//蛇的移动速度
    int foodx=8, foody=8;//生成食物的坐标
    //int lastx=2, lasty=2;//在尾部添加蛇身而准备的参数//尽量生成的数据不要是没有指向的
    int score ;//统计玩家的得分
    int level = '1';//地基关卡//实际数据大小应该为(1-9)字符型
    bool snakearr[60][30];//判断蛇是否死亡的bool数组
    string fileName = "C:/snakeTemp/score.txt";
    
    class Main {
    public:
    	//默认的蛇的生成//可以写在类的内部//但我怕出现bug就不改了
    	//坐标只是影响蛇出现的快慢
    	//snake e = { 6,6,NULL };
    	//snake d = { 6,7,&e };
    	snake c = { 6,8,NULL};
    	snake b = { 6,9,&c };
    	snake a = { 6,10,&b };
    	snake* head = &a;
    	snake* p = &a;
    	int snakeLength = 3;//蛇的长度
    
    	//生成地图的构造参数(默认地图的构造函数)
    	//2021.2.1添加构造已无需在修改调用游戏的启动时直接俄new这个构造就行
    	//2021.2.4日这个构造不在修改,功能完善了
    	Main(int levelNumber) {
    		score = 0;
    		//先生成上部的方块
    		for (int i = 0; i < JFramx / (length + interval); i++) {
    			//首先声明颜色,否则第一个格子怪怪的
    			setfillcolor(BLUE);
    			setcolor(BLUE);
    			fillrectangle(i * (length + interval), 0, i * (length + interval) + length, length);
    			snakearr[i][0]=1;
    			Sleep(30);
    		}
    		//对中间的方块·的操作决定了关卡的不同的说
    				if (levelNumber=='2') {
    					for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
    						fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
    						snakearr[0][i]=1;
    						if (i!=11&&i!=10&&i!=12) {
    							fillrectangle(37*sum,i*sum,37*sum+length,i*sum+length);
    							snakearr[37][i] = 1;
    						}
    						if (i!=7&&i!=8&&i!=14&&i!=15) {
    							fillrectangle(17 * sum, i * sum, 17 * sum + length, i * sum + length);
    							snakearr[17][i] = 1;
    						}
    						fillrectangle((JFramx / (length + interval) - 1) *sum, i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
    						snakearr[JFramx / (length + interval) - 1][i] = 1;
    						Sleep(30);
    					}
    				}
    				else if (levelNumber=='3') {
    					for (int i = 1; i <= JFramy / sum - 2;i++) {
    						fillrectangle(0,i*sum,length,i*sum+length);
    						snakearr[0][i]=1;
    						for (int i2 = 5; i2 < 9;i2++) {
    							for (int i1 = 12; i1 < 16;i1++) {
    								snakearr[i1][i2] = 1;
    							}
    							for (int i1 = 37; i1 < 41;i1++) {
    								snakearr[i1][i2] = 1;
    							}
    						}
    						for (int i2 = 7; i2 < 10;i2++) {
    							for (int i1 = 24; i1 < 27;i1++) {
    								snakearr[i1][i2] = 1;
    							}
    						}
    						for (int i2 = 13; i2 < 16;i2++) {
    							for (int i1 = 24; i1 < 27;i1++) {
    								snakearr[i1][i2] = 1;
    							}
    						}
    						for (int i2 = 17; i2 < 21; i2++) {
    							for (int i1 = 12; i1 < 16; i1++) {
    								snakearr[i1][i2] = 1;
    							}
    							for (int i1 = 37; i1 < 41; i1++) {
    								snakearr[i1][i2] = 1;
    							}
    						}
    						if (i==5||i==6) {
    							for (int i1 = 12; i1 < 16;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    							for (int i1 = 37; i1 < 41;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    						}
    						else if (i==8||i==7) {
    							for (int i1 = 12; i1 < 16;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    							for (int i1 = 37; i1 < 41;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    							for (int i1 = 24; i1 < 27;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    						}
    						else if (i==9||i==13||i==14||i==15) {
    							for (int i1 = 24; i1 < 27;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    						}
    						else if (i == 17 || i == 18 || i == 19||i==20) {
    							for (int i1 = 12; i1 < 16;i1++) {
    								fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
    								Sleep(30);
    							}
    							for (int i1 = 37; i1 < 41; i1++) {
    								fillrectangle(i1 * sum, i * sum, i1 * sum + length, i * sum + length);
    								Sleep(30);
    							}
    						}
    						fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
    						snakearr[JFramx / (length + interval) - 1][i]=1;
    						Sleep(30);
    					}
    				}
    				else {
    					//玩家不存在选关的操作时
    					level = '1';//令关卡的变量为零
    					for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
    						fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
    						snakearr[0][i]=1;
    						fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
    						snakearr[JFramx / (length + interval) - 1][i]=1;
    						Sleep(30);
    					}
    				}
    		//底部的生成
    		for (int i = 0; i < JFramx / (length + interval); i++) {
    			fillrectangle(i * (length + interval), (JFramy / (length + interval) - 1) * (length + interval), i * (length + interval) + length, JFramy - interval);
    			snakearr[i][JFramy / (length + interval) - 1]=1;
    			Sleep(30);
    		}
    		Main('s');
    	}
    
    	//这个构造完善了,不能在修改,时间2021.2.3
    	//蛇的加入构造,其中还有蛇的移动方法
    	Main(char numebr) {
    		int temp_key = 's';//接受键盘输入的事件的暂时量,为了使蛇的身体不会实现倒退的情况
    		while (1) {//接受键盘的事件
    			int ch;//接受键盘上的事件的得到的数据
    			Sleep(5);
    			if (_kbhit()) {
    				ch = _getch();
    				if (ch == 27) { closegraph();  break; }
    				else if ((ch == 'd'||ch==77) && temp_key != 'a') {//向右移动//新加入了判断蛇回退的判断
    					temp_key = 'd';
    				}else if ((ch == 'w'||ch==72)&&temp_key!='s') {    //向上移动//判断已添加
    					temp_key = 'w';
    				}else if ((ch == 's'||ch==80)&&temp_key!='w') {   //向上移动//判断已添加
    					temp_key = 's';
    				}else if ((ch == 'a'||ch==75)&&temp_key!='d') {   //向上移动//判断已添加
    					temp_key = 'a';
    				}else if (ch=='p') {
    					pauseGame();
    				}
    			}
    			//这里是蛇身移动的方法,在没有输入的时候的情况//已经减少了代码的冗余
    			if (temp_key=='d') {
    				createsnake(1);
    			}if (temp_key=='w') {
    				createsnake(2);
    			}if (temp_key=='s') {
    				createsnake(4);
    			}if (temp_key=='a') {
    				createsnake(3);
    			}
    		}
    	}
    
    	//生成新的蛇的方法每次的移动都是蛇的刷新与生成
    	void createsnake(int direction) {
    		//直接在生成蛇的时候就直接判断蛇的死亡
    		getScore();
    		setfood();
    		if (head->x==foodx&&head->y==foody) {
    			snake* endsnake=new snake;
    			endsnake->x = head->x;
    			endsnake->y = head->y;
    			endsnake->next = head;
    			snake* s = new snake;
    			 head=endsnake;
    		}
    		for (p = head; p; p = p->next) {
    			clearrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
    		}
    		int tempy = head->y;
    		int tempx = head->x;
    		int tempx02;
    		int tempy02;
    		if (direction == 1) { head->x++; }
    		else if (direction == 2) { head->y--; }
    		else if (direction == 3) { head->x--; }
    		else if (direction == 4) { head->y++; }
    		for (p = head; p; p = p->next) {
    			if (p == head) {
    				setcolor(RED);
    				setfillcolor(LIGHTRED);
    			}
    			else {
    				setcolor(GREEN);
    				setfillcolor(GREEN);
    			}
    			if (p == head) {
    				fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
    			}
    			else {
    				tempx02 = p->x;
    				tempy02 = p->y;
    				p->x = tempx;
    				p->y = tempy;
    				fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
    				tempx = tempx02;
    				tempy = tempy02;
    			}
    		}
    		Sleep(snakespeed);
    		snakeAlive(level);
    	}
    
    	//生成食物的函数
    	void setfood() {
    		if (head->x == foodx&&head->y==foody) {
    			score++;//分数的增加
    			addSnake();
    			unsigned seed=(time(0));
    			srand(seed);
    			foody = rand() % 22 + 1;
    			if (level=='1') {
    				foodx = rand() % 54 + 1;
    			}
    			else if (level=='2') {
    				if (head->x<17) {
    					foodx = rand()%17+20;
    				}
    				else if (head->x<37) {
    				foodx = rand()%17+38;
    				}
    				else if (head->x<55) {
    					foodx = rand() % 16 + 1;
    				}
    			}
    			else if (level=='3') {
    				if (head->x<12) {
    					foodx = rand()%7+16;
    				}
    				else if (head->x<24) {
    					foodx = rand() % 10+27;
    				}
    				else if (head->x<37) {
    					foodx = rand() % 14 + 41;
    				}
    				else if (head->x<54) {
    					foodx = rand() % 12 + 1;
    				}
    			}
    			setfillcolor(LIGHTMAGENTA);
    			fillrectangle(foodx*sum,foody*sum,foodx*sum+length,foody*sum+length);
    		}
    		else {
    		setcolor(LIGHTMAGENTA);
    		setfillcolor(LIGHTMAGENTA);
    		fillrectangle(foodx * sum, foody * sum, foodx * sum + length, foody * sum + length);
    		}
    	}
    
    	//判断蛇是否死亡
    	//本次修改时间:2021.2.4
    	//已经优化了特别多了,不要再修改了
    	//被调用的上级createSnake();
    	void snakeAlive(int level) {
    		for (p = head; p;p=p->next) {
    			if (head->x==p->x&&head->y==p->y&&p!=head) {
    				dead();
    				closegraph();
    			}
    		}
    		if (snakearr[head->x][head->y]==1) {
    			dead();
    			closegraph();
    		}
    	}
    
    	//使地图显示分数
    	void getScore() {
    		RECT r = { sum,sum,1200, 550 };
    		string s = "你的分数";
    		string stemp = to_string(score);
    		s += stemp;
    		settextcolor(GREEN);
    		drawtext(_T(s.c_str()),&r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    	}
    
    	//届几个在类外实现了
    	void addSnake();
    	void dead();
    	static void createTempFile();
    	static void createTempDirectory();
    	void pauseGame();//游戏的暂停方法
    };
    
    
    void Main::pauseGame() {
    	bool temp = 1;
    	while (temp) {
    		if (_kbhit()) {
    			temp = 0;
    		}
    	}
    }
    
    void Main::createTempDirectory() {
    	const char* temp_directory = "C:/snakeTemp";
    	if (_access(temp_directory,0)!=0) {
    		_mkdir(temp_directory);
    	}
    }
    
    
    //生成文件
     void Main::createTempFile() {
    	//下面这个判断在文件存在时返回的为0,于是在不为0时文件就不存在了
    	 createTempDirectory();
    	if (_access(fileName.c_str(),0)!=0) {
    		ofstream temp_os(fileName, ios::app);
    		temp_os << '0';
    		temp_os.close();
    	}
    }
    
    
    void Main::addSnake() {
    	snake* endsnake=head,*q=new snake;
    	while (endsnake ->next!=NULL) {
    		endsnake = endsnake -> next;
    	}
    	q->x = endsnake->x;
    	q->y = endsnake->y;
    	endsnake->next = q;
    }
    
        //死亡的动画
    	//时间2021.2.4:方法差不多完善了,之后可以在加一个io流的方法
    void Main::dead() {
    	for (int i = 0; i < 5;i++) {
    		for (p = head; p;p=p->next) {
    			clearrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
    		}
    		Sleep(200);
    		for (p = head; p;p=p->next) {
    			if (p->x==head->x&&p->y==head->y) {
    				setfillcolor(RED);
    				fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
    			}
    			else {
    				setfillcolor(GREEN);
    				fillrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
    			}	
    		}
    		Sleep(30);
    	}
    	if (score>readScore()) {//如果本次得分比上一次的高就保存在本地文件
    		writeScore(score);
    	}
    	clearcliprgn();
    	char string[] = "时间停止了,你..死了!";
    	char string01[] = "                      ";
    	settextcolor(RED);
    	settextstyle(100, 0, _T("宋体"));
    	for (int i = 0; i < 3; i++) {
    		outtextxy(250, 300, string);
    		Sleep(500);
    		outtextxy(250, 300, string01);
    		Sleep(1000);
    	}
    	settextcolor(GREEN);
    	char string02[] = "马上就会回到初始界面";
    	settextstyle(100, 0, _T("宋体"));
    	outtextxy(250, 300, string02);
    	Sleep(1000);
    	clearcliprgn();
    	be();
    }
    
    
    int readScore() {
    	fstream scorefile(fileName, ios::in);
    	string s;
    	getline(scorefile,s);
    	scorefile.close();
    	return stoi(s);
    }
    
    void writeScore(int score) {
    	fstream scorefile(fileName, ios::trunc | ios::out);
    	scorefile << score;
    	scorefile.close();
    }
    
    void be() {
    	Main::createTempFile();
    	memset(snakearr, 0, sizeof(snakearr));//bool数组的赋值
    	initgraph(JFramx, JFramy);
    	char str_0[] = "》贪吃蛇《";
    	char tips[] = "提示:";
    	char str_1[] = "欢迎你的游玩,本游戏由芽孢子独立完成,特别鸣谢张百害";
    	char str_2[] = "·使用WASD控制蛇的移动,箭头也行";
    	char str_3[] = "·撞墙而死.按p暂停";
    	char str_4[] = "·游戏界面可以显示你的分数";
    	char str_5[] = "   点击任意键继续";
    	char str_6[] = "·键盘输入数字可以选关(1-3)";
    	char deletestr[] = "                                                  ";
    	settextstyle(50, 0, _T("宋体"));
    	outtextxy(620, 50, str_0);
    	settextstyle(20, 0, _T("宋体"));
    	outtextxy(500, 130, str_1);
    	outtextxy(500, 180, tips );
    	outtextxy(500, 230, str_2);
    	outtextxy(500, 280, str_3);
    	outtextxy(500, 330, str_4);
    	outtextxy(500, 380, str_6);
    	settextstyle(50, 0, _T("宋体"));
    
    	int scoreFileNumber = readScore();
    	string scoreFile = "   你的最高分数:";
    	scoreFile += to_string(scoreFileNumber);
    	char Outscore[1024];
    	strcpy_s(Outscore,sizeof(Outscore),scoreFile.c_str());//c_str()方法能加字符串转化为字符数组
    
    	while (1) {
    		if (_kbhit()) {
    			level =_getch();//再键盘上得到的字符类型,从零开始计数的话,0的ASCll的值为48
    			if (level==27) {//在初始的界面中所加上的一个退出的的选项
    				closegraph();
    			}
    			break;
    		}
    		outtextxy(450, 500, str_5);
    		Sleep(500);
    		outtextxy(450, 500, deletestr);
    		Sleep(500);
    		outtextxy(450,500,Outscore);
    		Sleep(700);
    		outtextxy(450, 500, deletestr);
    		Sleep(500);
    	}
    	clearcliprgn();
    	new Main(level);//这里传值
    }
    
    int main() {
    	be();
    	getchar();
    	return 0;
    }
    
    展开全文
  • c++贪吃蛇完整源代码

    2010-06-13 18:41:35
    绝对完整的贪吃蛇源代码,c++编写,环境为visualc++6.0,包括完整的工作区、工程文件。是c++初学者不可多得的资料
  • c++贪吃蛇源代码 完整版

    万次阅读 多人点赞 2020-01-10 16:26:26
    c++ 实现贪吃蛇, 完整源码 文章结构: 数据结构分析 程序运行分析 难点分析 一点思考 源代码 总结 数据结构分析: 1.双向队列:这里我才用双向队列的数据结构存储蛇身节点(这里的蛇身节点我才用...

    c++ 实现贪吃蛇, 完整源码

    0.非常重要的注意事项

    请注意:
    1.这是c++代码,请建立.cpp文件而不是.c文件,然后将代码拷贝进去,再使用c++编译器进行编译运行。

    2.因为使用了一些c++11标准当中的语法,所以c++编译器的编译标准至少需要设置到c++11以上,不然会报错。编译标准可以在你的IDE里设置,或者使用命令行编译时附加-std=c++11选项。

    3.代码中使用了getch()函数,用于无回显的接收用户输入;使用了kbhit()函数用于判断用户是否按下键盘。但是如果你在visual studio中直接运行本代码可能会报错,你可以将上述两个函数替换为_getch()函数和_kbhit()函数就可以了。

    1.数据结构分析:

    这里我采用双向队列的数据结构存储蛇身节点,目的是:方便,减少屏闪。并且双向队列也能更好的体现贪吃蛇本身的特点。有利于实现,且效率也较高。

    2.程序运行分析

    程序开始用户随机按下w,a,s,d中任意按键开始游戏并且作为蛇运动的初始方向(如果刚开始觉得蛇的运动速度太慢可以键入’v’使变为当前运行素的1.25倍速,键入’b’则会使之变为当前速度的2/3倍速),然后进入循环持续游戏直到游戏结束,显示分数之后用户输入任意按键退出游戏。

    3.难点分析

    1.蛇移动怎么显示?

    这也就是我采用双向队列的原因,蛇每运动一步,就从双向队列中弹出队尾,然后将新的队首(即蛇头)压入队列首部,然后再清除蛇尾打印蛇身即可,不需要对贪吃蛇全部进行清楚以及打印,可以极大的减少程序运行过程中出现的闪烁现象。如果吃到食物那么本次运动就会在将蛇尾变为蛇头的同时再加入一个蛇身达到使蛇身长度加一的目的(我认为双向队列更能从本质上体现贪吃蛇本来的特点,而每次弹出队尾,加入队首而不对中间的蛇身进行改变也使程序变得更加简洁,运行更流畅)

    2.怎么控制吃到食物后蛇的速度的变化?

    最开始我设置初始速度为1000(即:Sleep()函数的参数为1000)每次吃到食物就将速度乘以0.8以此达到加速的目的。但我发现到后面速度越来越快没有上限,根本无法控制。
    解法:设置一个上限为MaxSpeed,则速度为 MaxSpeed + Index,MaxSpeed 保持不变且较小作为蛇速度的渐进上限,每次乘以0.8(可自定义)则乘到Index上面,这样的话速度就不会无限制的上升。

    3.怎么解决屏幕闪烁?

    解:不要使用system(“cls”);清屏函数,使用函数SetConsoleCursorPosition控制光标填充空格进行覆盖能大大减少屏闪问题!!这一点要注意了!

    4.一些废话

    1.首先肯定是存储蛇身的数据结构方面,有很多种选择:链表,双向队列,循环队列,vector甚至数组都可以用来存储蛇身。
    2.最开始以为这个比较简单…上手就开始写写废了一次,提醒大家在写程序(特别是这种结构比较复杂且步骤较多的程序)时一定要先进行规划,想清楚要使用的数据结构以及构建方式,想清楚再写,避免浪费时间。

    5.源代码

    下面是源代码,还需要什么功能大家可以在此基础上进行改动。

    #include<iostream>
    #include<windows.h>
    #include<conio.h>
    #include<deque>
    #include<ctime>
    #include<stdexcept>
    using namespace std;
    
    struct Snake { //蛇类结构体
        char image;
        short x, y; //坐标
    };
    
    class snakeGame {
    	public:
    	snakeGame();
    	void printMap();
    	// 控制光标移动
    	void gotoxy(short x, short y) {
    		hOut = GetStdHandle(STD_OUTPUT_HANDLE); //获取句柄
    		pos = {x, y};
    		SetConsoleCursorPosition(hOut, pos); //移动光标
    	}
    	//隐藏光标
    	void HideCursor()
    	{
    		HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    		CONSOLE_CURSOR_INFO CursorInfo;
    		GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
    		CursorInfo.bVisible = false; //隐藏控制台光标
    		SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
    	}
    	// 初始化蛇身,可根据需要更改初始长度
    	void initSnake() {
    		snake.push_front({'@', width / 2, height / 2});
    		for (int i=0; i<2;++i)
    			snake.push_back({'+', width/2,static_cast<short>(height/2+i+1)});
    	}
    	// 判断是否食物产生位置与蛇身冲突
    	int WrongLocation() {
    		for (Snake body : snake)
    			if(body.x == food_x && body.y == food_y) return 0;
    		return 1;
    	}
    	// 产生食物,并打印
    	void createFood() {
    		do {
    			food_x = rand() % (width - 4) + 2;
    			food_y = rand() % (height - 2) + 1;
    		} while (!WrongLocation());//处理冲突
    		gotoxy(food_x,food_y); cout << '*' << endl; //打印食物
    	}
    	void printSnake();
    	// 清除蛇尾
    	inline void clearSnake(Snake &tail) {
        	gotoxy(tail.x, tail.y); cout << ' '; //覆盖蛇尾,不使用清屏函数,避免了闪烁
    	}
    	void judgeCrash();
    	void foodEaten();
    	// 监控用户键盘输入
    	void userInput() {
    		char ch;
    		switch(ch=getch()) {
    			case 'w':if (dir != 's') dir = ch;break;
    			case 'a':if (dir != 'd') dir = ch;break;
    			case 's':if (dir != 'w') dir = ch;break;
    			case 'd':if (dir != 'a') dir = ch;break;
    			case 'v':speed*=0.8;break; case 'b':speed*=1.5;break;
    			case ' ':gotoxy(width / 2, height); cout << "游戏已暂停,任意键继续"; getch();
                gotoxy(width / 2, height); cout << "                     "; break;
    			default:break;
    		}
    	}
    	private:
    	// 以下是程序运行当中需要用到的一些中间变量或者是数据变量。
    	enum MapSize {height = 40,width = 120}; //地图尺寸
    	HANDLE hOut; COORD pos;
    	char dir; //direction
    	bool beg,eatFood=false;
    	double speed=200;
    	deque<Snake> snake;
    	int food_x,food_y;
    	int score=0;
    };
    // 处理吃到食物的情况
    void snakeGame::foodEaten() {
    	createFood();
    	eatFood=true;
    	speed*=.8;
    	++score;
    }
    // 判断蛇是否撞墙或者吃到自己的尾巴
    void snakeGame::judgeCrash() {
    	int flag=0;
    	if (snake.size()>=5) {
    		deque<Snake>::iterator iter = snake.begin() + 1;
    		int x = (iter-1)->x, y = (iter-1)->y;
    		for (; iter != snake.end(); ++iter) {
    			if (iter->x == x && iter->y == y) flag=1;
    		}}
    	if (flag || snake.front().x == 1 || snake.front().x == width - 2 || snake.front().y == 0 || snake.front().y == height - 1)//检测是否撞墙或者是否吃到自身
        {
            gotoxy(width / 2 - 10, height /2);
            cout << "游戏结束!您的分数是: " << score << "分(回车继续)"<<endl;
            while(1) {
                dir = getch();
                if (dir == '\r') break;}
    		runtime_error quit("游戏结束,正常退出"); throw quit;
        }
    }
    // 将蛇身打印出来
    void snakeGame::printSnake() {
        deque<Snake>::const_iterator iter = snake.begin();
        for (; iter <= snake.begin() + 1 && iter < snake.end(); ++iter) {
            gotoxy(iter->x, iter->y); cout << iter->image;
        }
    }
    // 打印出边框
    void snakeGame::printMap() {
    	int i;
        for (i = 0; i != width; i += 2) cout << "■"; //这个图案宽度占2,高度占1
        gotoxy(0, 1);
        for (i = 1; i != height; ++i) cout << "■" << endl;
        for (i = 1; i != height; ++i) {
            gotoxy(width - 2, i); cout << "■";}
        gotoxy(0, height - 1);
        for (i = 0; i != width; i += 2) cout << "■";
        cout << "贪吃蛇:1.方向键开始游戏 2.*代表食物 3.空格键暂停游戏\n        4.键入'v'加速    5.键入'b'减速";
    }
    // 类的构造函数。
    // 包含了程序的初始化(地图绘制,蛇身初始化),程序运行,程序结束等内容
    // 是程序最关键的部分
    snakeGame::snakeGame() {
    	HideCursor(); // 隐藏光标
    	srand(static_cast<unsigned int>(time(NULL)));
    	beg=true;
    	Snake tmp1,tmp2;
    	while (1) {
    		if(beg) { // 判断是不是第一次运行程序,因为第一次运行需要打印边框
    			printMap();
    			dir = getch();
    			initSnake();
    			createFood();
    			beg = eatFood=false;
    		}
    		tmp2=snake.back();
    		tmp1=snake.front();
    		snake.pop_back();
    		if (eatFood) { // 如果吃到食物...
    			tmp2.image='+';
    			snake.push_back(tmp2);
    			eatFood=false;
    		}
    		else clearSnake(tmp2);
    		// 判断当前的前进方向,根据dir来进行移动
    		if      (dir == 's') ++tmp1.y;
            else if (dir == 'a') --tmp1.x;
            else if (dir == 'd') ++tmp1.x;
            else 				 --tmp1.y;
    		try{
    			judgeCrash(); // 判断是否撞墙或者吃到自己
    		}
    		catch(runtime_error &quitSignal) {
    			throw quitSignal;
    		}
    		snake.front().image='+';
    		snake.push_front(tmp1);
    		printSnake();
    		Sleep(speed+30);
    		if (tmp1.x == food_x && tmp1.y == food_y) 
    			foodEaten();
    		// 监测用户的键入
    		if(kbhit()) userInput();
    	}
    }
    int main() {
    	// 设置小黑框的一些参数
    	system("mode con cols=120 lines=42");
    	try{
    		snakeGame game;
    	}
    	catch(runtime_error &gameEnd) {
    		system("cls");
    		cout<<gameEnd.what();
    		getch();
    	}
    }
    

    6.运行效果展示

    将边界改成方块后的运行截图

    7.总结

    网上真正能用的贪吃蛇源代码还是很少的,就算找到了不是要收费下载就是复制过来一大堆报错或者bug运行不了,所以本着帮助他人的想法自己写了一个版本的。写得不是很好,有不足之处欢迎大家批评指正。
    有任何问题可以留在评论区,力所能及可以给予帮助。
    peace~

    如果代码有报错可以去看看开头的重要注意事项喔~

    展开全文
  • C++贪吃蛇游戏源代码

    2015-06-23 20:33:47
    C++程序制作贪吃蛇游戏,核心算法是如何实现移动和吃掉食物.没有碰到食物的时候,把当前运动方向上的下个节点入队,并通过链表来添加蛇的节点.当吃到随机的食物时,蛇的节点自动增加。
  • int main() { cout 贪吃蛇\n\n\n\t\t Powered by xxxxxxx(差点忘了删)"; short int i,j, a, b; cout请输入行数:"; cin>>a; cin.sync(); cin.clear(); cout请输入列数:"; cin>>b; cin.sync(); cin.clear(); a+=2...

    [Asm] 纯文本查看 复制代码#include

    #include

    #include

    #include

    #include

    using namespace std;

    int eat_food = 0;

    float score = 0;

    short int grade = 0;

    short int timeout = 700;

    int step = 0;

    short int derect=77;//上下左右 asc

    class SNAKE

    {

    short int x;

    short int y;

    SNAKE* Qian;

    SNAKE* Hou;

    public:

    SNAKE(){x = 0; y = 0; Qian = NULL; Hou = NULL;}

    SNAKE(int a, int b){x = a; y =b; Qian = NULL; Hou = NULL;}

    void change(int a ,int b){if(a!=-1)x = a; if(b!=-1)y = b;}

    short int getx(){return x;}

    short int gety(){return y;}

    SNAKE* qian(){return Qian;}

    SNAKE* qian(SNAKE* a){Qian=a;return Qian;}

    SNAKE* hou(){return Hou;}

    SNAKE* hou(SNAKE* a){Hou=a;return Hou;}

    };

    class FOOD

    {

    public:

    short int x;

    short int y;

    };

    FOOD food;

    SNAKE* end;//尾巴地址

    SNAKE* head;///头地址

    bool move(int,int,short int **);

    bool randfood(int, int , short int &,short int &,short int **);

    int main()

    {

    cout << "\n\t贪吃蛇\n\n\n\t\t Powered by xxxxxxx(差点忘了删)";

    short int i,j, a, b;

    cout<

    cin>>a; cin.sync(); cin.clear();

    cout<

    cin>>b; cin.sync(); cin.clear();

    a+=2;b+=2;

    short int **point;

    point = new short int* [a]; //-1 墙 0 空 1 身子 2 食物 3头

    for(i=0; i

    point[i]=new short int[b];

    for(i = 1; i < a-1; ++i)

    for(j = 1; j < b-1; ++j)

    point[i][j] = 0;

    for(i = 0; i < a; ++i)

    point[i][b-1]=point[i][0]=-1;

    for(i = 0; i < b; ++i)

    point[0][i]=point[a-1][i]=-1;

    cout << " 游戏马上开始,请按任意键继续\n PS:可随时以cmd选择模式暂停\n\n";

    system("pause");

    end = new SNAKE;

    SNAKE* save_end = end;

    for(i = 1; i < (a-2)*(b-2); ++i)

    {

    head = new SNAKE;

    end -> qian(head);

    head -> hou(end);

    end = head;

    }

    head -> qian(save_end);

    save_end -> hou(head);

    head=head->qian();/形成a*b的环状双向链表,已验证

    end->change(a/2, b/2-1);

    head->change(a/2, b/2);

    point[a/2][b/2-1]=1;

    point[a/2][b/2]=3;

    randfood(a, b, food.x,food.y,point);

    while(move(a,b,point));///传值边界含外框

    for(i=0;i

    展开全文
  • C++贪吃蛇代码

    2016-02-12 16:57:45
    C++贪吃蛇代码,使用的dev c++测试,
  • C++控制台贪吃蛇源码

    2019-05-03 10:17:43
    非常精简的贪吃蛇游戏c++源码,总共140行代码,在控制台实现了贪吃蛇游戏逻辑,初学者可以做个参考
  • c++贪吃蛇贪吃蛇.zip

    2020-03-28 18:18:03
    c++贪吃蛇
  • c++贪吃蛇游戏源码

    2014-07-26 15:13:23
    控制台下的简单贪吃蛇,供新手参考,基本没啥工程价值。
  • 贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)贪吃蛇源码c++编写)
  • 贪吃蛇C++程序源码

    2018-11-28 10:19:37
    贪吃蛇c++.vcxproj 这是使用应用程序向导生成的 VC++ 项目的主项目文件, 其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
  • 贪吃蛇C++源码.zip

    2019-10-17 16:53:45
    一个C++写的贪吃蛇小游戏,使用控制台显示,键盘的wasd按键操控。
  • 本人用VS2017和C++写的贪吃蛇代码,运用方向键控制上下左右,具有不同果实,加速减速效果,同时有开始界面、暂停界面、结束界面和相应的BGM,另外还有存档和排行榜功能(并不是多用户)。同时附赠实验报告。
  • 贪吃蛇源码

    2018-01-06 18:20:34
    Qt C++制作贪吃蛇游戏,点击开始按键时进入游戏界面,游戏的等级和分数可以自己去设置,细节问题,自己可以去调试。贪吃蛇的难点,就是蛇的移动,与绘制蛇身蛇尾。
  • C++课程设计贪吃蛇源码附带详细注释+该程序的课设报告。这是我曾经使用过进行C++课程设计的代码,有注释+课设报告,保证轻松完成答辩

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,399
精华内容 959
关键字:

c++贪吃蛇源码

c++ 订阅