【51项目】51单片机自制小霸王游戏机

视频演示效果:

纳新作品——小霸王游戏机

目录:

目录

视频演示效果:

目录:

前言:

一、连接方式:

1.1 控制引脚

1.2. 显示模块

1.3. 定时器

1.4. 游戏逻辑与硬件结合

1.5. 中断处理

二、源码分析:

2.1. 全局变量与常量定义

2.2. 游戏初始化函数

2.3. 游戏状态与逻辑

2.4. 辅助功能

2.5. 显示与输入

2.6. 中断处理

2.7. 主函数

2.8. 源码整合:

完整工程源码获取方式:


前言:

51单片机自制小霸王游戏机不仅是一个充满乐趣的DIY项目,而且蕴含了深刻的教育和技术意义。通过这一过程,可以加深对嵌入式系统原理的理解,锻炼实践操作能力,同时也是一种对经典电子游戏文化的致敬和传承

首先,这一项目使得制作者能够深入理解51单片机的内部结构和工作原理。51单片机作为一种基础的微控制器,其编程和硬件接口设计对于电子工程的学习者来说是基础且关键的。在自制游戏机的实践中,制作者需要对51单片机的I/O端口、定时器、中断系统等有深入的了解和运用,这有助于提升对微控制器应用的熟练度。

其次,自制小霸王游戏机的过程是对电子电路设计能力的考验和提升。从电路板的布局设计到元件的选择,再到焊接和调试,每一步都需要精细的操作和严谨的思考。这不仅能够锻炼动手能力,还能培养解决实际问题的能力。

此外,该项目具有浓厚的文化意义。小霸王游戏机是许多80后甚至70后的童年记忆,通过自制游戏机,可以体验复古游戏带来的乐趣,同时也是对那个时代电子游戏文化的一种纪念和传承。

这一项目能够激发创新思维和独立解决问题的能力。在制作过程中,可能会遇到各种预料之外的挑战,比如如何优化电路设计以减小体积,如何编写更高效的代码来提升游戏性能,如何使游戏机界面更友好等。这些问题的解决,都需要制作者发挥创新思维,寻找最佳解决方案。

最后,自制小霸王游戏机也是一种良好的技术交流方式。制作者可以将自己的设计分享给他人,通过社区交流获取反馈和建议,从而不断提升自己的技术水平,同时也促进了技术爱好者和同行之间的交流与合作。

一、连接方式:

1.1 控制引脚

  • P2口:用于控制方向和确认操作。

    • 0x04: 表示向上移动。
    • 0x10: 表示向下移动。
    • 0x01: 表示向左移动。
    • 0x40: 表示向右移动。
    • 0x80: 表示确认操作。
  • P3口:用于控制蜂鸣器。

    • P3^7 (loud): 控制蜂鸣器的开关状态。
  • P0口:用于检测键盘输入,具体检测到哪个键由P0的值决定。

    • P0=0xf7: 检测第一列键盘输入。
    • P0=0xfb: 检测第二列键盘输入。
    • P0=0xfd: 检测第三列键盘输入。
    • P0=0xfe: 检测第四列键盘输入。

1.2. 显示模块

相关接口

  • LCD接口:用于显示游戏信息和状态。
    • 涉及到LCD的初始化、位置设置、数据写入等操作。
    • wr_i_lcd 和 wr_d_lcd 函数用于写入指令和数据到LCD。

该代码主要涉及对 LCD 的控制,LCD 通常通过多个引脚与微控制器连接。在本代码中,使用了一些特定的控制信号:

  • RS (Register Select):选择寄存器信号,用于选择指令寄存器或数据寄存器。rs=0表示指令寄存器,rs=1表示数据寄存器。

  • RW (Read/Write):读写控制信号。rw=0表示写操作,rw=1表示读操作。

  • E (Enable):使能信号。LCD 在 E 由高变低的瞬间捕获数据。

  • busy_lcd():检查 LCD 的忙碌状态,确保在其准备好之前不会发送新的指令或数据。

 数据线

  • lcddata:用于发送指令或数据到 LCD 的数据线。在特定指令下,将数据或命令传递给 LCD。

 电路接口功能

  • 延时函数 (delaynms):用于产生精确的时间延迟,以满足 LCD 的指令和数据处理的时间要求。通过软件延时的方式确保 LCD 在指令或数据写入后有充足的时间来完成操作。

  • 初始化函数 (init_lcd):对 LCD 进行初始化设置,包括配置 LCD 的指令集、显示控制和清屏等操作。

  • 图像处理函数 (img_disp, lcd_set_dot, clear_pic):这些函数用于在 LCD 上绘制图像或图形,通过操控特定的寄存器和位来改变显示内容。

硬件连接

  • 接口引脚:通常 LCD 与微控制器之间会有多个 GPIO 口连接,上述信号(RS, RW, E, lcddata)都需要连接到微控制器的相应引脚。

  • 电源与接地:LCD 显示屏需要连接合适的电源和接地,以确保稳定工作。

工作原理

  • 指令与数据传输:通过上述信号的组合,微控制器可以发送不同的命令和数据到 LCD,实现各种显示效果。

  • 忙碌检测:在执行新的指令或写入数据之前,通过 busy_lcd() 检测 LCD 的忙碌状态,以防止由于过快的指令发送导致的数据丢失或指令失效。

1.3. 定时器

  • 定时器设置
    • 使用定时器(如T1)来产生随机数,用于游戏逻辑中的随机生成(如食物位置的随机生成)。
    • TH1 和 TL1 分别用于设置定时器高位和低位。

1.4. 游戏逻辑与硬件结合

  • 游戏状态:通过变量flag来控制不同的游戏状态,如贪吃蛇、飞机大战等。
  • 随机数生成:利用定时器的计数值来随机生成游戏中的元素位置。

1.5. 中断处理

  • 中断服务程序:负责处理按键输入。
    • 对应的中断例程负责检测按键输入,并根据输入修改游戏状态或控制动作(如改变方向、选择菜单选项等)。

电路接口主要包括按键检测、LCD显示、蜂鸣器控制等部分。通过这些硬件接口,代码实现了一个简单的游戏控制系统。每个硬件接口的功能都通过相应的端口和位定义清晰地映射到特定的操作上,如移动、选择、确认等。

二、源码分析:

2.1. 全局变量与常量定义

代码开头定义了一些全局变量和常量,用于控制游戏的状态和行为。

  • 字符串常量:用于显示在 LCD 上的不同游戏名称和提示信息,如 namegame1loser 等。
  • 全局变量:如 ppxlengthflagslect 等,这些变量用于控制菜单选择、游戏状态、长度计数等。
  • 硬件接口loud 是一个特殊位(sbit),用于控制蜂鸣器的开关。
#include "includes.h"
#include "intrins.h"
#include "stdlib.h"

/*fx=0 ÓÒ 
  fx=1 ×ó
  fx=2 ÉÏ
  fx=3 ÏÂ*/
/*P2 ÉÏ 0x04 ÏÂ 0x10 ×ó 0x01 ÓÒ 0x40 È·ÈÏ 0x80 */ 
uchar code name[]={"С°ÔÍõÓÎÏ·»ú"};
uchar code game1[]={"Ì°³ÔÉß"};
uchar code game2[]={"´òµØÊó"};
uchar code game3[]={"·É»ú´óÕ½"};
uchar code game4[]={"ͼƬ"};
uchar code loser[]={"ÄãÊäÁË"};
uchar code lxy1[]={"¼ÌÐø"};
uchar code lxy2[]={"·µ»Ø"};
uchar code cj[]={"³¤¶È: "};
uchar code fjs[]={"·É»ú: "};
char code  mouse[]={"ÀÏÊó: "};
uchar p=1,px=1;
uchar length=9;	
uchar flag=0,slect=0,choose=0;
uchar ran1,ran2,food=0;
uchar planex[3]={28,30,0};
uchar zidan_x[10]={0},zidan_y[10]={0};
uchar boom_x[10]={0},boom_y[10]={0};
char dishu=0;
sbit loud=P3^7;					
struct xx
{
    char x[22];
	char y[22];
	char head;
	char tail;
	char dir;
}snake;

 

2.2. 游戏初始化函数

  • snake_init():初始化贪吃蛇游戏的状态,在 LCD 上绘制初始蛇的形状,并设置蛇的坐标、头尾指针和方向。
