打地鼠游戏设计论文

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

打地鼠游戏机(B题)
2011级华工猫酷队
队员李腾辉陈健锋蔡旭坤
我们的作品录像:/v_show/id_XMzkzMTIxMjgw.html
公布论文和全部源码,仅供学习
摘要:本作品采用STC12C5A60S22单片机作为主控芯片,选取1602液晶作为显示屏,通过红外接收器用遥控控制游戏机的开机和关机。

游戏程序应用C语言编译,主要使用函数为随机函数和键盘扫描函数。

通过随机函数产生一个随机数,该随机数使显示屏对应位置出现“O”,同时对应的LED被点亮以代表地鼠的随机出现。

通过键盘扫描函数,使每个按键各对应一个LED灯,通过按下该键使相应LED灯熄灭。

本系统配有开场音乐和游戏音效。

关键词:单片机、随机函数、键盘扫描函数、音乐
Abstract: this work using STC12C5A60S2 microcontroller as the main control chip select LCD as a display,1602, through the infrared receiver remote control game startup and shutdown. This game program using C language editing, the main function used are the random function and keyboard scan function. Use random functions to generate a random number, at the same time the random number to display the corresponding position"0" and the corresponding LED is illuminated to represent the random hamster. Through the keyboard scan function, make each key corresponds to a LED lamp, by pressing this key to the corresponding LED lights. The whole process has background music and game sound.
Key words: SCM, random function, keyboard scan function, music
游戏说明:
本游戏由8个LED灯分别代表8只地鼠,当地鼠跳出来时显示屏对应位置出现“O”,同时该地鼠对应的LED灯被点亮,在限定时间内按下相应按键后,对应LED灯熄灭,同时“O”闪烁一下,表示打中该地鼠。

游戏规则为,打中1~8号地鼠,每只得一分,在每局限定的时间30秒内得满当前关所需分即可进入一下关。

游戏分四关:第一关,地鼠跳出时间长,得10分后,游戏进入第二关;第二关,地鼠跳出时间较短,得15分后,游戏进入第三关;第三关,地鼠跳出时间更快,得20分后,游戏进入第四关。

第四关,得25分可过,但超越人类反应极限,不作阐述。

方案比较、设计:
方案一:用STC89C52作主控芯片,灯光表示地鼠,用红外遥控系统,用两层板完成整个电路。

方案二:用STC12C5A60S2作主控芯片,用灯光和液晶“0”表示地鼠,加入音乐,用红外遥控系统,用一层板完成整个电路。

显然,方案二更加适合,因为方案二中采用的主控芯片运算的速度要比方案一所用芯片快得多(达8倍),ram足够,而且游戏系统使用了定时中断函数,用STC12C5A60S2芯片会得到更快的响应。

而且方案二加入了液晶显示和音乐,使游戏不那么单调,使玩家更好体现游戏的过程。

最后,用一层板可以减少很多飞线,而且布局美观。

电路原理:
本系统包含六个子电路模块,分别为单片机系统电路、流水灯电路、蜂鸣器电路、2*4矩阵键盘、遥控红外接收电路、1602LCD显示屏模块。

单片机系统电路
流水灯电路蜂鸣器电路
2*4矩阵键盘
遥控红外接收电路1602液晶显示模块电路
各模块整合并接上电源后,通过遥控打开游戏系统。

随后,单片机系统驱动游戏系统进入初始化模式,同时蜂鸣器系统被驱动开始播放背景音乐。

游戏开始后,背景音乐停止,单片机系统开始随机驱动8个LED灯点亮,同时液晶上对应位置出现O,蜂鸣器系统同时被驱动,发出“嘀”一声。

此过程中,系统不断计时,不断刷新分数。

