贪吃蛇(结构体+数组)

zyl 喵星人 2023-06-04 16:08:08 2023-06-05 21:10:23 35
#include<iostream>
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<time.h>

using namespace std;

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

// 地图大小 #define W 40 #define H 40

struct snake{ int x,y; }; // 蛇结构体数组 snake snakes[W*H]; // 蛇的长度, 移动方向 int len = 0; char dir = 'd'; // 食物坐标 int foodx = 0,foody = 0; int FPS = 200; // 分数 速度 int score = 0, speed = (220-FPS)/20;

// 隐藏光标 void HideCursor(){ CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); }

// 设置光标位置 void setPos(int x,int y) { CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hConsoleOut; hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo); csbiInfo.dwCursorPosition.X = x;
csbiInfo.dwCursorPosition.Y = y;
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}

// 带颜色的输出 void COLOR_PRINT(const char* s, int color){ HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color); printf(s); SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7); }

// 游戏结束 bool GameOver(){ // 撞墙 snake t = snakes[0]; if(t.x >= W-1 || t.x <= 0 || t.y >= H-1 || t.y <= 0){ return true; } // 吃到自己 for(int i=3;i<=len-1;i++){ if(t.x == snakes[i].x && t.y == snakes[i].y){ return true; } } return false; }

// 判断食物和蛇身是否重合 bool inSnake(int x, int y){ for(int i=0;i<len;i++){ if(snakes[i].x == x && snakes[i].y == y) return false; } return true; }

// 随机生成食物 void createFood(){ srand(time(NULL)); while(1){ // 1~(W-1) foodx = rand()%(W-2)+1; foody = rand()%(H-2)+1; if(inSnake(foodx,foody)) return; } }

// 初始化 void init(){ // 初始化蛇 len = 4; snakes[0].x = 2; snakes[0].y = 2; for(int i=1;i<len;i++){ snakes[i].x = snakes[i-1].x + 1; snakes[i].y = snakes[i-1].y; } // 初始化食物 createFood(); }

// 游戏提示 void tips(){ setPos(W2+4, 3); printf("游戏说明:\n"); setPos(W2+4, 5); printf("按W A S D 或者 ↑ ↓ ← → 操控游戏\n"); setPos(W2+4, 7); printf("按Q减速,按E加速\n"); setPos(W2+4, 9); printf("当前食物分数:%d\n", 100+10speed); setPos(W2+4, 11); printf("当前速度:%d\n", speed); setPos(W*2+4, 13); printf("总 分:%d\n", score); }

// 画地图 void draw(){ for(int i=0;i<W;i++){ for(int j=0;j<H;j++){ if(i==0 || j==0 || i == W-1 || j == H-1) { setPos(i2,j); printf(""); } } } // 画蛇 for(int i=0;i<len;i++){ setPos(snakes[i].x2,snakes[i].y); // printf("■"); if(i == 0) COLOR_PRINT("", 4); else COLOR_PRINT("", 1); } // 画食物 setPos(foodx*2,foody); // printf("■"); COLOR_PRINT("", 10); // 更新数据信息 FPS = min(FPS, 200); FPS = max(FPS, 60); speed = (220-FPS)/20; tips(); }

// 控制移动 void move(){ int dx = 0, dy = 0; if(dir == 'u') dy = -1; else if(dir == 'd') dy = 1; else if(dir == 'l') dx = -1; else if(dir == 'r') dx = 1; setPos(snakes[len-1].x*2,snakes[len-1].y); printf(" "); for(int i=len-1;i>=1;i--){ snakes[i].x = snakes[i-1].x; snakes[i].y = snakes[i-1].y; } snakes[0].x = snakes[0].x + dx; snakes[0].y = snakes[0].y + dy; }

// 按键响应 void keyDown(){ char key; while(kbhit()) key = _getch(); // 看不见的输入获取 switch(key){ case 'W': case 'w': case 72: if(dir != 'd') dir = 'u'; break; case 'S': case 's': case 80: if(dir != 'u') dir = 'd'; break; case 'A': case 'a': case 75: if(dir != 'r') dir = 'l'; break; case 'D': case 'd': case 77: if(dir != 'l') dir = 'r'; break; case 'E': case 'e': FPS -= 20; break; case 'Q': case 'q': FPS += 20; break; } }