void snake_init(void)
{
   lcd_set_dot(1,1,0);
   lcd_set_dot(2,1,0);
   lcd_set_dot(3,1,0);
   lcd_set_dot(4,1,0);
   lcd_set_dot(5,1,0);
   lcd_set_dot(6,1,0);
   snake.x[0]=1;snake.y[0]=1;
   snake.x[1]=2;snake.y[1]=1;
   snake.x[2]=3;snake.y[2]=1;
   snake.x[3]=4;snake.y[3]=1;
   snake.x[4]=5;snake.y[4]=1;
   snake.x[5]=6;snake.y[5]=1;
   snake.head=5;
   snake.tail=0;
   snake.dir=0;	
}

2.3. 游戏状态与逻辑

  • die():处理游戏失败的情况,显示失败信息并等待用户选择继续或返回。
  • cata():菜单选择功能,显示可选游戏列表,并根据用户输入更新选择。
  • game_snake():贪吃蛇游戏的核心逻辑,包括蛇的移动、食物生成、碰撞检测等。
  • game_plane():飞机大战游戏的逻辑,处理子弹和敌机的碰撞、飞机的移动等。
  • game_mouse():打地鼠游戏逻辑,随机生成地鼠位置,并检测玩家是否成功击中。
void die(void)
{
	uchar i;
	loud=0;
	flag=5;
	clear_pic();
	wr_i_lcd(0x30);
	wr_i_lcd(0x01);
	i=0;
	lcd_pos(0,2);
	while(loser[i]!='\0')
	{
		wr_d_lcd(loser[i]);
		i++;
	}
	i=0;
	lcd_pos(2,0); 
	while(lxy1[i]!='\0')
	{
		wr_d_lcd(lxy1[i]);
		i++;	
	}
	i=0;
	lcd_pos(2,5); 
	while(lxy2[i]!='\0')
	{
		wr_d_lcd(lxy2[i]);
		i++;	
	}
	lcd_pos(3,0); wr_d_lcd('o');
	delay(1000);
	loud=1;
	while(flag==5);	
}
uchar cata(void)
{
	uchar i;
	i=0;
	slect=0;
	lcd_pos(0,0);
	wr_d_lcd('o');
	lcd_pos(0,1);
	while(game1[i]!='\0')
	{
		 wr_d_lcd(game1[i]);
		 i++;
	}
	lcd_pos(1,1);
	i=0;
	while(game3[i]!='\0')
	{
		 wr_d_lcd(game2[i]);
		 i++;
	}
	lcd_pos(2,1);
	i=0;
	while(game3[i]!='\0')
	{
		 wr_d_lcd(game3[i]);
		 i++;
	}
	lcd_pos(3,1);
	i=0;
	while(game4[i]!='\0')
	{
		 wr_d_lcd(game4[i]);
		 i++;
	}
	while(flag==0);	
}
void game_snake(void)
{
	uchar i,k,j;
	k=0;
	food=0;
	length=6;
	lcd_pos(3,0);
		i=0;
		while(cj[i]!='\0')
		{
		 	wr_d_lcd(cj[i]);
			i++;	
		}
		wr_d_lcd(length+48);
		while(1)
	   {
	   		if(food==0)
			{
				
				while(1)//·ÀÖ¹²úÉúµÄʳÎï³öÏÖÔÚÉß×Ô¼ºÉíÉÏ
				{
					ran1=TH1%59+1;
					ran2=TL1%30+1;
					food=1;
					i=snake.tail;
					while(i!=snake.head)
					{
						if(snake.x[i]==ran1&&snake.y[i]==ran2)
						{
							break;
						}
						i++;
						if(i==22) i=0;
						if(i==snake.head)
						{
							if(snake.x[i]==ran1&&snake.y[i]==ran2)
							{
								i=snake.head-1;
								break;
							}
						}	
					}
					if(i==snake.head) break;	
				}
				lcd_set_dot(ran1,ran2,0);
			}
			i=snake.tail;
			while(i!=snake.head)//ÉßÒ§µ½×Ô¼º
			{
				if(snake.x[i]==snake.x[snake.head]&&snake.y[i]==snake.y[snake.head])
				{
					die();	
					break;	
				}
				i++;
				if(i==22) i=0;
			}
			if(i!=snake.head) break;
			if(snake.x[snake.head] >= 60 || snake.y[snake.head] >= 30 ||snake.x[snake.head] == 0 ||snake.y[snake.head] == 0) //ÉßÅöǽ
			{
				die();	
				break;	
			}
	   		snake.head++;
			if(snake.head==22)
			{
				snake.head=0;
				if(snake.dir==0)	 //ÓÒ
				{
					snake.x[snake.head]=snake.x[21]+1;
					snake.y[snake.head]=snake.y[21];	
				}
				else if(snake.dir==1)  //×ó
				{
					snake.x[snake.head]=snake.x[21]-1;
					snake.y[snake.head]=snake.y[21];	
				}
				else if(snake.dir==2) //ÏÂ
				{		
					snake.x[snake.head]=snake.x[21];
					snake.y[snake.head]=snake.y[21]+1;
				}
				else if(snake.dir==3) //ÉÏ
				{
					snake.x[snake.head]=snake.x[21];
					snake.y[snake.head]=snake.y[21]-1;	
				}	
			}
			else
			{
				if(snake.dir==0)
				{
					snake.x[snake.head]=snake.x[snake.head-1]+1;
					snake.y[snake.head]=snake.y[snake.head-1];	
				}
				else if(snake.dir==1)
				{
					snake.x[snake.head]=snake.x[snake.head-1]-1;
					snake.y[snake.head]=snake.y[snake.head-1];	
				}
				else if(snake.dir==2)
				{
	   				snake.x[snake.head]=snake.x[snake.head-1];
					snake.y[snake.head]=snake.y[snake.head-1]+1;
				}
				else if(snake.dir==3)
				{
	   				snake.x[snake.head]=snake.x[snake.head-1];
					snake.y[snake.head]=snake.y[snake.head-1]-1;
				}
			}
			lcd_set_dot(snake.x[snake.head],snake.y[snake.head],0);
			if(snake.x[snake.head]!=ran1 || snake.y[snake.head]!=ran2)//Éßû³Ôµ½Ê³Îï
			{
				
				lcd_set_dot(snake.x[snake.tail],snake.y[snake.tail],1);
				snake.tail++;
				if(snake.tail==22) snake.tail=0;
			}
			else  //Éß³Ôµ½Ê³Îï
			{
				if(k<90) k+=10;
				loud=0;
				length++;
				wr_i_lcd(0x30);
			//	wr_i_lcd(0x01);
				lcd_pos(3,3);
				wr_d_lcd(length/10+48);
				wr_d_lcd(length%10+48);
				food=0;
			}
			for(i=0;i<100;i++)
				for(j=0;j<100-k;j++) 
					time_1ms(1000);
			
			loud=1;	
   		}	
}

2.4. 辅助功能

  • plane_init():初始化飞机的位置和状态。
  • back_ground():绘制游戏背景,比如边界和初始分数。
  • picture():显示图片的功能,通过选择不同的图片页来更新显示内容。
  • mouse_back():初始化打地鼠游戏的背景。
void plane_init(void)
{
	uchar i;
	lcd_set_dot(29,29,0);
	lcd_set_dot(28,30,0);
	lcd_set_dot(30,30,0);
	lcd_set_dot(29,30,0);
	for(i=0;i<10;i++)
	{
		zidan_x[i]=0;
		zidan_y[i]=0;
		boom_x[i]=0;
		boom_y[i]=0;	
	}
	planex[0]=28;	
	planex[1]=30;
}

