资讯详情

ege实现简易版贪吃蛇

文件已经上传 https://download.csdn.net/download/weixin_45755332/85616589

计算机图形学大作业 贪吃蛇

设计思路

画布

首先,画布应该由矩阵的形式组成。 画布可以初始化为0,蛇和食物可以设置为其他值,从而将画布与蛇身和食物分开。

在这里插入图片描述

蛇的移动

现在的蛇身可以加1,然后让蛇尾变成0,蛇头的前一个变成1。例如,当蛇向右移动时,蛇头的右侧变成1,并通过矩阵中的数字变化移动蛇身

碰撞检测

自身碰撞

蛇的身体是非0,如果蛇头遇到非0数字,就会相撞。

与食物碰撞

将食物的位置设成全局变量,如果蛇头的x y位置和食物x y蛇长就是一样的 1.食物自动随机更新。(这里要设置不能更新到蛇身上,只需在矩阵为0的位置更新即可)

和墙的碰撞

判断蛇头x,y值是否超过之前设置的边界。

画布刷新

蛇的长度、蛇和食物的位置都在不断变化,所以要不断刷新画布上的内容,以保持动态显示。

综上所述,考虑程序主体函数。

  • 初始化函数-应包括蛇的位置、颜色、食物的位置等
  • 蛇的移动函数——上下左右移动蛇身
  • 画布显示函数

全局常量和变量

这三个常量是最基本的,用宏定义,程序无法改变

#define BLOCK_SIZE 20 ////每个小格子的长度和宽度 #define HEIGHT 30 // 高度上有30个小格子 #define WIDTH 40 // 共40个小格子宽度 

这些变量不断更新,必须设置为全局变量

int blocks[HEIGHT][WIDTH] = { 
         0 }; // 用于记录蛇身颜色的全0矩阵初始化HSV颜色空间 char move_direction; // 用w a s d控制蛇的移动方向  int food_i, food_j; // 食物的位置 int is_failure = 0; // 游戏失败了吗? 

初始化函数

先初始化画布,再初始化蛇身

void start_up() { 
        // 程序初始化函数   // 初始画布大小,蛇身大小乘长宽,即宽度可放30个蛇身,高度可放40个蛇身  initgraph(WIDTH*BLOCK_SIZE, HEIGHT*BLOCK_SIZE);  randomize(); // 初始化随机数发生器  setcolor(EGERGB(200, 200, 200)); // 设置默认背景颜色
	setrendermode(RENDER_MANUAL);  // 设置为非自动刷新 (只有delay/delay_fps/getch 才刷新屏幕) 
	
	blocks[HEIGHT / 2][WIDTH / 2] = 1; //在画面正中间画蛇头
	for (int i = 1; i <= 4; i++) { 
         // 从正中间向左依次4个方块,数值依次为2,3,4,5 
		blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;
	}
	move_direction = 'd'; // 初始向右移动
	
	food_i = random(HEIGHT - 1) ; // 随机初始化食物位置
	food_j = random(WIDTH - 1);
}

展示函数

蛇的长度,蛇和食物的位置都是时刻变化的,所以要不断刷新画布上的内容,必须不断调用这个函数

//绘制函数 
void show() { 
         
	color_t color;
	cleardevice(); // 绘制下一帧时要将上一帧的内容清屏
	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (blocks[i][j]) { 
        
				// 如果矩阵该位置数值大于0 将HSV颜色空间转化为RGB形式来展示蛇身颜色
				color = HSVtoRGB(blocks[i][j] * 10, 0.8, 1);
			}
			else { 
        
				// 普通格子 
				color = EGERGB(150, 150, 150);
			}
					// 不同填充不同的颜色
			setfillcolor(color);
			//i是行(y),j是列(x),双重for循环就都填充了
			bar(j*BLOCK_SIZE, i*BLOCK_SIZE, (j + 1)*BLOCK_SIZE, (i + 1)*BLOCK_SIZE);
		}
	}
	// 食物默认颜色为绿色GREEN
	setfillcolor(GREEN);
	// 食物位置为全局变量,在更新蛇的长度和位置时,食物位置也随之更新
	bar(food_j*BLOCK_SIZE, food_i*BLOCK_SIZE, (food_j + 1)*BLOCK_SIZE, (food_i + 1)*BLOCK_SIZE);
	// 如果游戏失败就展示失败,is_failure是在其他函数传值过来的
	if (is_failure) { 
        
		setcolor(RED);
		setfont(80, 0, "宋体");
		xyprintf(240, 220, "GAME OVER");
	}
}