// 吃到食物 void eatFood(){ if(snakes[0].x == foodx && snakes[0].y == foody){ len++; for(int i=len-1;i>=1;i--){ snakes[i].x = snakes[i-1].x; snakes[i].y = snakes[i-1].y; } snakes[0].x = foodx; snakes[0].y = foody; setPos(foodx2,foody); printf(" "); score += 100+speed10; createFood(); } }

int main(){ HideCursor(); // 隐藏光标 init(); // 初始化游戏内容 tips(); while(1){ if(GameOver()) break; // 游戏结束判断 keyDown(); // 键盘按键 move(); // 蛇移动 eatFood(); // 判断是否吃到食物 draw(); // 画出地图和蛇 Sleep(FPS); } setPos((W+1)/2,(H-1)/2); COLOR_PRINT("游戏结束!,您获得了", 4); printf("%d", score); setPos(0,H+2); system("pause"); return 0; }

{{ vote && vote.total.up }}

共 18 条回复

liuser

棒~

Joshua Microsoft

有点抖,而且报错了 修正代码如下:

#include<iostream>
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<time.h>

using namespace std;

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

// 地图大小
#define W 40
#define H 40

struct snake{
	int x,y;
};
// 蛇结构体数组
snake snakes[W*H];
// 蛇的长度, 移动方向
int len = 0;
char dir = 'd';
// 食物坐标
int foodx = 0,foody = 0;
int FPS = 200;
// 分数        速度
int score = 0, speed = (220-FPS)/20;

// 隐藏光标
void HideCursor(){ 
	CONSOLE_CURSOR_INFO cursor_info = {1, 0};
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); 
}

// 设置光标位置
void setPos(int x,int y)  {
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;                            
	HANDLE hConsoleOut;
	hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
	csbiInfo.dwCursorPosition.X = x;                                    
	csbiInfo.dwCursorPosition.Y = y;                                    
	SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}

// 带颜色的输出
void COLOR_PRINT(const char* s, int color){
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
	printf(s);
	SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}

// 游戏结束
bool GameOver(){
	// 撞墙
	snake t = snakes[0];
	if(t.x >= W-1 || t.x <= 0 || t.y >= H-1 || t.y <= 0){
		return true;
	}
	// 吃到自己
	for(int i=3;i<=len-1;i++){
		if(t.x == snakes[i].x && t.y == snakes[i].y){
			return true;
		}
	}
	return false;
}

// 判断食物和蛇身是否重合
bool inSnake(int x, int y){
	for(int i=0;i<len;i++){
		if(snakes[i].x == x && snakes[i].y == y) return false;
	}
	return true;
}

// 随机生成食物
void createFood(){
	srand(time(NULL));
	while(1){
		// 1~(W-1)
		foodx = rand()%(W-2)+1;
		foody = rand()%(H-2)+1;
		if(inSnake(foodx,foody)) return;
	}
}

// 初始化
void init(){
	// 初始化蛇
	len = 4;
	snakes[0].x = 2;
	snakes[0].y = 2;
	for(int i=1;i<len;i++){
		snakes[i].x = snakes[i-1].x + 1;
		snakes[i].y = snakes[i-1].y;
	}
	// 初始化食物
	createFood();
}

// 游戏提示
void tips(){
	setPos(W*2+4, 3);
	printf("游戏说明:\n");
	setPos(W*2+4, 5);
	printf("按W A S D 或者 ↑ ↓ ← → 操控游戏\n");
	setPos(W*2+4, 7);
	printf("按Q减速,按E加速\n");
	setPos(W*2+4, 9);
	printf("当前食物分数:%d\n", 100+10*speed);
	setPos(W*2+4, 11);
	printf("当前速度:%d\n", speed);
	setPos(W*2+4, 13);
	printf("总    分:%d\n", score);
}