void back_ground(void)
{
	uchar i;
	clear_pic();
	wr_i_lcd(0x30);
	wr_i_lcd(0x01);
	for(i=0;i<=60;i++)
	{ 
		lcd_set_dot(i,0,0);
		lcd_set_dot(i,31,0);	
	}
	for(i=0;i<=32;i++)
	{
		lcd_set_dot(0,i,0);
		lcd_set_dot(60,i,0);	
	}
	if(flag==3)
	{
		lcd_pos(3,0);
		i=0;
		while(fjs[i]!='\0')
		{
			wr_d_lcd(fjs[i]);
			i++;
		}
		wr_d_lcd(length+48);
	}		
}
void game_plane(void)
{
	uchar i,t=0,j=0;
	while(1)
	{
		i=0;
		while(i<10)
		{
			j=0;
			while(j<10)
			{
				if(((zidan_x[i])==boom_x[j]) && ((zidan_y[i]-1==boom_y[j]) || (zidan_y[i]==boom_y[j])) && (zidan_x[i]!=0) && (zidan_y[i] != 0))
				{
					lcd_set_dot(zidan_x[i],zidan_y[i],1);
					lcd_set_dot(boom_x[j],boom_y[j],1);
					zidan_y[i]=0;
					zidan_x[i]=0;
					boom_x[j]=0;
					boom_y[j]=0;
					wr_i_lcd(0x30);
					length++;
					lcd_pos(3,3);
					if(length<10) wr_d_lcd(length+48);
					else
					{
						wr_d_lcd(length/10+48);
						wr_d_lcd(length%10+48);
					}
				} 
				j++;
			}
			i++;
		}
		i=0;
		while(i<10)
		{
			j=0;
			while(j<10)
			{
				if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0))
				{
					lcd_set_dot(zidan_x[i],zidan_y[i],1);
					lcd_set_dot(boom_x[j],boom_y[j],1);
					zidan_y[i]=0;
					zidan_x[i]=0;
					boom_x[j]=0;
					boom_y[j]=0;
				} 
				j++;
			}
			if((boom_x[i] ==planex[0]&& boom_y[i] ==29) || (boom_x[i] ==planex[1]&& boom_y[i] ==29) || ((boom_x[i] ==(planex[1]+planex[0])/2) && boom_y[i] ==29) )
			{
				die();
				break;	
			}
			i++;
		}
		if(i!=10) break;
		i=0;
		t++;
		ran2=TL1%59;
		while(i<10)
		{
			if(zidan_x[i]!=0)
			{
				if(zidan_y[i]==1)
				{
					lcd_set_dot(zidan_x[i],zidan_y[i],1);
					zidan_y[i]=0;
					zidan_x[i]=0;
				}
				else
				{ 
					lcd_set_dot(zidan_x[i],zidan_y[i],1); busy_lcd();
					zidan_y[i]--;
					lcd_set_dot(zidan_x[i],zidan_y[i],0);
				}	
			}				   
			i++;
		}
		
		i=0;
		while(boom_x[i]!=0) i++;
		if(t==4)
		{
			t=0;
			boom_x[i]=ran2+1;
			boom_y[i]=1;
		}
		i=0;
		while(i<10)
		{
			if(boom_x[i]!=0)
			{
				if(boom_y[i]==30)
				{
					lcd_set_dot(boom_x[i],boom_y[i],1);
					boom_y[i]=0;
					boom_x[i]=0;		
				}
				else
				{ 
					lcd_set_dot(boom_x[i],boom_y[i],1); busy_lcd();
					boom_y[i]++;
					lcd_set_dot(boom_x[i],boom_y[i],0); 
				}
			}
			i++;
		}			
		for(i=0;i<200;i++)
				for(j=0;j<50;j++)
				{ 
				//	if(i==70) loud=1;
					time_1ms(1000);
				} 	
	}	
}
void picture(void)
{
	img_disp(tab1);
	while(1)
	{
		if(p!=px)
		{
			if(px==4)
			{
				flag=0;
				break;
			}
			clear_pic();
			p=px;
			if(p==1) img_disp(tab1);
		//	else if(p==2) img_disp(tab1); 
			else if(p==2) img_disp(tab3); 
			
		}	   
	}
}
void mouse_back(void)
{
	char i,j;
	clear_pic();
	wr_i_lcd(0x30);
	wr_i_lcd(0x01);	
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			lcd_pos(i,j);
			wr_d_lcd('o');	
		}
	i=0;
	lcd_pos(1,4);
	while(mouse[i]!='\0')
	{
		wr_d_lcd(mouse[i]);
		i++;		
	}
	wr_d_lcd(length+48);
}

 

2.5. 显示与输入

  • lcd_pos():设置 LCD 的显示位置,用于更新屏幕上的字符位置。
  • lcd_set_dot():在特定坐标设置点,用于绘制图形或游戏元素。
  • clear_pic():清除屏幕内容,为下一次显示做好准备。
void game_mouse(void)
{
	uchar i,j,k;
	k=0;
	length=0;
	while(1)
	{
		ran1=TH1%4;
		ran2=TL1%4;
		lcd_pos(ran1,ran2);
		wr_d_lcd(0x02);
		dishu=1;
		loud=0;
		for(i=0;i<200;i++)
				for(j=0;j<200-k;j++)
				{ 
					if(i==70) loud=1;
					time_1ms(1000);
				}
		if(k<150) k+=10;
		if(dishu==1)
		{
			die();	
			break;
		}
		
		lcd_pos(1,7); 
		length++;
		if(length<10) wr_d_lcd(length+48);
		else
		{
			wr_d_lcd(length/10+48); wr_d_lcd(length%10+48);	
		}
		lcd_pos(ran1,ran2);
		wr_d_lcd('o');
	}
}

 

2.6. 中断处理

  • T0_():中断服务程序,用于处理按键输入,根据按键的不同改变游戏状态或控制游戏行为。包括方向键和确认键的处理。
