4个8×8led显示屏组成的,16X16点阵飞机射击游戏带源码和仿真,下面是仿真原理图:
16X16点阵飞机射击游戏单片机源程序:
- /*******************************************************
- *******16X16点阵飞机射击游戏****************************
- ********************************************************
- **广东技术师范学院天河学院-电气工程系-电气062班*********
- ***************梁宏阁***********************************
- *******************************************************/
- ////////////////////////////////////////////////////////
- #include "reg51.h"
- #include "absacc.h"
- #include "intrins.h"
- #include "stdio.h"
- ///////////////////
- #define DENGFANKAISHIJIAN 30
- #define QUDOUDONGSHIJIAN 2
- /////////////
- sbit P21 =P2^1 ;
- sbit P22 =P2^2 ;
- sbit P23 =P2^3 ;
- sbit P24 =P2^4 ;
- #define P00 P0
- ////////////////////
- sbit A_L =P1^1 ; //左移动
- sbit A_R =P1^2 ; //右移动
- sbit A_F =P1^3 ; //射击
- sbit A_S =P1^4 ; //开始/暂停
- sbit A_T =P1^5 ; //退出
- ///////////////////////////////////
- #define ZUO(a) P00=a;P24=0;P24=1
- #define YOU(a) P00=a;P21=0;P21=1
- #define SHANG(a) P00=a;P22=0;P22=1
- #define XIA(a) P00=a;P23=0;P23=1
- //////////////////////////////////////////
- //////////////////////////////////////////
- typedef struct //"飞机"用结构体统一信息
- {
- unsigned char x; //飞机的X坐标,最大为9
- unsigned int t; //飞机头显示内容
- unsigned int w;//飞机尾显示内容
- } FEIJI;
- FEIJI feiji;//定义飞机变量
- ///////////////////////////
- idata char GoOrStay ;//状态标记-1为未开始,0为正在游戏,1为暂停,2为设置状态
- idata char TU_Y;//最接近飞机的Y轴标记自向下数,最上层为1,无层时为0
- idata char xuanze;//选择start为0否为1
- idata unsigned char Guan;//关数
- unsigned char TU[32];//16X16图像数组
- idata unsigned char time_a=0;
- idata unsigned int time_b=0;//定时器内和关数有关的增量
- ////////////////////////////////
- /*3x5字模*/
- unsigned char code S_3X5[10][5]={{0x0e,0x0a,0x0a,0x0a,0x0e}/*0*/,{0x04,0x0c,0x04,0x04,0x04}/*1*/,
- {0x0e,0x02,0x0e,0x08,0x0e}/*2*/,{0x0e,0x02,0x0e,0x02,0x0e}/*3*/,{0x0a,0x0a,0x0e,0x02,0x02}/*4*/,
- {0x0e,0x08,0x0e,0x02,0x0e}/*5*/,{0x0e,0x08,0x0e,0x0a,0x0e}/*6*/,{0x0e,0x02,0x02,0x02,0x02}/*7*/,
- {0x0e,0x0a,0x0e,0x0a,0x0e}/*8*/,{0x0e,0x0a,0x0e,0x02,0x0e}/*9*/,
- };
- /*start+setup字模*/
- unsigned char code start_setup[32]={
- 0x1c,0x07,0x09,0x02,0x6a,0xb2,0x8a,0xaa,
- 0xeb,0xb2,0x2a,0xaa,0xca,0xaa,0x00,0x00,
- 0x03,0x80,0x01,0x06,0x6d,0x55,0x89,0x56,
- 0xed,0x54,0x29,0x54,0xcd,0x74,0x00,0x00};
- unsigned char code start[32]={
- 0x1c,0x07,0x09,0x02,0x6a,0xb2,0x8a,0xaa,
- 0xeb,0xb2,0x2a,0xaa,0xca,0xaa,0x00,0x00,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- unsigned char code setup[32]={
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0x03,0x80,0x01,0x06,0x6d,0x55,0x89,0x56,
- 0xed,0x54,0x29,0x54,0xcd,0x74,0x00,0x00};
- /*STAY字模*/
- unsigned char code stay[32]={
- 0x00,0x00,0x1f,0x00,0x04,0x11,0x04,0x0a,
- 0x74,0x04,0x84,0xc4,0x85,0x24,0x65,0x24,
- 0x15,0x24,0x15,0xe4,0xe5,0x20,0x05,0x20,
- 0x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00
- };
- /*OVER字模*/
- unsigned char code over[32]={
- 0xaa,0xaa,0xff,0xff,0x00,0x00,0x00,0x06,
- 0x05,0x35,0x65,0x45,0x95,0x46,0x95,0x75,
- 0x95,0x45,0x65,0x45,0x02,0x35,0x00,0x00,
- 0xff,0xff,0x55,0x55,0xff,0xff,0x55,0x55
- } ;
- /*WIN字模*/
- unsigned char code win[32]={
- 0x55,0x55,0xff,0xff,0x00,0x00,0xa9,0x40,
- 0x55,0x40,0x55,0x40,0x48,0x80,0x00,0x00,
- 0x0a,0xa4,0x0a,0xaa,0x05,0x2a,0x00,0x00,
- 0xff,0xff,0x00,0x00,0xff,0xff,0xaa,0xaa
- };
- ///////////函数声明/////////////////////
- extern void feijitu(void); //根据飞机的x坐标写出它的头尾形状,再给回TU数组
- extern void ZHENGJIAYIXING(void);//增加一行
- extern void chuqihua(void);//初始化显示
- extern void DELAY(unsigned int a); //延时子函数a最大为十进制65535
- //extern unsigned char zhenli(unsigned char a);//整理调整函数
- extern void dian1616(unsigned char ZZ[]);//16X16显示主函数
- extern void guanshu(unsigned char n);//将当前关卡加入到数组
- extern void QuDouDong(unsigned int a);//去抖动,同时显示
- extern void SheJi(void); //射击调整函数
- extern void AnNiu_S(void);//判开始暂停按钮
- extern void AnNiu_T(void);//判断退出按钮
- extern void AnNiu_L(void);//判左移按钮
- extern void AnNiu_R(void);//判右移出按钮
- extern void AnNiu_F(void);//判射击按钮
- extern void AnNiu(void);//按钮合集
- extern void SHANstart(void);//闪START
- extern void SHANsetup(void);//闪SETUP
- extern void SHAN( char a);//闪0闪start,1闪setup
- extern void winORfail(void);//判断胜利还是失败
- ///////////////////////////////////////
- /////////////////////////以下为显示一个16X16/////
- void DELAY(unsigned int a) //延时子函数a最大为十进制65535
- {while(a--)
- ;
- }
- void dian1616(unsigned char ZZ[])//16X16主函数
- { unsigned char a,b; //a放行号,b放字在数组的序号
- if(GoOrStay!=2)
- feijitu(); //加入飞机位置状态
- guanshu(Guan); //关数
- b=0;
- XIA(0x00); //不送出下半部分
- for(a=0x01;a!=0;a=(a<<1)) //上半个字
- {
- DELAY(50) ;//延时一小段时间为看清楚
- ZUO(ZZ[b]) ; //调调整函数,送出左
- b++ ;
- YOU(ZZ[b]); //送出右
- b++ ;
- SHANG(a) ;//送出行号
- DELAY(50) ;//延时一小段时间为了字型显示更清楚
- ZUO(0) ; //消影
- YOU(0);
- }
- SHANG(0x00); //不送出上半部分
- for(a=0x01;a!=0;a=(a<<1)) //下半个字
- { DELAY(50) ;//延时一小段时间为看清楚
-
- ZUO(ZZ[b]) ; //调整函数,送出左
- b++ ;
- YOU(ZZ[b]); //送出右
- b++ ;
- XIA(a); //送出行号
- DELAY(50) ;//延时一小段时间为了字型显示更清楚
- ZUO(0) ; //消影
- YOU(0);
- }
- }
- //////////////////以上为显示一个16X16////
- void ZHENGJIAYIXING(void)//增加一行
- {
- char a;
- for(a=15;a>-1;a--)
- { TU[2*(a+1)]=TU[2*a];
- TU[2*(a+1)+1]=((TU[2*a+1]&0xe0)|(TU[2*(a+1)+1]&0x3f)); //保留信息状态区的内容
- }
- TU[0]=0xff; //补上第0行显示内容
- TU[1]=(0xe0|(TU[1]&0x3f)); //保留信息状态区的内容
- TU_Y=(TU_Y+1);
- }
- ////
- void feijitu(void) //根据飞机的x坐标,写出它的头尾形态,并再其给回TU数组
- {
- unsigned char a;
- feiji.t=0x8000;
- for(a=0;a<feiji.x;a++)
- {
- feiji.t>>=1; //右移一位
- }
- feiji.w=(((feiji.t|(feiji.t>>1)&0xffe0)|(feiji.t<<1))&0xffe0); //尾显示形态
- feiji.t=(feiji.t&0xffe0)|((unsigned int)(0x20|(TU[29]&0x3f))); //保留信息状态区的内容
- feiji.w=(feiji.w&0xffe0)|((unsigned int)(0x20|(TU[31]&0x3f))); //保留信息状态区的内容
- TU[28]=(unsigned char)(feiji.t>>8);
- TU[29]=(unsigned char)feiji.t;
- TU[30]=(unsigned char)(feiji.w>>8);
- TU[31]=(unsigned char)feiji.w;
- }
- ///
- void guanshu(unsigned char n) //将当前关卡加入到数组
- {
- char a;
- if(n<10)
- {
- for(a=2;a<7;a++)
- {
- TU[2*a+1]=(TU[2*a+1]&0xe0)|S_3X5[n][a-2];
- }
- }
- }
- ///////////////////////////
- void SHANstart(void) //闪start
- { char a;
- a=15;
- while(a--)
- {
- dian1616(setup); //显示
- AnNiu();
- }
- a=15;
- while(a--)
- { dian1616(start_setup); //显示
- AnNiu();
- }
- }
- //
- void SHANsetup(void) //闪setup
- { char a;
- a=15;
- while(a--)
- {
- dian1616(start); //显示
- AnNiu();
- }
- a=15;
- while(a--)
- {
- dian1616(start_setup); //显示
- AnNiu();
- }
- }
- //
- void SHAN( char a)//a决定0闪start,1闪setup
- {
- if(a==0)
- SHANstart();
- else
- SHANsetup();
- }
- /////////////////////////////////
- void QuDouDong(unsigned int a)//去抖动,同时显示
- {
- while(a--)
- {
- if(GoOrStay!=2)
- feijitu(); //加入飞机位置状态
- guanshu(Guan);//加入显示关数
- dian1616(TU); //16x16点阵显示
- }
- }
- ///////
- void AnNiu_S(void)//判开始按钮
- {
- unsigned int n;//超时退出变量
- A_S=1;
- if(A_S==0)
- {
- A_S=1;
- QuDouDong(QUDOUDONGSHIJIAN);//去抖动
- if(A_S==0)
- {
- if(xuanze==0)//如为开始
- {
- if(GoOrStay==-1)
-
- GoOrStay=0;//标记为开始
- else
- {
- if(GoOrStay==0)
- GoOrStay=1;//如果已开始则暂停
- else
- if(GoOrStay==1)
- {GoOrStay=0;//如果已暂停则开始
- }
- }
-
- }
- if(GoOrStay==2)//如为设置
- { GoOrStay=-1;//标记为未开始
- xuanze=0;
- }
- if(xuanze==1)//如为选择
- GoOrStay=2;
-
- //等手放开
- n=DENGFANKAISHIJIAN;
- while(A_S==0)
- {
- A_S=1;
- dian1616(TU); //显示
- n--;
- if(n==0)
- break;//按钮超时退出
- }
- }
- }
- }
- ////
- void AnNiu_L(void)//左按钮
- {
- unsigned int n;//超时变量
- A_L=1;
- if(A_L==0)
- {
- A_L=1;
- QuDouDong(QUDOUDONGSHIJIAN); //去抖动
- if(A_L==0) //确认进入
- {
- if(GoOrStay==0)//如果正在游戏则用左右功能
- {
- if(feiji.x==0)//如果是最左则去最右
- {
- feiji.x=9;
- }
- else
- {
- feiji.x--;//沿x轴左移
- }
- }
- if(GoOrStay==-1)//如果未开始则为上下选择功能
- {
- if(xuanze==0)
- xuanze=1;
- else
- xuanze=0;
- }
- if(GoOrStay==2)//如果为设置则选择关数
- {
- if(Guan==9)
- Guan=0;
- else
- Guan++;
- }
- //等手放开
- n=DENGFANKAISHIJIAN;
- while(A_L==0)
- {
- A_L=1;
- dian1616(TU); //显示
- n--;
- if(n==0)
- break;//按钮超时退出
- }
- }//
- }
- }
- ///
- ////
- void AnNiu_R(void)//右按钮
- {
- unsigned int n;//超时变量
- A_R=1;
- if(A_R==0)
- {
- A_R=1;
- QuDouDong(QUDOUDONGSHIJIAN); //去抖动
- if(A_R==0) //确认进入
- {
- if(GoOrStay==0)//如果正在游戏则用左右功能
- {
- if(feiji.x==9)//如果是最右则去最左
- {
- feiji.x=0;
- }
- else
- {
- feiji.x++;//沿x轴右移
- }
- }
- if(GoOrStay==-1)//如果未开始则为上下选择功能
- {
- if(xuanze==0)
- xuanze=1;
- else
- xuanze=0;
- }
- if(GoOrStay==2)//如果为设置则选择关数
- {
- if(Guan==0)
- Guan=9;
- else
- Guan--;
- }
- //等手放开
- n=DENGFANKAISHIJIAN;
- while(A_R==0)
- {
- A_R=1;
- dian1616(TU); //显示
- n--;
- if(n==0)
- break;//按钮超时退出
- }
- }//
- }
- }
- ///
- //////
- void AnNiu_T(void)//退出
- {
- unsigned int n;
- A_T=1;
- if(A_T==0)
- {
- A_T=1;
- if(A_T==0)
- {
- A_T=1;
- QuDouDong(QUDOUDONGSHIJIAN);//去抖动
- if(A_T==0)
- {
- chuqihua(); //初始化
- //等手放开
- n=DENGFANKAISHIJIAN;
- while(A_T==0)
- {
- A_T=1;
- dian1616(TU); //显示
- n--;
- if(n==0)
- break;//按钮超时退出
- }
- }
- }
- }
- }
- ///
- ///
- void SheJi(void) //射击调整函数
- { idata char y;
-
- y=TU_Y;
-
- if(y!=0)
- {
- if(feiji.x<8)//找出最凹的y坐标
- { //在左半面找
- for(;((~TU[2*(y-1)])&(0X80>>feiji.x))==((unsigned char)(feiji.t>>8));y--)
- ;
- }
- else
- { //在右半面找
- for(;((~TU[2*(y-1)+1])&(0X80>>(feiji.x-8)))==((unsigned char)(feiji.t&0xc0));y--)
- ;
-
- }
- TU[2*(y-1)]=(unsigned char)((~(feiji.t>>8))&TU[2*(y-1)]);
- TU[2*(y-1)+1]=(unsigned char)(~((feiji.t)&0x00c0)&TU[2*(y-1)+1]);
-
- if((TU[2*(TU_Y-1)]==0)&&((TU[2*(TU_Y-1)+1]&0xc0)==0))
- {TU_Y--;
-
- }
- }
- dian1616(TU); //显示
- }
- void AnNiu_F(void)//判射击按钮
- { unsigned int n;
- A_F=1;
- if(A_F==0)
- {
- A_F=1;
- QuDouDong(QUDOUDONGSHIJIAN);//去抖动
- if(A_F==0)
- {
- if(GoOrStay==0)
- SheJi();//射击调整函数
- //等手放开
- n=2; //射击键超时少一点
- while(A_F==0)
- {
- A_F=1;
- dian1616(TU); //显示
- n--;
- if(n==0)
- break;//按钮超时退出
- }
- }
- }
- }
- void AnNiu(void) //按钮实现
- {
- AnNiu_S() ;//判开始暂停
- AnNiu_L() ;//判断左按钮
- AnNiu_R() ; //判断右按钮
- AnNiu_F() ; //判断射击
- AnNiu_T() ;//判断退出
-
- }
- ////
- void FAIL(void) //失败画面
- {
- idata unsigned int n;
- n=300;
- while(n--)
- dian1616(over);
- chuqihua();//初始化
- }
- void WINN(void)//胜利
- {
- idata unsigned int n;
- n=300;
- while(n--)
- dian1616(win);
- chuqihua(); //初始化
- }
- void winORfail(void)//判断胜利还是失败
- {
- if(Guan>9)//10关全过胜利
- WINN();//胜利画面
- else
- if(TU_Y>14)
- FAIL();
-
- }
- ////
- void SheZhi(void)//设置画面
- {
- TU[30]=TU[28]=0xff;//去掉飞机图形
- TU[29]|=0XC0;
- TU[31]|=0XC0;
-
- guanshu(Guan);
- while(GoOrStay==2)
- {
- dian1616(TU); //显示
- AnNiu();
- }
- }
- //////菜单////
- void caidan(void)
- {
- while(GoOrStay==-1|GoOrStay==2)//如果还没开始
- {
- if(GoOrStay==-1)
- SHAN(xuanze);//选择画面
- if(GoOrStay==2)
- SheZhi();//设置画面
- }
- }
- ///////////////////////////////////////////
- void TIME1(void) interrupt 3 //定时器1
- { TH1=0X3C;
- TL1=0XB0;//定时器初值
- EA=0;
- P3=0XF0;
-
- //定时器处理
- time_a++;
- if(time_a==(40-Guan*2))
- {
- ZHENGJIAYIXING();
- time_a=0;}
- time_b++;
- if(time_b==1200)
- {Guan++;
- time_b=0;
- }
- EA=1;
- TR1=1;
- TF1=0;
- }
- //定时器初始化
- void dishiqi(void)
- {
- TMOD=0X10;//定时器工作方式1
- TH1=0X3C;
- TL1=0XB0;//定时器初值
- ET1=1;
- EA=1;
- TF1=0;
- TR1=0;//关定时器
- }
- ////////////////////初始化//////////////////
- void chuqihua(void)//初始显示内容为0
- {
- idata char a;
- dishiqi() ;//定时器初始化
- for(a=0;a<32;a++)
- TU[a]=0x0;
- TU_Y=0;
- A_L =1 ; //左移动
- A_R =1 ; //右移动
- A_F =1 ; //射击
- A_S =1 ; //开始/暂停
- A_T =1 ; //退出
- P21=1;P22=1;P23=1;P24=1;
- for(a=0;a<16;a++)//画上边
- {
- TU[2*a+1]|=0x20;
- }
- ZHENGJIAYIXING(); //加一层
- feiji.x=5; //初始飞机位置
- GoOrStay=-1; //置状态标记为未开始
- Guan=0;//初始关卡为0
-
- xuanze=0;
- }
- /////////////////////////////////
-
-
- void main() //程序主函数
- {
- chuqihua();//初始化
- while(1)
- {
- if(GoOrStay==-1)
- caidan();
- AnNiu(); //按钮
- if(GoOrStay==0)
- {dian1616(TU); //显示
- TR1=1;//游戏时开定时器
- }
- winORfail();//判断是否胜利
- if(GoOrStay==1) //暂停
- {dian1616(stay);
- TR1=0;//关定时器
- }
- }
- }
复制代码
仿真工程文件和程序源码下载:
16X16点阵飞机射击游戏.rar
(29.01 KB, 下载次数: 69)
|