/*******************声明***********************/
//本demo主体小恐龙代码(除更新内容外)来源于
//git开源代码DOCTOROLIVE/Dino
//更新内容大量参考元器件官网例程、STC官网以及
//网友的分享。在此一并感谢 ^-^
/***************主要元器件清单******************/
//MCU: STC12C5A32S2
//OLED:2.42寸 IIC OLED(0.96也可,只是屏幕太小)
//充放电模块:IP5306-CK主控(该模块用于锂电池3.7
//或4.2升压为5V,尽量不要用DCDC升压模块,那种纹
//波很大,后期检测电池容量数据会一直跳变,如果
//不检测电池容量,DCDC模块亲试也是可以的。)
/*****************比较遗憾的*******************/
//不能自动保存分数,只能手动按按钮做为保存标志
//断电保存数据类型为int,理论上只能保存65535分
//为了防止数据溢出,判断超过65530强制为65530
//并且分数覆盖为乱码作为小彩蛋。
//PS:12单片机有LVD中断可以作为掉电保存,但是
//本人没用过,最近也比较忙,有愿意分享的可以分
//享下 ^-^
/*****************更新内容*********************/
//1、新增多种随机障碍物,太阳内容,内置彩蛋
//2、增加电池电量监测,可实时监测剩余电量
//3、新增断电保存功能
//PS:电池电量监测的值可能需要修改,我的思路是
//电池满电时电压(4.2)作为满电,电池带不起装置
//电压(应该是1.8)设为0%,请根据电池参数不同进
//行调整。至于电池剩余容量监测采用电压方式确实
//不准确,但是目前也没有好的方法。
/********************后期**********************/
//1.打算加MP3模块播放BGM,之前尝试过用蜂鸣器,
//但是音质不理想,源码仍保留,大家在工程中增
//添music.c,music.h,主函数添加musicInit(0.75)
//调用函数即可,这个例程也是用的别人的,一并感
///谢。
//2.硬件上增加太阳能电池板做额外供电,因为我的
//想法是把它做成一个挂坠,电池板功率和稳压问题
//后续考虑。
/**********************************************/
和单片机大小对比
extern const unsigned char code COVER[] ;
sbit key = P0^1;//重启游戏、跳跃按钮
sbit save = P0^0;//保存数据按钮
unsigned int highest_score=0;//最高分
unsigned int highest_temp_score=0;//外部函数调用eeprom
extern unsigned int adc10_start(uchar channel); //ADC通道选择 P01 channel = 0~7
unsigned char get_key_val()
{
unsigned char key_num = 0;
if (key == 0)
{
delay1ms(10);
if (key == 0)
{
key_num = 2;
}
}
return key_num;
}
void main(){
unsigned char key_num = 0,key_flag = 0;
unsigned char cactus_category = 0;
unsigned char cactus_length = 8;
unsigned long int score = 0;
unsigned int fly_n;//判断飞机动画是否过完
unsigned int ufo_n;//判断飞机动画是否过完
unsigned char height = 0;
int cactus_pos = 128;//这个变量不能用unsigned,不知道为啥
//unsigned char cur_speed = 30;
unsigned char failed = 0;
unsigned char reset = 0;
unsigned int adc0;
//unsigned int adc1;
//unsigned int adc2;
P1ASF = (1 << ADC_CH0||1 << ADC_CH1||1 << ADC_CH2); //12C5A60AD/S2系列模拟输入(AD)选择
ADC_CONTR = ADC_360T | ADC_ON;
OLED_Init(); //初始化OLED
//OLED_DrawBMP(0,0,128,8,COVER);
OLED_DrawBMP_Faster(0,0,128,8,COVER);
Delay_50ms(200);
OLED_Clear();
OLED_ShowString(10, 1, "Quote:", 10,10);
OLED_ShowString(0, 2, "git", 8,6);
OLED_ShowString(0, 3, "/DOCTOROLIVE/Dino", 8,6);
Delay_50ms(250);
OLED_Clear();
//OLED_DrawBMP(0,0,128,8,COVER);
OLED_DrawBMP_Faster(0,0,128,8,COVER);
while(get_key_val()==0);
delay_ms(100);
OLED_Clear();
while(1)
{
if (failed == 1)
{
draw_restart();
key_num = get_key_val();
if (key_num == 2){
score = 0;
failed = 0;
height = 0;
reset = 1;
oled_draw_dino_jump(reset);
oled_draw_cactus_random(cactus_category, reset);
fill_picture(0x00);
}
continue;
}
score ++;
if (height == 0) key_num = get_key_val();
oled_draw_ground();
oled_draw_cloud();
//随机太阳、ufo、飞机
if(rand()%5000==2500||ufo_n==1){ufo_n=1;if(oled_draw_ufo()<128)ufo_n=1;else ufo_n=0;//5000 2500
}else if(rand()%2000==1234||fly_n==1){fly_n=1;if(oled_draw_fight()<128)fly_n=1;else fly_n=0; //2000 1234
}else oled_draw_sun();
//oled_draw_dino();
//oled_draw_dino_jump(0);
//oled_draw_cactus();
//if (height>0 || key_num > 0) height = oled_draw_dino_jump(reset);
//else oled_draw_dino();
cactus_pos = oled_draw_cactus_random(cactus_category, reset);
if(cactus_category == 0) cactus_length = 8;
else if(cactus_category == 1) cactus_length = 16;
else cactus_length = 24;
if (cactus_pos + cactus_length < 0)
{
cactus_category = rand()%8; //障碍出现的随机数
oled_draw_cactus_random(cactus_category,1);//变量:植物随机,建筑随机,动物随机
}
if ((height < 16) && ( (cactus_pos>=16 && cactus_pos <=32) || (cactus_pos + cactus_length>=16 && cactus_pos + cactus_length <=32))){
failed = 1;//注释掉该行,不会判为撞上
}
if (height>0 || key_num > 0) height = oled_draw_dino_jump(reset);
else oled_draw_dino();
if(save==0){//保存数据
sector_Erase(0x0000);//写入前先擦除数据
Byte_write(0x0000,highest_score/10000);
Byte_write(0x0001,highest_score%10000/1000);
Byte_write(0x0002,highest_score%1000/100);
Byte_write(0x0003,highest_score%100/10);
Byte_write(0x0004,highest_score%10);
}
highest_temp_score=Byte_read(0x0000)*10000+
Byte_read(0x0001)*1000+
Byte_read(0x0002)*100+
Byte_read(0x0003)*10+
Byte_read(0x0004);
if(Byte_read(0x0000)==255 && Byte_read(0x0001)==255 && Byte_read(0x0002)==255 && Byte_read(0x0003)==255 && Byte_read(0x0004)==255 ){highest_temp_score=0;}
if(score > highest_score) highest_score = score;
if(score < highest_temp_score && highest_temp_score > highest_score) highest_score = highest_temp_score;
if(highest_score>65530){
OLED_ShowChar( 0,0,'%',12);
OLED_ShowChar( 7,0,'$',12);
OLED_ShowChar(14,0,'^',12);
OLED_ShowChar(21,0,'&',12);
OLED_ShowChar(28,0,'#',12);
OLED_ShowChar(35,0,'&',12);
OLED_ShowChar(42,0,'@',12);
OLED_ShowChar(49,0,'+',12);
OLED_ShowChar(56,0,'&',12);
OLED_ShowChar(63,0,'/',12);
OLED_ShowChar(70,0,'%',12);
OLED_ShowChar(77,0,'$',12);
OLED_ShowChar(84,0,'^',12);
OLED_ShowChar(91,0,'&',12);
OLED_ShowChar(98,0,'#',12);
OLED_ShowChar(105,0,'&',12);
highest_score=65530;
}
else{
OLED_ShowString(0, 0, "H", 12,6);
OLED_ShowNum(10, 0, highest_score, 6, 12);
OLED_ShowString(50,0, "N", 12,6);
OLED_ShowNum(60, 0, score, 5, 12);
}
//电池电量监视
adc0=adc10_start(0);
//adc1=adc10_start(1);
//adc2=adc10_start(2);
if(adc0>=900){
adc0=900;}else if(adc0<=718){
adc0=718;}
OLED_ShowNum(93,0,adc0/9,3,12);
OLED_ShowChar(112,0,'%',3);
if (score % 100 == 0) ET1 = 1;
else{
ET1 = 0;
}
reset = 0;
//速度固定,取消注释更改速度
//cur_speed =score/20;
//if (cur_speed > 49) cur_speed = 49;
delay_ms(60/* - cur_speed*/);
}
}
原理图: 无
仿真: 无
代码:
代码.7z
(79.29 KB, 下载次数: 9)
|