void T0_() interrupt 3
{
	/*P2 ÉÏ 0x04 ÏÂ 0x10 ×ó 0x01 ÓÒ 0x40 È·ÈÏ 0x80 */
	uchar temp,i,j;
	if(flag==1||flag==2)
	{
		TH1=(65536-30000)/256;
		TL1=(65536-30000)%256;
	}
	else
	{
		TH1=(65536-200)/256;
		TL1=(65536-200)%256;	
	}
	P2=0x00;
	temp=P2;
	if(temp!=0x00)
	{
		time_1ms(20);
		if(temp!=0x00)
		{	
			switch(temp)
			{
				case 0x04:
				{
					loud=0;
					 if(flag==0)
					 {
					 	lcd_pos(slect,0);
					 	wr_d_lcd(' ');
						if(slect==0) slect==3;
						else slect--;
						lcd_pos(slect,0);
					 	wr_d_lcd('o');
						while(P2!=0x00);
						time_1ms(50);	
					 } 
					 else if(flag==1)
							 if(snake.dir!=2) snake.dir=3;
					loud=1;
				}break;
				case 0x10:
				{

					loud=0;
					if(flag==0)
					{
						
						lcd_pos(slect,0);
					 	wr_d_lcd(' ');
						if(slect==3) slect==0;
						else slect++;
						lcd_pos(slect,0);
					 	wr_d_lcd('o');
						while(P2!=0x00);
						time_1ms(20);
					}
					 else if(flag==1)
				 		if(snake.dir!=3) snake.dir=2;
				 loud=1;
				}break; 
				case 0x01:
				{
					loud=0;
					if(flag==5)
					{
						if(choose != 0)
						{
							lcd_pos(3,0);
							wr_d_lcd('o');
							lcd_pos(3,6);
							wr_d_lcd(' ');
							choose=0;
							while(P2!=0x00);
							time_1ms(20);	
						}	
					} 
					 else if(flag==1)
					 {
						if(snake.dir!=0) snake.dir=1;
					}
				   	 else if(flag==3)
					 {
					 	if(planex[0]>1) 
						{
								
							planex[0]--;
							planex[1]--;
							lcd_set_dot(planex[0],30,0); busy_lcd();
							if((planex[0]-1)!=0) lcd_set_dot(planex[0]-1,30,1); busy_lcd();
							lcd_set_dot(planex[1],30,0);  busy_lcd();
							if((planex[1]+1)!=113) lcd_set_dot(planex[1]+1,30,1); busy_lcd();
							lcd_set_dot((planex[0]+planex[1])/2,29,0); busy_lcd();
							lcd_set_dot((planex[0]+planex[1])/2+1,29,1); busy_lcd();
							while(P2!=0x00)
							{
								i=0;
								while(i<10)
								{
									j=0;
									while(j<10)
									{
										if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0))
										{
											lcd_set_dot(zidan_x[i],zidan_y[i],1);
											lcd_set_dot(boom_x[j],boom_y[j],1);
											zidan_y[i]=0;
											zidan_x[i]=0;
											boom_x[j]=0;
											boom_y[j]=0;
											wr_i_lcd(0x30);
											length++;
											lcd_pos(3,3);
											if(length<10) wr_d_lcd(length+48);
											else
											{
												wr_d_lcd(length/10+48);
												wr_d_lcd(length%10+48);
											}
										} 
										j++;
									}
									i++;
								}	
							}
							time_1ms(20);
							
						} 
					}
					else if(flag==4)
					{
						if(px>1) px--;
						else if(px==1) px=2;
						while(P2!=0x00);
						time_1ms(20);
					}
					loud=1;		
				}break; 
				case 0x40:
				{
					loud=0;
					if(flag==5)
					{
						if(choose != 1)
						{
							lcd_pos(3,6);
							wr_d_lcd('o');
							lcd_pos(3,0);
							wr_d_lcd(' ');
							choose=1;
							while(P2!=0x00);
							time_1ms(20);	
						}	
					} 
					 else if(flag==1)
					 {
						if(snake.dir!=1) snake.dir=0;
					}
					 else if(flag==3)
					 {
					 	if(planex[1]<59)
						{
												
							planex[1]++;
							planex[0]++;
							lcd_set_dot(planex[0],30,0); busy_lcd();
							if((planex[0]-1)!=0) lcd_set_dot(planex[0]-1,30,1); busy_lcd();
							lcd_set_dot(planex[1],30,0);  busy_lcd();
							if((planex[1]+1)!=60) lcd_set_dot(planex[1]+1,30,1); busy_lcd();
							lcd_set_dot((planex[0]+planex[1])/2,29,0); busy_lcd();
							lcd_set_dot((planex[0]+planex[1])/2-1,29,1); busy_lcd();
							while(P2!=0x00)
							{
								i=0;
								while(i<10)
								{
									j=0;
									while(j<10)
									{
										if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0))
										{
											lcd_set_dot(zidan_x[i],zidan_y[i],1);
											lcd_set_dot(boom_x[j],boom_y[j],1);
											zidan_y[i]=0;
											zidan_x[i]=0;
											boom_x[j]=0;
											boom_y[j]=0;
											wr_i_lcd(0x30);
											length++;
											lcd_pos(3,3);
											if(length<10) wr_d_lcd(length+48);
											else
											{
												wr_d_lcd(length/10+48);
												wr_d_lcd(length%10+48);
											}
										} 
										j++;
									}
									i++;
								}
							}
							time_1ms(20);
							

						} 
					 }
					 else if(flag==4)
					 {
					 	if(px<2) px++;
						else if(px==2) px=1;
						while(P2!=0x00);
						time_1ms(20);
					 }
					 loud=1;		
				}break; 
				case 0x80: 
				{
					loud=0;
					if(flag==0)
					{
						if(slect==0) flag=1;
						else if(slect==1) flag=2;
						else if(slect==2) flag=3;
						else if(slect==3) flag=4;
						while(P2!=0x00);
						time_1ms(20);
					}
					else if(flag==5)
					{
						if(choose==0)
						{
							flag=slect+1;
						}
						else if(choose==1) flag=0;
						choose=0;
						while(P2!=0x00);
						time_1ms(20);
					}
					else if(flag==3)
					{
						i=0;
						while(zidan_x[i]!=0) i++;
						zidan_x[i]=planex[0]+1;
						zidan_y[i]=28;
						while(P2!=0x00);
						time_1ms(100);	
					}		
					else if(flag==4)
					{
						px=4;
						while(P2!=0x00);
						time_1ms(100);
					}
					loud=1;	
				}break; 
			}
		}	   
	}
	/*0x77	   0xb7	   0xd7	   0xe7
	  0x7b	   0xbb	   0xdb	   0xeb
	  0x7d	   0xbd	   0xdd	   0xed
	  0x7e     0xbe    0xde    0xee */
	P0=0xf7;
	temp=P0;
	if(temp!=0xf7)
	{
		
		time_1ms(20);
		if(temp!=0xf7)
		{
			switch(temp)
			{
				case 0x77:
				{
					if(ran1==0&&ran2==0) dishu=0;	
				}break;
				case 0xb7:
				{
					if(ran1==0&&ran2==1) dishu=0;	
				}break;
				case 0xd7:
				{
					if(ran1==0&&ran2==2) dishu=0;
				}break;
				case 0xe7:
				{
					if(ran1==0&&ran2==3) dishu=0;	
				}break;
			}
	//	   while(P0!=0xf7);
	    	time_1ms(20);
		}
	}
	P0=0xfb;
	temp=P0;
	if(temp!=0xfb)
	{
		
		time_1ms(20);
		if(temp!=0xfb)
		{
			switch(temp)
			{
				case 0x7b:
				{
					if(ran1==1&&ran2==0) dishu=0;		
				}break;
				case 0xbb:
				{
					if(ran1==1&&ran2==1) dishu=0;	
				}break;
				case 0xdb:
				{
					if(ran1==1&&ran2==2) dishu=0;
				}break;
				case 0xeb:
				{
					if(ran1==1&&ran2==3) dishu=0;	
				}break;
			}
		//	while(P0!=0xfb);
	    	time_1ms(20);
		}
	}
	P0=0xfd;
	temp=P0;
	if(temp!=0xfd)
	{
		
		time_1ms(20);
		if(temp!=0xfd)
		{
			switch(temp)
			{
				case 0x7d:
				{
					if(ran1==2&&ran2==0) dishu=0;	
				}break;
				case 0xbd:
				{
					if(ran1==2&&ran2==1) dishu=0;			
				}break;
				case 0xdd:
				{
					if(ran1==2&&ran2==2) dishu=0;
				}break;
				case 0xed:
				{
					if(ran1==2&&ran2==3) dishu=0;		
				}break;
			}
	//	   while(P0!=0xfd);
	    	time_1ms(20);
		}
	}
	P0=0xfe;
	temp=P0;
	if(temp!=0xfe)
	{
		
		time_1ms(20);
		if(temp!=0xfe)
		{
			switch(temp)
			{
				case 0x7e:
				{	
					if(ran1==3&&ran2==0) dishu=0;	
				}break;
				case 0xbe:
				{
					if(ran1==3&&ran2==1) dishu=0;	
				}break;
				case 0xde:
				{
					if(ran1==3&&ran2==2) dishu=0;  	
				}break;
				case 0xee:
				{
					if(ran1==3&&ran2==3) dishu=0;	
				}break;
			}
		//	 while(P0!=0xfe);
	    	time_1ms(20);
		}
	}	
}

 

2.7. 主函数

  • main():程序的入口,初始化 LCD,显示起始画面,进入主循环。根据不同的 flag 值进入相应的游戏模块或功能模块。
void main()
{
   char i=0,j;
   loud=1;
   init_lcd();     //³õʼ»¯
  img_disp(tab1);    //ÏÔʾͼÏñ
  delaynms(1000);
  wr_i_lcd(0x30);
   wr_i_lcd(0x01);
   lcd_pos(1,1);
   while(name[i]!='\0') 
   {
   		wr_d_lcd(name[i]);
		i++;
		if(i%2!=0)loud=0;
		delay(20000);
   }
   clear_pic();
   wr_i_lcd(0x30);
	wr_i_lcd(0x01);
	TMOD=0x10;
	TH1=(65536-8000)/256;
	TL1=(65536-8000)%256;
	EA=1;		 
	ET1=1;
	TR1=1;
	while(1)
	{
		clear_pic();
		wr_i_lcd(0x30);
		wr_i_lcd(0x01);
		cata();
		if(flag==1)
		{
			while(flag==1)
			{
				food=0;
				back_ground();
				snake_init();
				game_snake();
			}	
		}
		if(flag==2)
		{			
			while(flag==2)
			{
				/*Ò»ÅÅ16¸öµØÊó
				00 01 02 03
				10 11 12 13
				20 21 22 23
				30 31 32 33*/
				length=0;
				mouse_back();
				game_mouse();
			}		
		}
		if(flag==3)
		{
			while(flag==3)
			{
				length=0;
				back_ground();
				plane_init();
				game_plane();
			}	
		}
		if(flag==4)
		{
			px=1;
			p=1;
			clear_pic();
			wr_i_lcd(0x30);
			wr_i_lcd(0x01);
			picture();		
		}
	}

		
}

2.8. 源码整合:

#include "includes.h"
#include "intrins.h"
#include "stdlib.h"

// 方向代码:0 右,1 左,2 上,3 下
// P2 端口:上 0x04,下 0x10,左 0x01,右 0x40,确认 0x80

