贪吃蛇-EasyX版

目录

 开始界面

OPTIONS界面

RULE界面

 COLOUR界面

 SPEED界面

 MAPSIZE界面

游戏界面

源码 


VS2022  EasyX库 C++

写在前面:贪吃蛇用数组模拟循环队列,最大长度(也即数组的长度)是里面宏定义的SNAKELENGTH,没有写判断最后是否满屏胜利。我自己加了一些选项界面虽然不太美观但也能看。蛇的移动是通过用背景(我的背景是白色的,所以我就用了一张白色的图片)覆盖最后一个节点,然后打印新的头部节点,这样子每次只需要对两个节点进行操作,不需要把所有的节点全部删除然后再打印。一开始写的时候用了链表,使用上出了点问题还有很高的延迟,所以直接换了方法。其中改变蛇颜色里的 loadimage 可以选择不同的节点样式(我自己画了几个。。),需要根据自己的图片文件位置进行更改,学过一些easyx的同学应该很容易操作。

 开始界面

 进入游戏后会看到如图的界面,START即开始游戏,所有选项都会按照默认设置。

  1. 地图大小:400*400
  2. 地图规则:不可穿墙
  3. 蛇身颜色:黑色
  4. 蛇行进速度:speed1(即 1/1 s前进一格)

OPTIONS界面

  1. RULE:进入更改游戏规则界面,即是否可以穿墙
  2. COLOUR:进入更改蛇身颜色界面
  3. SPEED:进入更改蛇速度界面
  4. MAPSIZE:进入更改地图大小界面
  5. BACK:返回上一界面

RULE界面

即是否可以穿墙 

 COLOUR界面

可选择的节点样式,可以根据自己的需求增加或删除 

 SPEED界面

 

分别对应 1/1 s ,1/2 s ,1/4 s , 1/8 s 

 MAPSIZE界面

 更改地图大小,返回后应用(单位像素),默认为最小400*400

游戏界面

源码 

#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#define SNAKELENGTH 160

class MAP {
private:
	int size; //大中小三种地图(20的倍数)800*800 、400*400 、 600*600  (再+20为一个节点的大小)
	bool rule; //0 不能穿地图,1 可以
public:
	MAP() :size(420), rule(false) {}
	MAP(int a, bool b) :size(a), rule(b) {}
	int get_size() {return size;}
	bool get_rule() {return rule;}
	void set_size(int sz) {size = sz;}
	void set_rule(bool ru) {rule = ru;}
};
struct NODE {
	int x, y;
};
struct SNAKE {
	int length;
	NODE body[SNAKELENGTH];
	int head, tail;
	int speed;
	SNAKE(int len=0,int h=0,int t=0,int spd=1):length(len),head(h),tail(t),speed(spd) {
		body[0].x = 200;
		body[0].y = 200;
	}
};
void START() { //绘制开始窗口

	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 180, _T("START"));
	outtextxy(180, 220, _T("OPTIONS"));
	outtextxy(180, 260, _T("EXIT"));
}
void OPTIONS() { //绘制选项窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 140, _T("RULE"));
	outtextxy(180, 180, _T("COLOUR"));
	outtextxy(180, 220, _T("SPEED"));
	outtextxy(180, 260, _T("MAPSIZE"));
	outtextxy(180, 300, _T("BACK"));
}
void RULE() { //绘制RULE窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 180, _T("YES"));
	outtextxy(180, 220, _T("NO"));
	outtextxy(180, 260, _T("BACK"));
}
void COLOR() { //绘制调节蛇颜色窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 180, _T("black"));
	outtextxy(180, 220, _T("red"));
	outtextxy(180, 260, _T("pink"));
	outtextxy(180, 300, _T("green"));
	outtextxy(180, 340, _T("BACK"));
}
void SPEED() { //绘制调节速度窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 180, _T("speed1"));
	outtextxy(180, 220, _T("speed2"));
	outtextxy(180, 260, _T("speed4"));
	outtextxy(180, 300, _T("speed8"));
	outtextxy(180, 340, _T("BACK"));
}
void MAPSIZE() { //绘制调节地图大小窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(180, 180, _T("400*400"));
	outtextxy(180, 220, _T("600*600"));
	outtextxy(180, 260, _T("800*800"));
	outtextxy(180, 300, _T("BACK"));
}
void EXIT() { //绘制退出窗口
	setbkcolor(WHITE);
	cleardevice();
	setbkcolor(COLORREF(0x9c9690));
	//绘制文本
	settextcolor(BLACK);
	settextstyle(20, 15, _T("黑体"));
	outtextxy(50, 180, _T("DO IT YOURSELF"));
	Sleep(1000000);
	setbkcolor(WHITE);
	cleardevice();
	settextstyle(20, 0, _T("黑体"));
	outtextxy(100, 200, _T("还是要我来"));
	//Sleep(1000000);
}