// 画地图
void draw(){
	for(int i=0;i<W;i++){
		for(int j=0;j<H;j++){
			if(i==0 || j==0 || i == W-1 || j == H-1) {
				setPos(i*2,j);
				printf("");
			}
		}
	}
	// 画蛇
	for(int i=0;i<len;i++){
		setPos(snakes[i].x*2,snakes[i].y);
		if(i == 0) COLOR_PRINT("", 4);
		else COLOR_PRINT("", 1);
	}
	// 画食物
	setPos(foodx*2,foody);
	COLOR_PRINT("", 10);
	// 更新数据信息
	FPS = min(FPS, 200);
	FPS = max(FPS, 60);
	speed = (220-FPS)/20;
	tips();
}

// 控制移动
void move(){
	int dx = 0, dy = 0;
	if(dir == 'u') dy = -1;
	else if(dir == 'd') dy = 1;
	else if(dir == 'l') dx = -1;
	else if(dir == 'r') dx = 1;
	setPos(snakes[len-1].x*2,snakes[len-1].y);
	printf("  ");
	for(int i=len-1;i>=1;i--){
		snakes[i].x = snakes[i-1].x;
		snakes[i].y = snakes[i-1].y;
	}
	snakes[0].x = snakes[0].x + dx;
	snakes[0].y = snakes[0].y + dy;
	
	setPos(snakes[0].x*2, snakes[0].y);
	COLOR_PRINT("", 4);
}

// 按键响应
void keyDown(){
	char key = ' '; // 给key一个默认值,以防止未初始化的情况发生
	while(kbhit()) key = _getch();  // 看不见的输入获取
	switch(key){
		case 'W':
		case 'w':
		case 72:
			if(dir != 'd') dir = 'u';
			break;
		case 'S':
		case 's':
		case 80:
			if(dir != 'u') dir = 'd';
			break;
		case 'A':
		case 'a':
		case 75:
			if(dir != 'r') dir = 'l';
			break;
		case 'D':
		case 'd':
		case 77:
			if(dir != 'l') dir = 'r';
			break;
		case 'E':
		case 'e':
			FPS -= 20;
			break;
		case 'Q':
		case 'q':
			FPS += 20;
			break;
	} 
} 

// 吃到食物
void eatFood(){
	if(snakes[0].x == foodx && snakes[0].y == foody){
		len++;
		for(int i=len-1;i>=1;i--){
			snakes[i].x = snakes[i-1].x;
			snakes[i].y = snakes[i-1].y;
		}
		snakes[0].x = foodx;
		snakes[0].y = foody;
		setPos(foodx*2,foody);
		printf("  ");
		score += 100+speed*10;
		createFood();
	}
}


int main(){
	HideCursor(); // 隐藏光标
	init();   // 初始化游戏内容
	tips();
	while(1){
		if(GameOver()) break;  // 游戏结束判断
		keyDown();  // 键盘按键
		move();  // 蛇移动
		eatFood(); // 判断是否吃到食物
		Sleep(FPS);
	}
	setPos((W+1)/2,(H-1)/2);
	COLOR_PRINT("游戏结束!,您获得了", 4);
	printf("%d", score);
	setPos(0,H+2);
	system("pause");
	return 0;
} 
qym 山顶洞人

@lixinyan 谁抄袭了他只是重发了 OK?

ykj39 西瓜

建议地图大小调到20到30之间(我不专业但我试过)

outman008

11740分,又望各位编程大佬(bushi贪吃蛇大佬来破

lixinyan 爱因斯坦

抄袭CPP

outman008

贪吃蛇:“我是怎么出生的思密达?” 我:“我看不懂所以我不知道啊思密达。”

csr 陈俊豪-幺爸

6666666666666666666666666666666666666

Even226 逗比

我是来搞笑的,嘻嘻嘻

Even226 逗比

抵制不良游戏,拒绝盗版游戏。 注意自我保护,谨防受骗上当。 适度游戏益脑,沉迷游戏伤身。 合理安排时间,享受健康生活。