游戏实现代码:
//begin_display//
#ifndef BeginDisplay_H
#define BeginDisplay_H
//#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit dula=P2^6;
sbit wela=P2^7;
//sbit bemp=P2^3;
int runlight[9]={0xff,0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f} ;
uchar run_light_num,kkk; //流水灯亮到哪一盏,kkk为定时0计数uchar begin_flag,time_counter,mouse_hit;
void delay(uint z) //延时1ms
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delayus(unsigned char x) //最新12c5a延时1us {
while(x--)
{
_nop_();
_nop_();
_nop_();
}
}
void delayms(unsigned char x) //最新12c5a延时1毫秒{
unsigned char i,j,k;
for(k = x; k > 0; k--)
for(i = 22; i > 0; i--)
for(j = 250; j > 0; j--);
}
void write_com(uchar com)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38); //显示模式设置
write_com(0x0f); //开显示、光标、闪烁
write_com(0x06); //读写一个后地址加一,不移屏write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80+0x01); //起始指针位置
}
void begin_display()
{
int i;
uchar code table[]="##Whack a Mole##";
uchar code table1[]=" By CoolCat ";
init();
write_com(0x80+0x10) ;
for(i=0;i<16;i++) //写入第一行字
{
write_data(table[i]) ;
delayms(5);
}
write_com(0x80+0x50) ; //坐标变至下一行for(i=0;i<16;i++)
{
write_data(table1[i]) ;
delayms(5);
}
for(i=0;i<16;i++)
{
write_com(0x18); //整屏左移一位
delayms(100);
}
for(i=0;i<5;i++) //整屏闪烁
{
write_com(0x08);
delayms(50);
write_com(0x0f);
delayms(50);
}
while(begin_flag);
}
/*void light_run()
{
int i;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
EA=1;//开中断
ET0=1;
TR0=1; //开定时0
for(j=0;j<4;j++)
for(i=1;i<9;i++)
{
P0=runlight[i];
if(i==8) i==0;
} */
void ready_go()
{
int i;
//bemp=1; //初始化不响
uchar code table3[]="Ready ";
uchar code table4[]="Go" ;
uchar code table5[]="5 4 3 2 1";
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80+0x01) ;
for(i=0;i<9;i++) //写入第一行字
{
write_data(table5[i]) ;
bemp=~bemp;
delayms(500);
}
bemp=1;
write_com(0x80+0x40) ; //坐标变至下一行
for(i=0;i<6;i++) //display "ready "再停顿一下
{
write_data(table3[i]) ;
delayms(50);
}
delayms(500);
for(i=0;i<2;i++)
{
write_data(table4[i]) ;
delayms(50);
}
write_data(0x7e) ;
delayms(50);
write_data(0x7e) ; //向右方向头
delayms(50);
/*for(i=0;i<16;i++)
{
write_com(0x18); //整屏左移一位
delay(300);
} */
for(i=0;i<2;i++) //整屏闪烁
{
write_com(0x08);
delayms(50);
write_com(0x0f);
delayms(50);
}
}
/*void Timer00() interrupt 1 //该中断为流水灯转
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
run_light_num++;
P0=runlight[run_light_num] ; //流水灯亮
if (run_light_num==8) run_light_num=1;
} */
#endif
//GamingDisplay_h//
#ifndef GamingDisplay_h
#define GamingDisplay_h //有静止的time_score() , 动态的score_display() ,
//定时器2
uchar iii; //定时器2的i
uchar numm_temp=0x82;
uchar hole[]={ 0x80,0x82,0x83,0x84,
0x85,0x86,0x87,
0x88,0x8b } ; //8b王牌鼠
void first_line_mouse1602()
{
int i;
uchar code table8[]=" #_______#^_^# " ; //8个地鼠8是王牌地鼠打中加2分
write_com(0x80);
for(i=0;i<16;i++)
{
write_data(table8[i]) ;
delay(1);
}
}
void time_score() //显示时间和分数的单词静态加上显示地鼠{ //尼码还是得按5次才有显示int i; //不要全部用i了
uchar code table6[]="Time ";
uchar code table7[]="Score ";
//dula=0;
//wela=0;
//lcden=0;
//write_com(0x38); //显示模式设置
write_com(0x0c); //不要光标,闪烁
//write_com(0x06); //读写一个后地址加一,不移屏
write_com(0x01); //清屏,显示清0,数据指针清0
write_com(0x80+0x01); //起始指针位置
//write_com(0x0c);
delay(5);
first_line_mouse1602();
delayms(5);
write_com(0x80+0x40) ;
for(i=0;i<5;i++) //第二行写时间这个不用动{
write_data(table6[i]) ;
delayms(5);
}
write_com(0x80+0x48) ; //第二行后分数
for(i=0;i<6;i++)
{
write_data(table7[i]) ;
delayms(5);
}
}
void level_1_display()
{
uchar code table8[]="####Level 1#### ";
int i;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table8[i]);
delayms(50);
}
delayms(500);
}
void level_2_display()
{
uchar code table8[]="####Level 2#### ";
int i;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table8[i]);
delayms(50);
}
delayms(500);
}
void level_3_display()
{
uchar code table8[]="####Level 3#### ";
int i;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table8[i]);
delayms(50);
}
delayms(500);
}
void level_4_display()
{
uchar code table8[]="##BT##Level 4## ";
int i;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table8[i]);
delayms(50);
}
delayms(500);
}
void congratulation() //过关后的庆贺
{
int i;
uchar code table9[]="congratulation!!";
uchar code table10[]="Your score" ;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table9[i]);
delayms(50);
}
write_com(0x80+0x41);
for(i=0;i<10;i++)
{
write_data(table10[i]);
delayms(50);
}
write_com(0x80+0x4c) ;
write_data(mouse_hit/10+0x30) ; //显示分数十位
//delay(5);
write_data(mouse_hit%10+0x30) ; //显示分数个位
write_com(0x50);
}
void game_over() // 失败
{
int i;
uchar code table9[]=" Gmae Over ";
uchar code table10[]="Your score" ;
write_com(0x01); //清屏,显示清0,数据指针清0 write_com(0x80); //起始指针位置
for(i=0;i<16;i++)
{
write_data(table9[i]);
delayms(50);
}
write_com(0x80+0x41);
for(i=0;i<10;i++)
{
write_data(table10[i]);
delayms(50);
}
write_com(0x80+0x4c) ;
write_data(mouse_hit/10+0x30) ; //显示分数十位
//delay(5);
write_data(mouse_hit%10+0x30) ; //显示分数个位write_com(0x50);
}
void mouse_1602display(uchar numm)
{
//first_line_mouse1602();
write_com(hole[numm_temp]) ;
write_data(0x5f) ; //0x5f="_"
write_com(hole[numm]) ;
write_data(0x4f) ; // 0x4f=大O
numm_temp=numm;
write_com(0x50);
}
void init_timer2()
{
RCAP2H=(65536-50000)/256; //重装载计数器赋初值
RCAP2L=(65536-50000)%256;
ET2=1; //开定时器2中断
EA=1; //开总中断
}
void gaming_display()
{
init_timer2();
TR2=1; //开启定时器,并设置为自动重装载模式}
/*void timer2() interrupt 5 //调用定时器2,自动重装载模式
{
TF2=0; //定时器2的中断标志要软件清0
iii++; //计数标志自加1
if(iii==8)
{
iii=0; //将静态变量清0
score_display();
}
} */
#endif
//mouse_level//
#ifndef MouseLevel_H
#define MouseLevel_H //有time_counter, mouse_hit ,random , key_scan ,
// mouse_out , 两个定时中断0和1
#define level_1 50
#define level_2 70
#define level_3 80 //不同等级对应不同的地鼠数
#define level_4 100
uchar seed,keyscan_num,
temp_num,random_num; //声明时间种子,键盘数,临时数,计时数
//击中地鼠数
int iiii;
int deng[9]={0xff,0xfe,0xfd,0xfb,0xf7,
0x7f,0xbf,0xdf,0xef} ;
int random()
{
uchar j,k;
srand(seed);
k=(rand()%8+1);
j=1+(int)(16.0*rand()/65535); //j和k是两种实现随机机算法,j算法优return(k) ;
}
uchar keyscan();
void mouse_out(uchar mouse_num,uchar speed) //第一个变量是老鼠数,第二个是速度
{
uchar i,kk, random_temp ,keyscan_temp;
keyscan_num=0;
random_num=1;
mouse_hit=0;
time_counter=30; //初始化时间和分数
TMOD=0X11;
TH0=(65536-61440)/256; //定时中断初始化开了2个中断
TL0=(65536-61440)%256; //0是给随机函数用的,1是进行定时扫描键盘的TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
EA=1;//开中断
ET0=1;
TR0=1; //开定时0
ET1=1;
TR1=1;
for(kk=0;kk<mouse_num;kk++)
{
random_temp=random(); //防止使用过程中random()变化
if(random_num!=random_temp) //random_num不变要让keyscan num 保持一段时间
//产生不重合的随机数
random_num=random_temp;
else if (random_temp>=7)
random_num=random_temp-1;
else random_num=random_temp+1;
P1=deng[random_num];
bemp=0;
delayms(50);
bemp=1;
//for(i=0;i<100;i++) delay(99);
for(i=0;i<speed;i++) //此处的i用于调节速度
{
if(random_num==keyscan_num)
{
P1=0xff ;
//i++; //此处的加是击中后出鼠速度会加快
if(keyscan_num!=keyscan_temp) ////要解决不断刷分的问题{
mouse_hit++;
if(random_num==8) mouse_hit++; //神鼠加2分
first_line_mouse1602();
}
//keyscan_num=9;
keyscan_temp=keyscan_num;
}
delayms(1000);
}
if(time_counter==0) break;
//delay(2000);
}
}
/********************************************************* *****************************主程序*********************** *********************************************************/ void game_start()
{
int i;
level_1_display(); //第一关10分过关
time_score();
mouse_out(level_1,4);
if(mouse_hit>=10)
{
congratulation();
for(i=0;i<3;i++)
delayms(500);
mouse_hit=0;
}
else
{
game_over();
while(1);
}
level_2_display(); //第二关15分过关
time_score();
mouse_out(level_2,3); //这个函数里面有开定时设置时间if(mouse_hit>=15)
{
congratulation();
for(i=0;i<3;i++)
delayms(500);
mouse_hit=0;
}
else
{
game_over();
while(1);
}
level_3_display(); //第三关20分过关
time_score();
mouse_out(level_3,2); //这个函数里面有开定时设置时间if(mouse_hit>=20)
{
congratulation();
for(i=0;i<3;i++)
delayms(500);
mouse_hit=0;
}
else
{
game_over();
while(1);
}
while(1);
//gaming_display();
}
/*********************************************************
**********************************************************
*********************************************************/
void Timer0() interrupt 1//该中断是为random()提供时间种子服务,并计时{
if(music_flag==1)
{
bemp = !bemp;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0;
kkk++;
if(kkk==100)
{
run_light_num++;
P1=runlight[run_light_num] ; //流水灯亮
if (run_light_num==8) run_light_num=0;
kkk=1;
}
}
else
{TH0=(65536-61440)/256;
TL0=(65536-61440)%256;
seed=seed+iiii; //产生更混乱的时间种子,除去重复的bug if(seed>100) seed=0; //时间种子服务
iiii++;
if(iiii%3==1)
{
mouse_1602display(random_num); //1602液晶显示地鼠
write_com(0x80+0x4e) ;
write_data(mouse_hit/10+0x30) ; //显示分数十位
//delay(5);
write_data(mouse_hit%10+0x30) ; //显示分数个位
write_com(0x50);
}
if(iiii==1) //经过计算15次恰为1秒,time_counter用以显示剩余时间
{
time_counter-- ;
if(time_counter==0)
{
TR0=0; //关中断
TR1=0;
P1=deng[0]; //灯全灭
first_line_mouse1602();
}
write_com(0x80+0x45) ;
write_data(time_counter/10+0x30) ; //显示时间十位
//delay(5);
write_data(time_counter%10+0x30) ; //显示时间个位
//delay(5);
write_com(0x50);
}
if(iiii==19) iiii=0; }
}
void Timer1() interrupt 3//该中断时定时进行键盘扫描服务
{
TH1=(65536-5000)/256;
TL1=(65536-5000)%256;
temp_num=keyscan(); //这个判断语句防止不断收到0 if(temp_num) keyscan_num=temp_num;
}
uchar keyscan()
{
uchar num,temp;
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0) //按下去
{
delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=1;
break;
case 0xde:num=5;
break;
/* case 0xbe:num=4;
break;
case 0x7e:num=8;
break; */
}
/* while(temp!=0xf0) //松手才有效{
temp=P3;
temp=temp&0xf0;
} */
}
}
P3=0xfd;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=2;
break;
case 0xdd:num=6;
break;
/* case 0xbd:num=3;
break;
case 0x7d:num=7;
break; */
}
/* while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
} */ }
}
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:num=3;
break;
case 0xdb:num=7;
break;
/* case 0xbb:num=2;
break;
case 0x7b:num=6;
break; */
}
/* while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
} */ }
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=4;
break;
case 0xd7:num=8;
break;
/* case 0xb7:num=1;
break;
case 0x77:num=5;
break; */
}
/* while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
} */ }
}
return num;
}
#endif
//music//
#ifndef __SOUNDPLAY_H_REVISION_FIRST__
#define __SOUNDPLAY_H_REVISION_FIRST__
#include <reg52.h>
//******************************************************************** ******
#define SYSTEM_OSC 11059200//12000000 //定义晶振频率12000000HZ
#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔
sbit bemp = P2^3; //定义输出管脚
int music_flag;
idata unsigned int FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
idata unsigned char SignTab[7] = { 0,2,4,5,7,9,11 }; //1~7在频率表中的位置
idata unsigned char LengthTab[7]= { 1,2,4,8,16,32,64 };
idata unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存idata unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存//******************************************************************** ******
void InitialSound(void)
{
bemp = 1;
Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值(10ms的初装值)
Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256; // 计算TH1应装入的初值
TH1 = Sound_Temp_TH1;
TL1 = Sound_Temp_TL1;
TMOD |= 0x11;
ET0 = 1;
ET1 = 0;
TR0 = 0;
TR1 = 0;
EA = 1;
}
/*void BeepTimer0(void) interrupt 1 //音符发生中断
{
if(music_flag==1)
{
bemp = !bemp;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0;
}
/* else
{TH0=(65536-61440)/256;
TL0=(65536-61440)%256;
seed=seed+iiii; //产生更混乱的时间种子,除去重复的bug if(seed>100) seed=0; //时间种子服务
iiii++;
if(iiii%3==1)
{
mouse_1602display(random_num); //1602液晶显示地鼠
write_com(0x80+0x4e) ;
write_data(mouse_hit/10+0x30) ; //显示分数十位
//delay(5);
write_data(mouse_hit%10+0x30) ; //显示分数个位
write_com(0x50);
}
if(iiii==1) //经过计算15次恰为1秒,time_counter用以显示剩余时间
{
time_counter-- ;
if(time_counter==0)
{
TR0=0; //关中断
TR1=0;
P1=deng[0]; //灯全灭
first_line_mouse1602();
}
write_com(0x80+0x45) ;
write_data(time_counter/10+0x30) ; //显示时间十位
//delay(5);
write_data(time_counter%10+0x30) ; //显示时间个位
//delay(5);
write_com(0x50);
}
if(iiii==19) iiii=0; } */
/* bemp = !bemp;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0; */
//}
//******************************************************************** ******
void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
idata unsigned int NewFreTab[12]; //新的频率表
idata unsigned char i,j;
idata unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
idata unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表{
j = i + Signature;
if(j > 11)
{
j = j-12;
NewFreTab[i] = FreTab[j]*2;
}
else
NewFreTab[i] = FreTab[j];
if(Octachord == 1)
NewFreTab[i]>>=2;
else if(Octachord == 3)
NewFreTab[i]<<=2;
}
SoundLength = 0;
while(Sound[SoundLength] != 0x00) //计算歌曲长度
{
SoundLength+=2;
}
Point = 0;
Tone = Sound[Point];
Length = Sound[Point+1]; // 读出第一个音符和它时时值
LDiv0 = 12000/Speed; // 算出1分音符的长度(几个10ms) LDiv4 = LDiv0/4; // 算出4分音符的长度
LDiv4 = LDiv4-LDiv4*SOUND_SPACE; // 普通音最长间隔标准TR0 = 0;
TR1 = 1;
while(Point < SoundLength)
{
SL=Tone%10; //计算出音符
SM=Tone/10%10; //计算出高低音
SH=Tone/100; //计算出是否升半
CurrentFre = NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率
if(SL!=0)
{
if (SM==1) CurrentFre >>= 2; //低音
if (SM==3) CurrentFre <<= 2; //高音
Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
Sound_Temp_TH0 = Temp_T/256;
Sound_Temp_TL0 = Temp_T%256;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿}
SLen=LengthTab[Length%10]; //算出是几分音符
XG=Length/10%10; //算出音符类型(0普通1连音2顿音)
FD=Length/100;
LDiv=LDiv0/SLen; //算出连音音符演奏的长度(多少个10ms)
if (FD==1)
LDiv=LDiv+LDiv/2;
if(XG!=1)
if(XG==0) //算出普通音符的演奏长度
if (SLen<=4)
LDiv1=LDiv-LDiv4;
else
LDiv1=LDiv*SOUND_SPACE;
else
LDiv1=LDiv/2; //算出顿音的演奏长度
else
LDiv1=LDiv;
if(SL==0) LDiv1=0;
LDiv2=LDiv-LDiv1; //算出不发音的长度
if (SL!=0)
{
TR0=1;
for(i=LDiv1;i>0;i--) //发规定长度的音
{
while(TF1==0);
TH1 = Sound_Temp_TH1;
TL1 = Sound_Temp_TL1;
TF1=0;
}
}
if(LDiv2!=0)
{
TR0=0; bemp=1;
for(i=LDiv2;i>0;i--) //音符间的间隔
{
while(TF1==0);
TH1 = Sound_Temp_TH1;
TL1 = Sound_Temp_TL1;
TF1=0;
}
}
Point+=2;
Tone=Sound[Point];
Length=Sound[Point+1];
}
bemp = 1;
}
//********************************************************************
******
//*****************************Music********************************** ********************
//挥着翅膀的女孩
/*unsigned char idata Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,
0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,
0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,
0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,
0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,
0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,
0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,
0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,
0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,
0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,
0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
0x15,0x03, 0x17,0x03,
0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,
0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,
0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,
0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,
0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,
0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,
0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,
0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,
0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
0x16,0x66, 0x17,0x04,
0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,
0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,
0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02,
0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,
0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};
//同一首歌
unsigned char idata Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,
0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,
0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,
0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,
0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,
0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,
0x1A,0x01, 0x19,0x02, 0x19,0x03,
0x1A,0x03, 0x1B,0x02,
0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,
0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,
0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,
0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,
0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,
0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,
0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,
0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,
0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,
0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,
0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,
0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,
0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,
0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,
0x00,0x00 };
//两只蝴蝶
unsigned char idata Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,
0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,
0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,
0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,
0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,
0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,
0x19,0x03, 0x19,0x03, 0x1A,0x03,
0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,
0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,
0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,
0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,
0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,
0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,
0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,
0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,
0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,
0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,
0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,
0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,
0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,
0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
0x17,0x02, 0x1A,0x03, 0x1A,0x03,
0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,
0x10,0x03, 0x15,0x00, 0x00,0x00 }; */ unsigned char code Super[]={ 0x17,0x0D, 0x17,0x03, 0x17,0x0D, 0x15,0x0E, 0x17,0x04,
0x19,0x03, 0x0F,0x03, 0x15,0x03, 0x0F,0x03, 0x0D,0x03,
0x10,0x04, 0x11,0x0D, 0x11,0x04, 0x10,0x0D, 0x0F,0x03,
0x17,0x0D, 0x19,0x0E, 0x1A,0x04, 0x18,0x0E, 0x19,0x04,
0x17,0x04, 0x15,0x0E, 0x16,0x0E, 0x11,0x03, 0x15,0x03,
0x0F,0x03, 0x0D,0x03, 0x10,0x0D, 0x11,0x04, 0x11,0x0E,
0x10,0x03, 0x0F,0x0E, 0x17,0x03, 0x19,0x0D, 0x1A,0x03,
0x18,0x0D, 0x19,0x03, 0x17,0x0D, 0x16,0x0E, 0x15,0x04,
0x11,0x02, 0x19,0x03, 0x18,0x0E, 0x18,0x0E, 0x17,0x03,
0x17,0x0D, 0x0F,0x04, 0x10,0x0D, 0x15,0x03, 0x10,0x0E,
0x15,0x0E, 0x16,0x03, 0x19,0x0E, 0x18,0x04, 0x18,0x0D,
0x17,0x03, 0x17,0x0D, 0x1F,0x03, 0x1F,0x0D, 0x1F,0x03,
0x19,0x0E, 0x18,0x0E, 0x18,0x04, 0x17,0x0D, 0x17,0x04,
0x0F,0x04, 0x10,0x04, 0x15,0x0D, 0x10,0x0E, 0x15,0x04,
0x16,0x04, 0x17,0x03, 0x16,0x03, 0x15,0x04, 0x19,0x04,
0x00,0x00 };
unsigned char code fun[]={ 0x17,0x02, 0x17,0x02, 0x18,0x02, 0x19,0x02, 0x19,0x02,
0x18,0x02, 0x17,0x02, 0x16,0x02, 0x15,0x02, 0x15,0x02,
0x16,0x02, 0x17,0x02, 0x17,0x66, 0x16,0x02, 0x16,0x01,
0x00,0x00} ;
unsigned char code sad[]={0x23,0x02, 0x23,0x02, 0x20,0x02, 0x20,0x02, 0x23,0x02,
0x23,0x02, 0x24,0x02, 0x24,0x02, 0x24,0x02, 0x21,0x02,
0x21,0x02, 0x24,0x02, 0x24,0x02, 0x25,0x02, 0x24,0x0E,
0x23,0x04, 0x23,0x02, 0x23,0x0E, 0x24,0x04, 0x25,0x0E,
0x24,0x0E, 0x23,0x0E, 0x25,0x04, 0x24,0x0E, 0x23,0x0E,
0x22,0x0E, 0x24,0x04, 0x00,0x00};
//******************************************************************** ***************
#endif
void super_mary()
{
music_flag=1;
InitialSound();
// light_run();
// while(1)
Play(Super,0,3,100);
music_flag=0;
}
//red_line_begin//
#ifndef RedLine_H
#define RedLine_H
#include <reg52.h>
#define uchar unsigned char
//sbit light=P1^0;
uchar f;
#define Imax 14000 //此处为晶振为11.0592时的取值, #define Imin 8000 //如用其它频率的晶振时,
#define Inum1 1450 //要改变相应的取值。