HSV和RGB两种颜色表示的联系

RGB 是我们接触最多的颜色空间,由三个通道表示一幅图像,分别为红色®,绿色(G)和蓝色(B)。这三种颜色的不同组合可以形成几乎所有的其他颜色。

在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。 HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相)
  • Saturation(饱和度、色彩纯净度)
  • Value(明度)

蛇的移动

// 移动小蛇及相关处理函数
void move_snake() { 
        
	/*移动蛇,可以将矩阵中所有非0数的位置都加1,蛇头的向哪移动, 蛇头的前一个位置元素就变成1, 最后一个元素变成0*/
	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (blocks[i][j] > 0)  // 是小蛇身体
				blocks[i][j]++;
		}
	}
	 // 标记旧蛇头、蛇尾坐标
	int old_head_i, old_head_j, old_tail_i, old_tail_j; 
	// 
	int max = 0;
	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (max < blocks[i][j]) { 
         //旧蛇头位置的值最大 
				max = blocks[i][j];
				old_tail_i = i;
				old_tail_j = j;
			}
			if (2 == blocks[i][j]) { 
         //旧蛇头位置的值为2 
				old_head_i = i;
				old_head_j = j;
			}
		}
	}

	int new_head_i = old_head_i; //新蛇头位置
	int new_head_j = old_head_j;

	switch (move_direction) { 
        
	case 'w': // 向上移动
		new_head_i = old_head_i - 1;
		break;
	case 's': //向下移动 
		new_head_i = old_head_i + 1;
		break;
	case 'a': //向左移动
		new_head_j = old_head_j - 1;
		break;
	case 'd': //向右移动
		new_head_j = old_head_j + 1;
		break;
	}

	// 如果蛇头超出边界,或者碰到蛇身,游戏失败
	if ((new_head_i >= HEIGHT) || (new_head_i < 0)
		|| (new_head_j >= WIDTH) || (new_head_j < 0)
		|| (blocks[new_head_i][new_head_j] > 0)) { 
        
		is_failure = 1; //游戏失败
		return;
	}

	blocks[new_head_i][new_head_j] = 1; //新蛇头位置数值为1
	if ((new_head_i == food_i) && (new_head_j == food_j)) { 
        
		//如果新蛇头正好碰到食物
		food_i = random(HEIGHT - 5) + 2; //重新随机食物位置 
		food_j = random(WIDTH - 5) + 2;
		//不对旧蛇尾处理,相当于蛇的长度+1 
	}
	else { 
        
		//没有碰到食物
		blocks[old_tail_i][old_tail_j] = 0;
	}
}
#include <graphics.h>
#define BLOCK_SIZE 20 //每个小格子的长宽大小
#define HEIGHT 30 // 高度上一共30个小格子
#define WIDTH 40 // 宽度上一共40个小格子

//全局变量定义
int blocks[HEIGHT][WIDTH] = { 
         0 }; // 初始化一个全0的矩阵,用来记录蛇身体的颜色,这里用HSV颜色空间
char move_direction; // 用w a s d控制小蛇移动方向 
int food_i, food_j; // 食物的位置
int is_failure = 0; // 是否游戏失败