uchar code name[] = {"小龟游戏机"};
uchar code game1[] = {"贪吃蛇"};
uchar code game2[] = {"打地鼠"};
uchar code game3[] = {"飞机大战"};
uchar code game4[] = {"图片"};
uchar code loser[] = {"你输了"};
uchar code lxy1[] = {"继续"};
uchar code lxy2[] = {"返回"};
uchar code cj[] = {"长度: "};
uchar code fjs[] = {"飞机: "};
char code mouse[] = {"老鼠: "};

// 全局变量定义
uchar p = 1, px = 1;
uchar length = 9;	
uchar flag = 0, slect = 0, choose = 0;
uchar ran1, ran2, food = 0;
uchar planex[3] = {28, 30, 0};
uchar zidan_x[10] = {0}, zidan_y[10] = {0};
uchar boom_x[10] = {0}, boom_y[10] = {0};
char dishu = 0;

sbit loud = P3^7; // 定义蜂鸣器的开关

// 贪吃蛇的结构体
struct xx {
    char x[22];
    char y[22];
    char head;
    char tail;
    char dir;
} snake;

// 贪吃蛇初始化函数
void snake_init(void) {
    lcd_set_dot(1, 1, 0);
    lcd_set_dot(2, 1, 0);
    lcd_set_dot(3, 1, 0);
    lcd_set_dot(4, 1, 0);
    lcd_set_dot(5, 1, 0);
    lcd_set_dot(6, 1, 0);
    snake.x[0] = 1; snake.y[0] = 1;
    snake.x[1] = 2; snake.y[1] = 1;
    snake.x[2] = 3; snake.y[2] = 1;
    snake.x[3] = 4; snake.y[3] = 1;
    snake.x[4] = 5; snake.y[4] = 1;
    snake.x[5] = 6; snake.y[5] = 1;
    snake.head = 5;
    snake.tail = 0;
    snake.dir = 0;	
}

// 游戏失败处理函数
void die(void) {
    uchar i;
    loud = 0; // 关闭蜂鸣器
    flag = 5; // 设置标志为5,表示游戏结束
    clear_pic();
    wr_i_lcd(0x30);
    wr_i_lcd(0x01);
    i = 0;
    lcd_pos(0, 2);
    while (loser[i] != '\0') {
        wr_d_lcd(loser[i]);
        i++;
    }
    i = 0;
    lcd_pos(2, 0); 
    while (lxy1[i] != '\0') {
        wr_d_lcd(lxy1[i]);
        i++;	
    }
    i = 0;
    lcd_pos(2, 5); 
    while (lxy2[i] != '\0') {
        wr_d_lcd(lxy2[i]);
        i++;	
    }
    lcd_pos(3, 0); 
    wr_d_lcd('o');
    delay(1000);
    loud = 1; // 打开蜂鸣器
    while (flag == 5);	
}

// 游戏菜单选择
uchar cata(void) {
    uchar i;
    i = 0;
    slect = 0;
    lcd_pos(0, 0);
    wr_d_lcd('o');
    lcd_pos(0, 1);
    while (game1[i] != '\0') {
         wr_d_lcd(game1[i]);
         i++;
    }
    lcd_pos(1, 1);
    i = 0;
    while (game3[i] != '\0') {
         wr_d_lcd(game2[i]);
         i++;
    }
    lcd_pos(2, 1);
    i = 0;
    while (game3[i] != '\0') {
         wr_d_lcd(game3[i]);
         i++;
    }
    lcd_pos(3, 1);
    i = 0;
    while (game4[i] != '\0') {
         wr_d_lcd(game4[i]);
         i++;
    }
    while (flag == 0);	
}

// 贪吃蛇游戏逻辑
void game_snake(void) {
    uchar i, k, j;
    k = 0;
    food = 0;
    length = 6;
    lcd_pos(3, 0);
    i = 0;
    while (cj[i] != '\0') {
        wr_d_lcd(cj[i]);
        i++;	
    }
    wr_d_lcd(length + 48);
    while (1) {
        if (food == 0) {
            while (1) { // 确保生成的食物不在蛇身上
                ran1 = TH1 % 59 + 1;
                ran2 = TL1 % 30 + 1;
                food = 1;
                i = snake.tail;
                while (i != snake.head) {
                    if (snake.x[i] == ran1 && snake.y[i] == ran2) {
                        break;
                    }
                    i++;
                    if (i == 22) i = 0;
                    if (i == snake.head) {
                        if (snake.x[i] == ran1 && snake.y[i] == ran2) {
                            i = snake.head - 1;
                            break;
                        }
                    }	
                }
                if (i == snake.head) break;	
            }
            lcd_set_dot(ran1, ran2, 0);
        }
        i = snake.tail;
        while (i != snake.head) { // 蛇碰到自己
            if (snake.x[i] == snake.x[snake.head] && snake.y[i] == snake.y[snake.head]) {
                die();	
                break;	
            }
            i++;
            if (i == 22) i = 0;
        }
        if (i != snake.head) break;
        if (snake.x[snake.head] >= 60 || snake.y[snake.head] >= 30 || snake.x[snake.head] == 0 || snake.y[snake.head] == 0) { // 蛇撞墙
            die();	
            break;	
        }
        snake.head++;
        if (snake.head == 22) {
            snake.head = 0;
            if (snake.dir == 0) { // 右
                snake.x[snake.head] = snake.x[21] + 1;
                snake.y[snake.head] = snake.y[21];	
            } else if (snake.dir == 1) { // 左
                snake.x[snake.head] = snake.x[21] - 1;
                snake.y[snake.head] = snake.y[21];	
            } else if (snake.dir == 2) { // 下
                snake.x[snake.head] = snake.x[21];
                snake.y[snake.head] = snake.y[21] + 1;
            } else if (snake.dir == 3) { // 上
                snake.x[snake.head] = snake.x[21];
                snake.y[snake.head] = snake.y[21] - 1;	
            }	
        } else {
            if (snake.dir == 0) {
                snake.x[snake.head] = snake.x[snake.head - 1] + 1;
                snake.y[snake.head] = snake.y[snake.head - 1];	
            } else if (snake.dir == 1) {
                snake.x[snake.head] = snake.x[snake.head - 1] - 1;
                snake.y[snake.head] = snake.y[snake.head - 1];	
            } else if (snake.dir == 2) {
                snake.x[snake.head] = snake.x[snake.head - 1];
                snake.y[snake.head] = snake.y[snake.head - 1] + 1;
            } else if (snake.dir == 3) {
                snake.x[snake.head] = snake.x[snake.head - 1];
                snake.y[snake.head] = snake.y[snake.head - 1] - 1;
            }
        }
        lcd_set_dot(snake.x[snake.head], snake.y[snake.head], 0);
        if (snake.x[snake.head] != ran1 || snake.y[snake.head] != ran2) { // 蛇没有吃到食物
            lcd_set_dot(snake.x[snake.tail], snake.y[snake.tail], 1);
            snake.tail++;
            if (snake.tail == 22) snake.tail = 0;
        } else {  // 蛇吃到食物
            if (k < 90) k += 10;
            loud = 0;
            length++;
            wr_i_lcd(0x30);
            // wr_i_lcd(0x01);
            lcd_pos(3, 3);
            wr_d_lcd(length / 10 + 48);
            wr_d_lcd(length % 10 + 48);
            food = 0;
        }
        for (i = 0; i < 100; i++)
            for (j = 0; j < 100 - k; j++) 
                time_1ms(1000);

        loud = 1;	
    }	
}

// 飞机初始化函数
void plane_init(void) {
    uchar i;
    lcd_set_dot(29, 29, 0);
    lcd_set_dot(28, 30, 0);
    lcd_set_dot(30, 30, 0);
    lcd_set_dot(29, 30, 0);
    for (i = 0; i < 10; i++) {
        zidan_x[i] = 0;
        zidan_y[i] = 0;
        boom_x[i] = 0;
        boom_y[i] = 0;	
    }
    planex[0] = 28;	
    planex[1] = 30;
}

// 游戏背景绘制
void back_ground(void) {
    uchar i;
    clear_pic();
    wr_i_lcd(0x30);
    wr_i_lcd(0x01);
    for (i = 0; i <= 60; i++) { 
        lcd_set_dot(i, 0, 0);
        lcd_set_dot(i, 31, 0);	
    }
    for (i = 0; i <= 32; i++) {
        lcd_set_dot(0, i, 0);
        lcd_set_dot(60, i, 0);	
    }
    if (flag == 3) {
        lcd_pos(3, 0);
        i = 0;
        while (fjs[i] != '\0') {
            wr_d_lcd(fjs[i]);
            i++;
        }
        wr_d_lcd(length + 48);
    }		
}

