标题:
单片机16X16点阵飞机射击游戏 仿真+源程序
[打印本页]
作者:
zhfirst
时间:
2017-2-28 14:51
标题:
单片机16X16点阵飞机射击游戏 仿真+源程序
4个8×8led显示屏组成的,16X16点阵飞机射击游戏带源码和仿真,下面是仿真原理图:
0.png
(36.92 KB, 下载次数: 90)
下载附件
2017-3-1 04:28 上传
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;//关定时器
}
}
}
复制代码
0.png
(65.78 KB, 下载次数: 67)
下载附件
2017-3-1 04:27 上传
仿真工程文件和程序源码下载:
16X16点阵飞机射击游戏.rar
(29.01 KB, 下载次数: 69)
2017-3-1 04:29 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1