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

news2025/2/25 3:00:19

视频演示效果:

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

目录:

目录

视频演示效果:

目录:

前言:

一、连接方式:

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文库

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32-S3遇见OpenAI:OpenAI官方发布ESP32嵌入式实时RTC SDK

目录 OpenAI RTC SDK简介应用场景详解智能家居控制系统个人健康助手教育玩具 技术亮点解析低功耗设计快速响应高精度RTC安全性保障开发者指南 最近&#xff0c;OpenAI官方发布了一款针对ESP32-S3的嵌入式实时RTC&#xff08;实时时钟&#xff09;SDK&#xff0c;这标志着ESP32-…

Elasticsearch:减少 Elastic 容器镜像中的 CVE(常见的漏洞和暴露)

作者&#xff1a;来自 Elastic Maxime Greau 在这篇博文中&#xff0c;我们将讨论如何通过在 Elastic 产品中切换到最小基础镜像并优化可扩展漏洞管理程序的工作流程来显著减少 Elastic 容器镜像中的常见漏洞和暴露 (Common Vulnerabilities and Exposures - CVEs)。 基于 Chai…

计算机网络 (21)网络层的几个重要概念

前言 计算机网络中的网络层是OSI&#xff08;开放系统互连&#xff09;模型中的第三层&#xff0c;也是TCP/IP模型中的第二层&#xff0c;它位于数据链路层和传输层之间&#xff0c;负责数据包从源主机到目的主机的路径选择和数据转发。 一、网络层的主要功能 路由选择&#xf…

LED背光驱动芯片RT9293应用电路

一&#xff09;简介&#xff1a; RT9293 是一款高频、异步的 Boost 升压型 LED 定电流驱动控制器&#xff0c;其工作原理如下&#xff1a; 1&#xff09;基本电路结构及原理 RT9293的主要功能为上图的Q1. Boost 电路核心原理&#xff1a;基于电感和电容的特性实现升压功能。当…

第四届计算机、人工智能与控制工程

第四届计算机、人工智能与控制工程 The 4th International Conference on Computer, Artificial Intelligence and Control Engineering 重要信息 大会官网&#xff1a;www.ic-caice.net 大会时间&#xff1a;2025年1月10-12日 大会地点&#xff1a;中国合肥 (安徽大学磬苑…

【Rust 学习笔记】Rust 基础数据类型介绍——指针、元组和布尔类型

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 Rust 基础数据类型介绍——指针、元组和布尔类型一、元组类型…

YOLO系列的学习

YOLOV1全解 You Only Look Once&#xff0c;把检测问题转化成回归问题&#xff0c;一个CNN就搞定了&#xff01;&#xff01;&#xff01;效率高&#xff0c;可对视频进行实时检测&#xff0c;应用领域非常广&#xff0c;到V3的时被美国军方用于军事行动&#xff0c;作者出于某…

鸿蒙应用开发搬砖经验之—使用DevTools工具调试前端页面

环境说明&#xff1a; 系统环境&#xff1a;Mac mini M2 14.5 (23F79) 开发IDE&#xff1a;DevEco Studio 5.0.1 Release 配置步骤&#xff1a; 按着官方的指引来慢慢一步一步来&#xff0c;但前提是要配置好SDK的路径&#xff08;没有配置的话&#xff0c;可能先看下面的配…

计算机网络练习题

学习这么多啦&#xff0c;那就简单写几个选择题巩固一下吧&#xff01; 1. 在IPv4分组各字段中&#xff0c;以下最适合携带隐藏信息的是&#xff08;D&#xff09; A、源IP地址 B、版本 C、TTL D、标识 2. OSI 参考模型中&#xff0c;数据链路层的主要功能是&#xff08;…

Django REST framework 源码剖析-视图类详解(Views)

Django REST framework视图图解 视图类&#xff08;View&#xff09; ‌视图‌是DRF中处理用户请求的基本单元。它们可以是函数视图&#xff08;FBV&#xff09;或类视图&#xff08;CBV&#xff09;。函数视图使用函数来处理请求&#xff0c;而类视图则使用类来处理请求。类视…