// 移动小蛇及相关处理函数
void move_snake() { 
        
	/*移动蛇,可以将矩阵中所有非0数的位置都加1,蛇头的前一个位置元素变成1,最后一个元素变成0 */
	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (blocks[i][j] > 0)  // 是小蛇身体
				blocks[i][j]++;
		}
	}

	int old_head_i, old_head_j, old_tail_i, old_tail_j;  // 旧蛇头、蛇尾坐标

	int max = 0;

	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (max < blocks[i][j]) { 
         //旧蛇头位置的值最大 
				max = blocks[i][j];
				old_tail_i = i;
				old_tail_j = j;
			}
			if (2 == blocks[i][j]) { 
         //旧蛇头位置的值为2 
				old_head_i = i;
				old_head_j = j;
			}
		}
	}

	int new_head_i = old_head_i; //新蛇头位置
	int new_head_j = old_head_j;

	switch (move_direction) { 
        
	case 'w': // 向上移动
		new_head_i = old_head_i - 1;
		break;
	case 's': //向下移动 
		new_head_i = old_head_i + 1;
		break;
	case 'a': //向左移动
		new_head_j = old_head_j - 1;
		break;
	case 'd': //向右移动
		new_head_j = old_head_j + 1;
		break;
	}

	// 如果蛇头超出边界,或者碰到蛇身,游戏失败
	if ((new_head_i >= HEIGHT) || (new_head_i < 0)
		|| (new_head_j >= WIDTH) || (new_head_j < 0)
		|| (blocks[new_head_i][new_head_j] > 0)) { 
        
		is_failure = 1; //游戏失败
		return;
	}

	blocks[new_head_i][new_head_j] = 1; //新蛇头位置数值为1
	if ((new_head_i == food_i) && (new_head_j == food_j)) { 
        
		//如果新蛇头正好碰到食物
		food_i = random(HEIGHT - 5) + 2; //重新随机食物位置 
		food_j = random(WIDTH - 5) + 2;
		//不对旧蛇尾处理,相当于蛇的长度+1 
	}
	else { 
        
		//没有碰到食物
		blocks[old_tail_i][old_tail_j] = 0;
	}
}

void start_up() { 
        // 程序初始化函数 
	// 初始化画布大小
	initgraph(WIDTH*BLOCK_SIZE, HEIGHT*BLOCK_SIZE);
	randomize(); //初始化随机数发生器
	setcolor(EGERGB(200, 200, 200));// 设置默认背景颜色
	setrendermode(RENDER_MANUAL); //设置为非自动刷新 (只有delay/delay_fps/getch 才刷新屏幕) 
	
	blocks[HEIGHT / 2][WIDTH / 2] = 1; //画面中间画蛇头
	for (int i = 1; i <= 4; i++) { 
         // 向左依次4个方块,数值依次为2,3,4,5 
		blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;
	}
	move_direction = 'd'; // 初始向右移动
	food_i = random(HEIGHT - 1) ; // 随机初始化食物位置
	food_j = random(WIDTH - 1);
}

void show() { 
         //绘制函数 
	color_t color;
	cleardevice();// 清屏

	for (int i = 0; i < HEIGHT; i++) { 
        
		for (int j = 0; j < WIDTH; j++) { 
        
			if (blocks[i][j]) { 
        
				// 蛇身颜色,将HSV颜色空间转化为RGB形式
				color = HSVtoRGB(blocks[i][j] * 10, 0.8, 1);
			}
			else { 
        
				//普通格子 
				color = EGERGB(150, 150, 150);
			}
			setfillcolor(color);
			//i是行(y),j是列(x) 
			bar(j*BLOCK_SIZE, i*BLOCK_SIZE, (j + 1)*BLOCK_SIZE, (i + 1)*BLOCK_SIZE);
		}
	}
	// 食物
	setfillcolor(GREEN);
	bar(food_j*BLOCK_SIZE, food_i*BLOCK_SIZE, (food_j + 1)*BLOCK_SIZE, (food_i + 1)*BLOCK_SIZE);
	if (is_failure) { 
        
		//如果游戏失败
		setcolor(RED);
		setfont(80, 0, "宋体");
		xyprintf(240, 220, "GAME OVER");
	}
}

//与输入无关的更新函数
void update_without_input() { 
        
	// 如果游戏失败,返回
	if (is_failure)
		return;
	static int wait_index = 1;
	wait_index++;

	if (wait_index == 10) { 
         //每10帧 执行一次,用这个控制小蛇移动速度 
		move_snake();
		wait_index = 1;
	}
}

void update_with_input() { 
        
	if (kbhit()) { 
        
		char input = getch();
		switch (input) { 
        
		case 'w':
		case 'd':
		case 's':
		case 'a':
			move_direction = input;
		}
	}
}

int main() { 
        
	start_up();
	while (is_run()) { 
        
		show();
		update_without_input();
		update_with_input();
		delay_fps(60);
	}
	closegraph();
	return 0;
}

标签: ege红外传感器p60074

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司