#define Inum2 700
#define Inum3 3000
sfr ISP_CONTR=0xc7; //软件复位定义
unsigned char Im[4]={0x00,0x00,0x00,0x00};
uchar show[2]={0,0};
unsigned long m,Tc;
unsigned char IrOK,num;
//外部中断解码程序
void intersvr1(void) interrupt 2 using 1
{
Tc=TH0*256+TL0; //提取中断时间间隔时长TH0=0;
TL0=0; //定时中断重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
f=1;
return;
} //找到启始码
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取码
}
if(m==32)
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
IrOK=1;
}
else IrOK=0; //取码完成后判断读码是否正确}
//准备读下一码
}
}
/*演示主程序*/
void red_line_begin()
{
m=0;
f=0;
EA=1;
IT1=1; //负边缘触发
EX1=1; //开外部中断1
TMOD=0x11;
TH0=0;TL0=0;
TR0=1; //ET0=1;
//light=1;
while(1)
{
if(IrOK==1) //较验正解
/* switch(Im[2])
{
case 0x45:begin_flag=1;
break;
case 0x16:ISP_CONTR=0x20;
break;
} */
if (Im[2]==0x45)
{
//light=0;
begin_flag=1;
break;
}
else if(Im[2]==0x16)
ISP_CONTR=0x20; //软件复位成功!
}
EX1=0;
TR0=0;
}
#endif
//打地鼠//
#include<reg52.h>
#include <stdlib.h>
#include"music.h"
//#include"sky.h"
#include"begin_display.h"
#include"red_line_begin.h"
#include"gameing_display.h"
#include"mouse_level.h"
void main()
{
begin_display(); //过场动画还可改进
red_line_begin(); //按下遥控器开关键后开始游戏//sky();
super_mary();
ready_go();
//delayms(50);
game_start();
}。

相关文档
最新文档