spring中使用@Validated,什么是JSR 303数据校验,spring boot中怎么使用数据校验

文章目录 一、JSR 303后台数据校验1.1 什么是 JSR303&#xff1f;1.2 为什么使用 JSR 303&#xff1f; 二、Spring Boot 中使用数据校验2.1 基本注解校验2.1.1 使用步骤2.1.2 举例Valid注解全局统一异常处理 2.2 分组校验2.2.1 使用步骤2.2.2 举例Validated注解Validated和Vali…

网页单机版五子棋小游戏项目练习-初学前端可用于练习~

今天给大家分享一个 前端练习的项目&#xff0c;技术使用的是 html css 和javascrpit 。希望能对于 刚刚学习前端的小伙伴一些帮助。 先看一下 实现的效果图 1. HTML&#xff08;HyperText Markup Language&#xff09; HTML 是构建网页的基础语言&#xff0c;它的主要作用是定…

UE5材质节点Distance

Distance可以计算两个物体间的距离&#xff0c;可以用来做过渡效果 当相机和物体距离3000的时候&#xff0c;就会渐渐从蓝过渡到红色&#xff0c;除以500是为了平滑过渡

【AIGC-ChatGPT进阶提示词指令】AI美食助手的设计与实现:Lisp风格系统提示词分析

引言 在人工智能助手的应用领域中&#xff0c;美食烹饪是一个既专业又贴近生活的方向。本文将详细分析一个基于Lisp风格编写的美食助手系统提示词&#xff0c;探讨其结构设计、功能实现以及实际应用效果。 提出你的菜系&#xff0c;为你分析&#xff0c;并生成图片卡片 提示词…

基于开发/发布/缺陷分离模型的 Git 分支管理实践20250103

基于开发/发布/缺陷分离模型的 Git 分支管理实践 引言 在现代软件开发中&#xff0c;合理的分支管理策略是保证项目成功的关键因素之一。本文将详细介绍一种基于开发/发布/缺陷分离的 Git 分支管理模型&#xff0c;这种模型不仅能提升团队协作效率&#xff0c;还能确保代码质…

【Cocos TypeScript 零基础 3.1】

目录 场景跳转 场景跳转 把新建好的TS文件与场景绑定 选中 场景 或 camera 拖进右边的 属性检查器 双击T文件,进入编辑 至于用什么IDE看个位朋友高兴 我这里有 VScode ,先用这个,老师也没有推荐 (老师也用的是这个) VScode UI 也有中文包,请自行上网搜索 打开创建的TS文件后…

SAP SD学习笔记23 - 无偿出荷(免费交货)与继续无偿出荷(继续免费交货)

上一章讲了SAP中的一括请求处理。 SAP SD学习笔记22 - VF04&#xff0c;VF06&#xff0c;VF24 等一括请求处理-CSDN博客 本章继续讲SAP中的内容&#xff1a;无偿出荷 和 继续无偿出荷。 - 无偿出荷本身是挺常用的&#xff0c;常见的例子就是送给客户样品&#xff1b; - 继续…

021-spring-springmvc-组件

SpringMVC的handMapping 比较重要的部分 比较重要的部分 比较重要的部分 关于组件的部分 这里以 RequestMappingHandlerMapping 为例子 默认的3个组件是&#xff1a; org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping org.springframework.web.servlet.mvc…

实现一个iOS晃动动画

有时候在开发中&#xff0c; 需要我们实现一个晃动动画&#xff0c; 达到一个提示的效果&#xff0c;如下图所示 思路&#xff0c; 我们要实现的本质上是一个旋转动画&#xff0c;然后 设置一个旋转角度&#xff0c;以底部中间为中心旋转&#xff0c; 左右各有一个旋转的角度…

C# 服务调用RFC函数获取物料信息,并输出生成Excel文件

这个例子是C#服务调用RFC函数&#xff0c;获取物料的信息&#xff0c;并生成Excel文件 上接文章&#xff1a;C#服务 文章目录 创建函数创建结构编写源代码创建批处理文件运行结果-成功部署服务器C#代码配置文件注意&#xff01;&#xff01; 创建函数 创建结构 编写源代码 创建…