// 飞机大战游戏逻辑
void game_plane(void) {
    uchar i, t = 0, j = 0;
    while (1) {
        i = 0;
        while (i < 10) {
            j = 0;
            while (j < 10) {
                if (((zidan_x[i]) == boom_x[j]) && ((zidan_y[i] - 1 == boom_y[j]) || (zidan_y[i] == boom_y[j])) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {
                    lcd_set_dot(zidan_x[i], zidan_y[i], 1);
                    lcd_set_dot(boom_x[j], boom_y[j], 1);
                    zidan_y[i] = 0;
                    zidan_x[i] = 0;
                    boom_x[j] = 0;
                    boom_y[j] = 0;
                    wr_i_lcd(0x30);
                    length++;
                    lcd_pos(3, 3);
                    if (length < 10) wr_d_lcd(length + 48);
                    else {
                        wr_d_lcd(length / 10 + 48);
                        wr_d_lcd(length % 10 + 48);
                    }
                } 
                j++;
            }
            i++;
        }
        i = 0;
        while (i < 10) {
            j = 0;
            while (j < 10) {
                if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {
                    lcd_set_dot(zidan_x[i], zidan_y[i], 1);
                    lcd_set_dot(boom_x[j], boom_y[j], 1);
                    zidan_y[i] = 0;
                    zidan_x[i] = 0;
                    boom_x[j] = 0;
                    boom_y[j] = 0;
                } 
                j++;
            }
            if ((boom_x[i] == planex[0] && boom_y[i] == 29) || (boom_x[i] == planex[1] && boom_y[i] == 29) || ((boom_x[i] == (planex[1] + planex[0]) / 2) && boom_y[i] == 29)) {
                die();
                break;	
            }
            i++;
        }
        if (i != 10) break;
        i = 0;
        t++;
        ran2 = TL1 % 59;
        while (i < 10) {
            if (zidan_x[i] != 0) {
                if (zidan_y[i] == 1) {
                    lcd_set_dot(zidan_x[i], zidan_y[i], 1);
                    zidan_y[i] = 0;
                    zidan_x[i] = 0;
                } else { 
                    lcd_set_dot(zidan_x[i], zidan_y[i], 1); busy_lcd();
                    zidan_y[i]--;
                    lcd_set_dot(zidan_x[i], zidan_y[i], 0);
                }	
            }				   
            i++;
        }
        
        i = 0;
        while (boom_x[i] != 0) i++;
        if (t == 4) {
            t = 0;
            boom_x[i] = ran2 + 1;
            boom_y[i] = 1;
        }
        i = 0;
        while (i < 10) {
            if (boom_x[i] != 0) {
                if (boom_y[i] == 30) {
                    lcd_set_dot(boom_x[i], boom_y[i], 1);
                    boom_y[i] = 0;
                    boom_x[i] = 0;		
                } else { 
                    lcd_set_dot(boom_x[i], boom_y[i], 1); busy_lcd();
                    boom_y[i]++;
                    lcd_set_dot(boom_x[i], boom_y[i], 0); 
                }
            }
            i++;
        }			
        for (i = 0; i < 200; i++)
            for (j = 0; j < 50; j++) { 
                // if (i == 70) loud = 1;
                time_1ms(1000);
            } 	
    }	
}

// 图片显示函数
void picture(void) {
    img_disp(tab1);
    while (1) {
        if (p != px) {
            if (px == 4) {
                flag = 0;
                break;
            }
            clear_pic();
            p = px;
            if (p == 1) img_disp(tab1);
            // else if (p == 2) img_disp(tab1); 
            else if (p == 2) img_disp(tab3); 
            
        }	   
    }
}

// 打地鼠背景初始化
void mouse_back(void) {
    char i, j;
    clear_pic();
    wr_i_lcd(0x30);
    wr_i_lcd(0x01);	
    for (i = 0; i < 4; i++)
        for (j = 0; j < 4; j++) {
            lcd_pos(i, j);
            wr_d_lcd('o');	
        }
    i = 0;
    lcd_pos(1, 4);
    while (mouse[i] != '\0') {
        wr_d_lcd(mouse[i]);
        i++;		
    }
    wr_d_lcd(length + 48);
}

// 打地鼠游戏逻辑
void game_mouse(void) {
    uchar i, j, k;
    k = 0;
    length = 0;
    while (1) {
        ran1 = TH1 % 4;
        ran2 = TL1 % 4;
        lcd_pos(ran1, ran2);
        wr_d_lcd(0x02);
        dishu = 1;
        loud = 0;
        for (i = 0; i < 200; i++)
            for (j = 0; j < 200 - k; j++) { 
                if (i == 70) loud = 1;
                time_1ms(1000);
            }
        if (k < 150) k += 10;
        if (dishu == 1) {
            die();	
            break;
        }
        
        lcd_pos(1, 7); 
        length++;
        if (length < 10) wr_d_lcd(length + 48);
        else {
            wr_d_lcd(length / 10 + 48); 
            wr_d_lcd(length % 10 + 48);	
        }
        lcd_pos(ran1, ran2);
        wr_d_lcd('o');
    }
}

// 主函数入口
void main() {
    char i = 0, j;
    loud = 1;
    init_lcd();     // 初始化LCD
    img_disp(tab1); // 显示图片
    delaynms(1000);
    wr_i_lcd(0x30);
    wr_i_lcd(0x01);
    lcd_pos(1, 1);
    while (name[i] != '\0') {
        wr_d_lcd(name[i]);
        i++;
        if (i % 2 != 0) loud = 0;
        delay(20000);
    }
    clear_pic();
    wr_i_lcd(0x30);
    wr_i_lcd(0x01);
    TMOD = 0x10;
    TH1 = (65536 - 8000) / 256;
    TL1 = (65536 - 8000) % 256;
    EA = 1;		 
    ET1 = 1;
    TR1 = 1;
    while (1) {
        clear_pic();
        wr_i_lcd(0x30);
        wr_i_lcd(0x01);
        cata();
        if (flag == 1) {
            while (flag == 1) {
                food = 0;
                back_ground();
                snake_init();
                game_snake();
            }	
        }
        if (flag == 2) {			
            while (flag == 2) {
                /* 一个4x4的打地鼠格子
                00 01 02 03
                10 11 12 13
                20 21 22 23
                30 31 32 33 */
                length = 0;
                mouse_back();
                game_mouse();
            }		
        }
        if (flag == 3) {
            while (flag == 3) {
                length = 0;
                back_ground();
                plane_init();
                game_plane();
            }	
        }
        if (flag == 4) {
            px = 1;
            p = 1;
            clear_pic();
            wr_i_lcd(0x30);
            wr_i_lcd(0x01);
            picture();		
        }
    }
}

// 中断处理函数
void T0_() interrupt 3 {
    /* P2 上 0x04 下 0x10 左 0x01 右 0x40 确认 0x80 */
    uchar temp, i, j;
    if (flag == 1 || flag == 2) {
        TH1 = (65536 - 30000) / 256;
        TL1 = (65536 - 30000) % 256;
    } else {
        TH1 = (65536 - 200) / 256;
        TL1 = (65536 - 200) % 256;	
    }
    P2 = 0x00; // 初始化P2为0
    temp = P2;
    if (temp != 0x00) {
        time_1ms(20);
        if (temp != 0x00) {	
            switch (temp) {
                case 0x04: { // 上键
                    loud = 0;
                    if (flag == 0) { // 菜单导航
                        lcd_pos(slect, 0);
                        wr_d_lcd(' ');
                        if (slect == 0) slect = 3;
                        else slect--;
                        lcd_pos(slect, 0);
                        wr_d_lcd('o');
                        while (P2 != 0x00);
                        time_1ms(50);	
                    } else if (flag == 1) { // 贪吃蛇游戏中
                        if (snake.dir != 2) snake.dir = 3;
                    }
                    loud = 1;
                } break;
                case 0x10: { // 下键
                    loud = 0;
                    if (flag == 0) { // 菜单导航
                        lcd_pos(slect, 0);
                        wr_d_lcd(' ');
                        if (slect == 3) slect = 0;
                        else slect++;
                        lcd_pos(slect, 0);
                        wr_d_lcd('o');
                        while (P2 != 0x00);
                        time_1ms(20);
                    } else if (flag == 1) { // 贪吃蛇游戏中
                        if (snake.dir != 3) snake.dir = 2;
                    }
                    loud = 1;
                } break; 
                case 0x01: { // 左键
                    loud = 0;
                    if (flag == 5) { // 游戏失败后
                        if (choose != 0) {
                            lcd_pos(3, 0);
                            wr_d_lcd('o');
                            lcd_pos(3, 6);
                            wr_d_lcd(' ');
                            choose = 0;
                            while (P2 != 0x00);
                            time_1ms(20);	
                        }	
                    } else if (flag == 1) { // 贪吃蛇游戏中
                        if (snake.dir != 0) snake.dir = 1;
                    } else if (flag == 3) { // 飞机大战游戏中
                        if (planex[0] > 1) {
                            planex[0]--;
                            planex[1]--;
                            lcd_set_dot(planex[0], 30, 0); busy_lcd();
                            if ((planex[0] - 1) != 0) lcd_set_dot(planex[0] - 1, 30, 1); busy_lcd();
                            lcd_set_dot(planex[1], 30, 0);  busy_lcd();
                            if ((planex[1] + 1) != 113) lcd_set_dot(planex[1] + 1, 30, 1); busy_lcd();
                            lcd_set_dot((planex[0] + planex[1]) / 2, 29, 0); busy_lcd();
                            lcd_set_dot((planex[0] + planex[1]) / 2 + 1, 29, 1); busy_lcd();
                            while (P2 != 0x00) {
                                i = 0;
                                while (i < 10) {
                                    j = 0;
                                    while (j < 10) {
                                        if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {
                                            lcd_set_dot(zidan_x[i], zidan_y[i], 1);
                                            lcd_set_dot(boom_x[j], boom_y[j], 1);
                                            zidan_y[i] = 0;
                                            zidan_x[i] = 0;
                                            boom_x[j] = 0;
                                            boom_y[j] = 0;
                                            wr_i_lcd(0x30);
                                            length++;
                                            lcd_pos(3, 3);
                                            if (length < 10) wr_d_lcd(length + 48);
                                            else {
                                                wr_d_lcd(length / 10 + 48);
                                                wr_d_lcd(length % 10 + 48);
                                            }
                                        } 
                                        j++;
                                    }
                                    i++;
                                }	
                            }
                            time_1ms(20);
                        } 
                    } else if (flag == 4) { // 图片显示中
                        if (px > 1) px--;
                        else if (px == 1) px = 2;
                        while (P2 != 0x00);
                        time_1ms(20);
                    }
                    loud = 1;		
                } break; 
                case 0x40: { // 右键
                    loud = 0;
                    if (flag == 5) { // 游戏失败后
                        if (choose != 1) {
                            lcd_pos(3, 6);
                            wr_d_lcd('o');
                            lcd_pos(3, 0);
                            wr_d_lcd(' ');
                            choose = 1;
                            while (P2 != 0x00);
                            time_1ms(20);	
                        }	
                    } else if (flag == 1) { // 贪吃蛇游戏中
                        if (snake.dir != 1) snake.dir = 0;
                    } else if (flag == 3) { // 飞机大战游戏中
                        if (planex[1] < 59) {
                            planex[1]++;
                            planex[0]++;
                            lcd_set_dot(planex[0], 30, 0); busy_lcd();
                            if ((planex[0] - 1) != 0) lcd_set_dot(planex[0] - 1, 30, 1); busy_lcd();
                            lcd_set_dot(planex[1], 30, 0);  busy_lcd();
                            if ((planex[1] + 1) != 60) lcd_set_dot(planex[1] + 1, 30, 1); busy_lcd();
                            lcd_set_dot((planex[0] + planex[1]) / 2, 29, 0); busy_lcd();
                            lcd_set_dot((planex[0] + planex[1]) / 2 - 1, 29, 1); busy_lcd();
                            while (P2 != 0x00) {
                                i = 0;
                                while (i < 10) {
                                    j = 0;
                                    while (j < 10) {
                                        if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {
                                            lcd_set_dot(zidan_x[i], zidan_y[i], 1);
                                            lcd_set_dot(boom_x[j], boom_y[j], 1);
                                            zidan_y[i] = 0;
                                            zidan_x[i] = 0;
                                            boom_x[j] = 0;
                                            boom_y[j] = 0;
                                            wr_i_lcd(0x30);
                                            length++;
                                            lcd_pos(3, 3);
                                            if (length < 10) wr_d_lcd(length + 48);
                                            else {
                                                wr_d_lcd(length / 10 + 48);
                                                wr_d_lcd(length % 10 + 48);
                                            }
                                        } 
                                        j++;
                                    }
                                    i++;
                                }
                            }
                            time_1ms(20);
                        } 
                    } else if (flag == 4) { // 图片显示中
                        if (px < 2) px++;
                        else if (px == 2) px = 1;
                        while (P2 != 0x00);
                        time_1ms(20);
                    }
                    loud = 1;		
                } break; 
                case 0x80: { // 确认键
                    loud = 0;
                    if (flag == 0) { // 在菜单中选择游戏
                        if (slect == 0) flag = 1;
                        else if (slect == 1) flag = 2;
                        else if (slect == 2) flag = 3;
                        else if (slect == 3) flag = 4;
                        while (P2 != 0x00);
                        time_1ms(20);
                    } else if (flag == 5) { // 游戏失败后选择继续或返回
                        if (choose == 0) {
                            flag = slect + 1;
                        } else if (choose == 1) flag = 0;
                        choose = 0;
                        while (P2 != 0x00);
                        time_1ms(20);
                    } else if (flag == 3) { // 飞机大战游戏中
                        i = 0;
                        while (zidan_x[i] != 0) i++;
                        zidan_x[i] = planex[0] + 1;
                        zidan_y[i] = 28;
                        while (P2 != 0x00);
                        time_1ms(100);	
                    } else if (flag == 4) { // 图片显示中
                        px = 4;
                        while (P2 != 0x00);
                        time_1ms(100);
                    }
                    loud = 1;	
                } break; 
            }
        }	   
    }
    // 检测P0口的输入,判断打地鼠游戏中的鼠标位置
    P0 = 0xf7;
    temp = P0;
    if (temp != 0xf7) {
        time_1ms(20);
        if (temp != 0xf7) {
            switch (temp) {
                case 0x77: {
                    if (ran1 == 0 && ran2 == 0) dishu = 0;	
                } break;
                case 0xb7: {
                    if (ran1 == 0 && ran2 == 1) dishu = 0;	
                } break;
                case 0xd7: {
                    if (ran1 == 0 && ran2 == 2) dishu = 0;
                } break;
                case 0xe7: {
                    if (ran1 == 0 && ran2 == 3) dishu = 0;	
                } break;
            }
            time_1ms(20);
        }
    }
    P0 = 0xfb;
    temp = P0;
    if (temp != 0xfb) {
        time_1ms(20);
        if (temp != 0xfb) {
            switch (temp) {
                case 0x7b: {
                    if (ran1 == 1 && ran2 == 0) dishu = 0;		
                } break;
                case 0xbb: {
                    if (ran1 == 1 && ran2 == 1) dishu = 0;	
                } break;
                case 0xdb: {
                    if (ran1 == 1 && ran2 == 2) dishu = 0;
                } break;
                case 0xeb: {
                    if (ran1 == 1 && ran2 == 3) dishu = 0;	
                } break;
            }
            time_1ms(20);
        }
    }
    P0 = 0xfd;
    temp = P0;
    if (temp != 0xfd) {
        time_1ms(20);
        if (temp != 0xfd) {
            switch (temp) {
                case 0x7d: {
                    if (ran1 == 2 && ran2 == 0) dishu = 0;	
                } break;
                case 0xbd: {
                    if (ran1 == 2 && ran2 == 1) dishu = 0;			
                } break;
                case 0xdd: {
                    if (ran1 == 2 && ran2 == 2) dishu = 0;
                } break;
                case 0xed: {
                    if (ran1 == 2 && ran2 == 3) dishu = 0;		
                } break;
            }
            time_1ms(20);
        }
    }
    P0 = 0xfe;
    temp = P0;
    if (temp != 0xfe) {
        time_1ms(20);
        if (temp != 0xfe) {
            switch (temp) {
                case 0x7e: {	
                    if (ran1 == 3 && ran2 == 0) dishu = 0;	
                } break;
                case 0xbe: {
                    if (ran1 == 3 && ran2 == 1) dishu = 0;	
                } break;
                case 0xde: {
                    if (ran1 == 3 && ran2 == 2) dishu = 0;  	
                } break;
                case 0xee: {
                    if (ran1 == 3 && ran2 == 3) dishu = 0;	
                } break;
            }
            time_1ms(20);
        }
    }	
}

完整工程源码获取方式:毕设&amp;课设&amp;项目&amp;实训-51单片机自制小霸王游戏机资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/947378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC(五)实现文件上传

目录 1.先导jar包 2.在Springmvc.xml配置文件上传解析器 3. 编写文件上传的html页面 4.在controller包中创建FileController.class文件 5.文件下载 6.重启服务器测试 1.先导jar包 <dependency><groupId>commons-fileupload</groupId><artifactId>…

LabVIEW声波谐振管自动化测量系统

开发了一种基于LabVIEW的声波谐振管自动化测量系统。该系统利用LabVIEW的强大功能&#xff0c;实现了对声波谐振频率的精确测量&#xff0c;提高了实验数据的采集效率和准确性。系统主要应用于物理教学和科研中&#xff0c;用于研究声波在谐振管中的传播特性。 项目背景 传统的…

docker Error response from daemon

问题 Error response from daemon: Get "https://index.docker.io/v1/search?qnginx&n25": read tcp 192.168.50.233:54354->54.198.86.24:443: read: connection reset by peer Unable to find image redis:latest locally docker: Error response from d…

PHP框架+gatewayworker实现在线1对1聊天--gatewayworker说明(2)

文章目录 gatewayworker使用说明onConnect 说明 gatewayworker使用说明 gatewayworker里只需要使用Applications\YourApp下的Events.php文件。 对文件的代码进行一下改造&#xff0c;如下&#xff0c;我们只需要用到onConnect方法&#xff0c;写法固定&#xff0c;其他方法都…

【Hadoop】Hadoop安全之Knox网关

目录 一、概述 2.1 knox介绍 2.2 版本信息 二、部署 三、验证Knox网关 3.1 Hdfs RESTFULL 3.2 HDFSUI 3.3 YARNUI 3.4 HBASEUI 一、概述 2.1 knox介绍 Apache Knox网关是一个用于与Apache Hadoop部署的REST api和ui交互的应用程序网关。Knox网关为所有与Apache Hadoop…

PyCharm专项训练5 最短路径算法

一、实验目的 本文的实验目的是通过编程实践&#xff0c;掌握并应用Dijkstra&#xff08;迪杰斯特拉&#xff09;算法和Floyd&#xff08;弗洛伊德&#xff09;算法来解决图论中的最短路径问题。 二、实验内容 数据准备&#xff1a; 使用邻接表的形式定义两个图graph_dijkstra…

分布式算法(五):初识ZAB协议

文章目录 一、什么是Zookeeper二、ZAB与Zookeeper的关系为什么Zookeeper不直接使用Paxos 三、ZAB简介1.名词解释提案&#xff08;Proposal&#xff09;事务&#xff08;Transaction&#xff09;原子广播&#xff08;Atomic Broadcast&#xff09; 2.集群角色领导者&#xff08;…

word中插入zotero引用

1、参考文献末尾没有文献&#xff1f; 在文献条目要显示的地方点击“refresh” 2、参考文献条目没有悬挂缩进&#xff1f; 把“书目”添加到样式库中&#xff0c;修改样式为悬挂缩进1.5字符 3、交叉引用&#xff1f; 宏 新建一个宏 粘贴下面代码 Public Sub ZoteroLinkCita…

利用3DGS中convert.py处理自采数据

前言 3DGS源码中convert.py提供对自采数据集的处理&#xff0c;需要预先安装Colmap和ImageMagick. ubuntu22.04安装colmap 点击进入NVIDIA官网&#xff0c;查看GPU的CMAKE_CUDA_ARCHITECTURES 1、克隆colmap源码&#xff0c;并进入colmap文件夹 git clone https://github.c…

【Vue】vue-router使用addRoute动态加载路由后刷新页面404

场景&#xff1a;动态加载路由&#xff0c;点击菜单路由跳转正常&#xff0c;但刷新页面报404 原因&#xff1a;使用404做异常路由捕获 刷新页面会导致路由丢失&#xff0c;重建路由时先加载了静态路由&#xff08;包含异常路由捕获404&#xff09;&#xff0c;此时动态路由还未…

USB射频微波功率计的功能与优势-盛铂科技

USB射频功率计是一种用于测量射频信号&#xff08;RF&#xff09;功率的仪器&#xff0c;它通过USB接口与计算机或其他设备连接&#xff0c;以便于进行数据采集、处理和显示。 主要功能 功率测量&#xff1a;能够测量射频信号的功率&#xff0c;通常以毫瓦&#xff08;mW&…

【Vim Masterclass 笔记01】Section 1:Course Overview + Section 2:Vim Quickstart

文章目录 Section 1&#xff1a;Course Introduction 课程概述S01L01 Course Overview 课程简介课程概要 S01L02 Course Download 课程资源下载S01L03 What Vim Is and Why You Should Learn It 何为 Vim&#xff1f;学来干啥&#xff1f;1 何为 Vim2 为何学 Vim Section 2&…

Elasticsearch JavaRestClient版

文章目录 初始化RestHighLeveClient&#xff08;必要条件&#xff09;索引库操作1.创建索引库&#xff08;4步&#xff09;2.删除索引库&#xff08;3步&#xff09;3.判断索引库是否存在&#xff08;3步&#xff09;4.总结&#xff1a;四步走 文档操作1.创建文档&#xff08;4…

基于Pytorch和yolov8n手搓安全帽目标检测的全过程

一.背景 还是之前的主题&#xff0c;使用开源软件为公司搭建安全管理平台&#xff0c;从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection&#xff0c;我是从运行、训练、标注倒过来学习的。由于工作原因&#xff0c;抽空…

driftingblues6靶机

打开靶场 查看页面源代码&#xff0c;最下面有一个注释&#xff0c;提供了一个网址 vmlist.github.io&#xff0c;我们去访问一下 这里是一个github页面&#xff0c;提供攻防虚拟机的下载&#xff0c;对我们解题并没有什么有用的信息&#xff0c;我们再去扫描端口 发现只有80端…

python学习笔记—12—布尔类型、if语句

1. 布尔类型 (1) 定义 (2) 比较运算符 (3) 代码演示 1. 手动定义 bool_1 True bool_2 False print(f"bool_1的内容是&#xff1a;{bool_1}, 类型是&#xff1a;{type(bool_1)}") print(f"bool_2的内容是&#xff1a;{bool_2}, 类型是&#xff1a;{type(bool…

EasyExcel自定义动态下拉框(附加业务对象转换功能)

全文直接复制粘贴即可&#xff0c;测试无误 一、注解类 1、ExcelSelected.java 设置下拉框 Documented Target({ElementType.FIELD})//用此注解用在属性上。 Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中&#xff0c;jvm加载class文件之后&#xff0c…

Fetch处理大模型流式数据请求与解析

为什么有的大模型可以一次返回多个 data&#xff1f; Server-Sent Events (SSE)&#xff1a;允许服务器连续发送多个 data: 行&#xff0c;每个代表一个独立的数据块。 流式响应&#xff1a;大模型服务通常以流式响应方式返回数据&#xff0c;提高响应速度。 批量处理&#x…

开源低代码平台-Microi吾码-一键安装使用(CentOS一键安装MySql+Redis+MinIO+MongoDB+Watchtower脚本)

开源低代码平台-Microi吾码-一键安装使用 前言CentOS7一键安装脚本注意事项&#xff1a;安装成功预览图安装过程图安装结果docker脚本代码【有点东西&#xff1a;&#xff09;】踩过的坑开源低代码平台Microi吾码-系列文档 前言 有小伙伴提出他并不想在本地编译代码、打包镜像、…

Ubuntu 24.04 LTS 解决网络连接问题

1. 问题描述 现象&#xff1a;ens33 网络接口无法获取 IPv4 地址&#xff0c;导致网络不可用。初步排查&#xff1a; 运行 ip a&#xff0c;发现 ens33 接口没有分配 IPv4 地址。运行 ping www.baidu.com&#xff0c;提示“网络不可达”。查看 NetworkManager 日志&#xff0c…