int main() {
	MAP my_map;
	SNAKE my_snake(1, 0, 0, 1);
	IMAGE my_style, white, food;
	ExMessage mess;
	int my_face=0;
	int food_x, food_y;
	loadimage(&my_style, _T("pho\\black.png"));
	loadimage(&white, _T("pho\\white.png"));
	loadimage(&food, _T("pho\\food.png"));
	initgraph(420, 420);


	START();
	int start_x = 140, start_y = 180;
	outtextxy(start_x, start_y, _T("->"));
	while (1) { //接收开始游戏或结束游戏
		
		char start_com = _getch();

		if (start_com == 72 || start_com == 75) {
			start_y -= 40;
			if (start_y < 180) start_y = 260;
		}
		else if (start_com == 80 || start_com == 77) {
			start_y += 40;
			if (start_y > 260) start_y = 180;
		}
		else if (start_com == 13) {
			if (start_y == 220) { //进入OPTIONS
				OPTIONS();
				int options_x = 140, options_y = 100;
				while (1) { //接收options,选择设置
					char options_com = _getch();
					if (options_com == 72 || options_com == 75) {
						options_y -= 40;
						if (options_y < 140) options_y = 300;
					}
					else if (options_com == 80 || options_com == 77) {
						options_y += 40;
						if (options_y > 300) options_y = 140;
					}
					else if (options_com == 13) {
						if (options_y == 140) { //改变规则
							RULE();
							int rule_x = 140, rule_y = 180;
							outtextxy(rule_x, rule_y, _T("->"));
							while (1) {
								char rule_com = _getch();
								if (rule_com == 72 || rule_com == 75) {
									rule_y -= 40;
									if (rule_y < 180) rule_y = 260;
								}
								else if (rule_com == 80 || rule_com == 77) {
									rule_y += 40;
									if (rule_y > 260) rule_y = 180;
								}
								else if (rule_com == 13) {
									if (rule_y == 180) {
										my_map.set_rule(1);
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										RULE();
										outtextxy(rule_x, rule_y, _T("->"));
									}
									else if (rule_y == 220) {
										my_map.set_rule(0);
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										RULE();
										outtextxy(rule_x, rule_y, _T("->"));
									}
									else if (rule_y == 260) {
										break;
									}
								}
								RULE();
								outtextxy(rule_x, rule_y, _T("->"));
							}
						}
						else if (options_y == 180) { //改变蛇颜色
							COLOR();
							int color_x = 140, color_y = 180;
							outtextxy(color_x, color_y, _T("->"));
							while (1) {
								char color_com = _getch();
								if (color_com == 72 || color_com == 75) {
									color_y -= 40;
									if (color_y < 180) color_y = 340;
								}
								else if (color_com == 80 || color_com == 77) {
									color_y += 40;
									if (color_y > 340) color_y = 180;
								}
								else if (color_com == 13) {
									if (color_y == 180) {
										loadimage(&my_style, _T("pho\\black.png"));
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										COLOR();
										outtextxy(color_x, color_y, _T("->"));
									}
									else if (color_y == 220) {
										loadimage(&my_style, _T("pho\\red.png"));
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										COLOR();
										outtextxy(color_x, color_y, _T("->"));
									}
									else if (color_y == 260) {
										loadimage(&my_style, _T("pho\\pink.png"));
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										COLOR();
										outtextxy(color_x, color_y, _T("->"));
									}
									else if (color_y == 300) {
										loadimage(&my_style, _T("pho\\green.png"));
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										COLOR();
										outtextxy(color_x, color_y, _T("->"));
									}
									else break;
								}
								COLOR();
								outtextxy(color_x, color_y, _T("->"));
							}
						}
						else if (options_y == 220) { //改变蛇速度
							SPEED();
							int speed_x = 140, speed_y = 180;
							outtextxy(speed_x, speed_y, _T("->"));
							while (1) {
								char speed_com = _getch();
								if (speed_com == 72 || speed_com == 75) {
									speed_y -= 40;
									if (speed_y < 180) speed_y = 340;
								}
								else if (speed_com == 80 || speed_com == 77) {
									speed_y += 40;
									if (speed_y > 340) speed_y = 180;
								}
								else if(speed_com==13) {
									if (speed_y == 180) {
										my_snake.speed = 1;
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										SPEED();
										outtextxy(speed_x, speed_y, _T("->"));
									}
									else if (speed_y == 220) {
										my_snake.speed = 2;
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										SPEED();
										outtextxy(speed_x, speed_y, _T("->"));
									}
									else if (speed_y == 260) {
										my_snake.speed = 4;
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										SPEED();
										outtextxy(speed_x, speed_y, _T("->"));
									}
									else if (speed_y == 300) {
										my_snake.speed = 8;
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										SPEED();
										outtextxy(speed_x, speed_y, _T("->"));
									}
									else break;
								}
								SPEED();
								outtextxy(speed_x, speed_y, _T("->"));
							}
						}
						else if (options_y == 260) { //改变地图大小
							MAPSIZE();
							int map_x = 140, map_y = 180;
							outtextxy(map_x, map_y, _T("->"));
							while (1) {
								char map_com = _getch();
								if (map_com == 72 || map_com == 75) {
									map_y -= 40;
									if (map_y < 180) map_y = 300;
								}
								else if (map_com == 80 || map_com == 77) {
									map_y += 40;
									if (map_y > 300) map_y = 180;
								}
								else if (map_com == 13) {
									if (map_y == 180) {
										my_map.set_size(420);
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										MAPSIZE();
										outtextxy(map_x, map_y, _T("->"));
									}
									else if (map_y == 220) {
										my_map.set_size(620);
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										MAPSIZE();
										outtextxy(map_x, map_y, _T("->"));
									}
									else if (map_y == 260) {
										my_map.set_size(820);
										outtextxy(0, 0, _T("SUCCEED!"));
										Sleep(500);
										MAPSIZE();
										outtextxy(map_x, map_y, _T("->"));
									}
									else {
										closegraph();
										initgraph(my_map.get_size(), my_map.get_size());
										MAPSIZE();
										break;
									}
								}
								MAPSIZE();
								outtextxy(map_x, map_y, _T("->"));
							}
						}
						else if (options_y == 300) { //返回上一菜单
							break;
						}
					}
					OPTIONS();
					outtextxy(options_x, options_y, _T("->"));
				}
			}
			else if (start_y == 260) { //进入EXIT
				EXIT();
			}
			else { //进入STARTgame
				int wait_time = 1000 / my_snake.speed;
				int flag = 0; // 0 alive, 1 body_death, 2 wall_death
				//初始化蛇的长度,头,尾,否则死过一次之后再也不能重新开始
				my_snake.length = 1;
				my_snake.head = 0;
				my_snake.tail = 0;
				setbkcolor(WHITE);
				cleardevice();
				srand(time(NULL));
				food_x = rand() % (my_map.get_size() / 20 - 1) * 20;
				food_y = (rand() - 654) % (my_map.get_size() / 20 - 1) * 20;
				putimage(food_x, food_y, &food);
				while (1) {

					//接收移动指令
					if (peekmessage(&mess, EM_KEY)) {
						flushmessage();
						if (mess.vkcode == VK_UP && my_face != 1) my_face = 0;
						else if (mess.vkcode == VK_DOWN && my_face != 0) my_face = 1;
						else if (mess.vkcode == VK_LEFT && my_face != 3) my_face = 2;
						else if (mess.vkcode == VK_RIGHT && my_face != 2) my_face = 3;
					}
					//如果头部经过食物就重新生成食物坐标,同时保留最后一节作为加长的部分
					if (my_snake.body[my_snake.head].x == food_x && my_snake.body[my_snake.head].y == food_y) {
						int flag=1;//记录食物坐标是否与身体重合,1 重合,0 不重合
						while (flag) {
							flag = 0;
							food_x = rand() % (my_map.get_size() / 20 - 1) * 20;
							food_y = (rand() - 654) % (my_map.get_size() / 20 - 1) * 20;
							for (int i = 0; i < my_snake.length; i++) { //判断食物坐标是否与身体重合,如果重合flag=1
								int temp = (my_snake.tail + i) % SNAKELENGTH;
								if (my_snake.body[temp].x == food_x && my_snake.body[temp].y == food_y) {
									flag = 1;
								}
							}
						}
						putimage(food_x, food_y, &food);
						my_snake.length++; //记录蛇的长度
					}
					else {
						putimage(my_snake.body[my_snake.tail].x, my_snake.body[my_snake.tail].y, &white);//清除最后一节
						my_snake.tail = (my_snake.tail + 1) % SNAKELENGTH; //确定新的尾部
					}
					my_snake.head = (my_snake.head + 1) % SNAKELENGTH; //确定新的头部
					my_snake.body[my_snake.head].y = my_snake.body[(my_snake.head + SNAKELENGTH - 1) % SNAKELENGTH].y;
					my_snake.body[my_snake.head].x = my_snake.body[(my_snake.head + SNAKELENGTH - 1) % SNAKELENGTH].x;
					switch (my_face) { //新的头部坐标
					case 0:my_snake.body[my_snake.head].y -= 20; break;
					case 1:my_snake.body[my_snake.head].y += 20; break;
					case 2:my_snake.body[my_snake.head].x -= 20; break;
					case 3:my_snake.body[my_snake.head].x += 20; break;
					}
					//根据地图规则判断是否可以穿过地图边缘 (在打印新的头部之前,一定!!!!)
					if (my_map.get_rule()) {
						my_snake.body[my_snake.head].x = (my_snake.body[my_snake.head].x + my_map.get_size() ) % (my_map.get_size() );
						my_snake.body[my_snake.head].y = (my_snake.body[my_snake.head].y + my_map.get_size() ) % (my_map.get_size() );
					}
					putimage(my_snake.body[my_snake.head].x, my_snake.body[my_snake.head].y, &my_style); //在新的头部地址打印身体
					for (int i = 0; i < my_snake.length - 1; i++) { //判断死亡
						int temp = my_snake.tail;
						temp = (temp + i) % SNAKELENGTH;
						//撞上自己的身体
						if (my_snake.body[temp].x == my_snake.body[my_snake.head].x && my_snake.body[temp].y == my_snake.body[my_snake.head].y) {
							flag = 1;
						}
					}
					if (my_snake.body[my_snake.head].x<0 || my_snake.body[my_snake.head].x>my_map.get_size()-20 || my_snake.body[my_snake.head].y<0 || my_snake.body[my_snake.head].y>my_map.get_size()-20) {
						flag = 2;
					}
					if (flag) {
						if (flag == 1) outtextxy(my_map.get_size() / 2 - 150, my_map.get_size() / 2, _T("BODY DEATH!"));
						else outtextxy(my_map.get_size() / 2 - 150, my_map.get_size() / 2, _T("WALL DEATH!"));
						flag = 0;
						Sleep(3000);
						break;
					}
					Sleep(wait_time);
				}
			}
		}
		START();
		outtextxy(start_x, start_y, _T("->"));
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值