回答

收藏

【Atmel XMEGA-A3BU手记】hold得住?

其他 其他 4775 人阅读 | 0 人回复 | 2013-05-24


话说2011年,某网商启用“Hold住姐”做了个平面广告,一句“店庆Hold不住”把一个购物狂的形象描述的活灵活现。据说“购物狂”被认为是一种心理学的疾病,有心理学家尝试以药物控制购物狂的购物习惯。在香港,有人因为购物狂,以信用卡大量签帐,成为卡奴,引致被迫辍学、破产,甚至盗取他人信用卡签帐等犯罪行为。2006年,香港导演韦家辉曾执导电影《购物狂》,以夸张手法探讨购物狂这种社会现象。


    故事的主人公叫方芳芳,由张柏芝饰演(看着海报,楼主又忍不住要说“岁月是把杀猪刀”了),虽然只是个小护士,可是却有惊人的购物癖好,经济已然陷于困境。为了解决自己的疯狂购物欲,芳芳去看心理医生,没想到这个刘青云扮的大夫有选择恐惧症,再后来又遇见陈小春、官恩娜,于是2男2女发生一系列搞笑故事,当然最后是喜剧片必有的皆大欢喜结局。《购物狂》首映于2006年,如果是在2009年来看这个故事,明显Out了,因为2009年最in的是“秒杀”。秒杀本是网游用语,代表瞬间一击致死的战斗模式,被人转用于限时抢购的概念之后,非常流行,甚至出现了以此为爱好、为职业的秒杀一族。
    岁月荏苒,到了2012年,EE世界也出现了一件“秒杀”盛事——“Stellaris? LM4F120 LaunchPad火热来袭!!!”,经此一役,爱板网名声大震,而LM4F Launchpad板块也成为了论坛里迄今为止仅次于灌水区的唯一一个回帖数过万的板块。参加的童鞋,当时Hold不住了吧?
    今天做的这个游戏应用,基本上就是个秒杀的操作——游戏开始之后,倒数10秒至0,这时玩家就要快速按下任意一个按键,之后界面显示与0秒之间的差距:如果在0秒前按,显示负数;如果在0秒后按,显示正数;如果0秒之后10秒钟还不按,太逊了,GAME OVER!那么怎么实现呢?
    我们知道,XMEGA-A3BU中有rtc,这是个uint32_t类型的timestamp,如果用asf的claendar解释,就是从1970年以来的秒数。我们可以取两次rtc_get_time()的差就能在不需设置正确rtc时间的情况下计算出秒数,但是以秒为单位总是觉得太粗糙了。XMEGA-A3BU中还有一个利器可以解决这个问题——TC,使用tc可以轻松的将1秒分为100份,因此我们设置好tc,启用它,就会每隔1/100秒运行这个中断函数:
  1. static void int_callback(void)
  2. {
  3.         if(tc_global<99)
  4.         {
  5.                 tc_global++;
  6.         }
  7.         else
  8.         {
  9.                 tc_global=0;
  10.         }
  11. }
复制代码
这样,随时读取tc_global的值可以得到当前的百分秒数。
然后主函数就简单了:
  1. void game_1_quick_count (void)
  2. {
  3.         struct keyboard_event input;
  4.        
  5.         uint32_t ts_start;
  6.         uint32_t ts_last;
  7.         uint32_t ts_current;
  8.        
  9.         uint32_t tc_start;
  10.         uint32_t tc_last;
  11.        
  12.         int i_count=0;
  13.         int i_n_tmp=10;
  14.        

  15.                
  16.         while(1)
  17.         {
  18.                
  19.                 //CLS
  20.                 gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
  21.                 // Draw static strings outside the loop
  22.                 gfx_mono_draw_string("Press a Key to start", 0, 8, &sysfont);
  23.                 do {
  24.                         //exit when 5th button pressed
  25.                         if( get_lightsensor_value()<100)
  26.                         {
  27.                                 stop_TC();
  28.                                 return;
  29.                         }
  30.                         keyboard_get_key_state(&input);
  31.                         // Wait for key release
  32.                 } while (input.type != KEYBOARD_RELEASE);
  33.        
  34.                 start_TC();
  35.                
  36.                
  37.                 //CLS
  38.                 gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
  39.                 i_count=0;
  40.                 i_n_tmp=10;
  41.                 //gfx_mono_put_bitmap(bitmap_numbers[i_n_tmp], 60, 8);
  42.                 gfx_mono_draw_char('1',60-5,16,&sysfont);
  43.                 gfx_mono_draw_char('0',60 ,16,&sysfont);
  44.                 ts_start = rtc_get_time();
  45.                 ts_last=ts_start;
  46.                 tc_start=tc_global;//tc_read_count(&TCC0);
  47.                 do {
  48.                         //exit when 5th button pressed
  49.                         if( get_lightsensor_value()<100)
  50.                         {
  51.                                 stop_TC();
  52.                                 return;
  53.                         }
  54.                         ts_current = rtc_get_time();
  55.                         if(ts_current!=ts_last)
  56.                         {
  57.                                 i_count+=(ts_current-ts_last)%60;
  58.                                 i_n_tmp=i_count<=10?10-i_count:i_count-10;

  59.                                 if(i_n_tmp>=10)
  60.                                 {
  61.                                         gfx_mono_draw_char('1',60-5,16,&sysfont);
  62.                                         gfx_mono_draw_char('0',60 ,16,&sysfont);
  63.                                 }
  64.                                 else
  65.                                 {
  66.                                         gfx_mono_draw_char(' ',60-5,16,&sysfont);
  67.                                         gfx_mono_draw_char('0'+i_n_tmp,60,16,&sysfont);
  68.                                 }
  69.                                
  70.                                 ts_last=ts_current;
  71.                                 //showScore(tc_last, tc_start, i_count);
  72.                         }                       
  73.                        
  74.                         keyboard_get_key_state(&input);
  75.                         // Wait for key release
  76.                 } while (input.type != KEYBOARD_RELEASE && i_n_tmp<=10);
  77.                 tc_last=tc_global;
  78.                
  79.                 stop_TC();
  80.                
  81.                 //CLS
  82.                 gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
  83.                 if(i_n_tmp>10)
  84.                 {
  85.                         //over time
  86.                         gfx_mono_draw_string("Game Over", 5, 8, &sysfont);
  87.                 }
  88.                 else
  89.                 {
  90.                         gfx_mono_draw_string("Score :", 5, 0, &sysfont);
  91.                         //show result
  92.                         showScore(tc_last, tc_start, i_count);
  93.                 }
  94.                 do {
  95.                         //exit when 5th button pressed
  96.                         if( get_lightsensor_value()<100)
  97.                         {
  98.                                 return;
  99.                         }
  100.                         keyboard_get_key_state(&input);
  101.                         // Wait for key release
  102.                 } while (input.type != KEYBOARD_RELEASE );
  103.                 //delay_s(5);
  104.         }
  105. };
复制代码
下面上图,看效果:





分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条