查看: 4458|回复: 3

【Atmel XMEGA-A3BU手记】来甲飞旋龙 沙海献神门

[复制链接]
  • TA的每日心情
    郁闷
    2024-10-28 10:11
  • 签到天数: 1703 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2013-5-10 13:45:08 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 nemon 于 2013-5-10 17:38 编辑

    上次提到“岁月是把杀猪刀”,今天看看它的另一个牺牲品李连杰——1982年,李连杰初出茅庐主演少林寺,那家伙青葱年少的小伙儿帅呆了、酷毙了、震倒一大片。
    032.jpg
    30年弹指一冒烟演的功夫,当年的少年郎的脸上满是成熟的横肉了,唉……
    2011010634266797.jpg

    大家知道前面那个戴墨镜的白胡子老爷爷是谁吗?对,徐克。
    那么这二位高人在一起在拍什么片子呢?答案是——
    c2cec3fdfc039245d7fc13468794a4c27c1ed21b0ef40511.jpg


    p1466853289.jpg

    《龙门飞甲》的故事大概是这样的:一上来,李连杰把东厂的老大灭了。这时候周迅护送宫里逃出来正被西厂追缉的范晓萱去龙门,李连杰虽然曾是西厂的厂公陈坤的手下败将,也甘冒风险暗中保护准GF周迅,这一堆人到了龙门客栈,遇上了以春哥为核心紧密团结的“宝藏搜索小组”。
    p1535930575.jpg

    李连杰、周迅、范晓萱集团在了解到李宇春集团根据石碑上“来甲飞旋龙 沙海献神门”的记载,谋划趁六十年一遇的龙卷风将沙子移开的一小段时间里,深入黄沙掩埋的大白上国皇宫攫取宝藏的目的后,与其联手和陈坤火并,在血与沙之间的激烈搏斗中,在男猪脚在龙卷风中作秀,以及范晓萱露出反间真面目的狗血剧情之后,春哥也不顾眼见到手的金子伸出援手,最终江湖人士消灭了西厂阉党逃出迷宫。

    罗嗦了许多,估计已经有童鞋思维活跃、才思敏捷、冰雪聪明、玉树临风地猜到了本期主题——迷宫。
    话说在XMEGA A3BU Xplained kit的128x32像素的lcd上画迷宫还是很紧张的,墙要占1个像素,迷宫里的人最小也要用1个像素,人和墙之间还要留1个像素,加起来就已经是4个像素了。这样算起来,8个格子,马马虎虎还可以,不过,最下面一行就没法画墙了。
    1. #define MAZE_WIDTH  8
    2. #define MAZE_HEIGHT 8
    复制代码
    迷宫呢,设计成这样:
    左边的有坐标的是完整版,中间的是只画右边和下边墙的,右边的图的是只画左边和上边的墙。
    2013-05-10_160716_00001.png
    每个格子用一个整数表示,二进制时第1、2、3、4位为1,分别表示左边、上边、下边、右边有墙。比如上图中左上角的7(即二进制的0111),表示左边、上边、下边有墙。注意两个相邻的格子都同时记录了两个格子之间是否有墙,因此数据是存在冗余,这样处理的好处是,当需要判断是否可以向某方显移动时,只要判断所在单元格的对应位是否为1就行了,算法简便迅速。
    1. #define WALL_LEFT  1
    2. #define WALL_UP    2
    3. #define WALL_DOWN  4
    4. #define WALL_RIGHT 8

    5. unsigned char maze_data[8][8]={
    6.         7, 6,10, 3, 6,14, 3,14,
    7.         3,10, 9, 5,10, 3, 4,10,
    8.         9, 5,12, 3, 8, 9, 3,12,
    9.         5,10, 3,12,13, 9, 5,10,
    10.         3, 4, 4, 2,14, 5,10, 9,
    11.         9, 3,14, 9, 3, 6,12, 9,
    12.         1, 8,11, 1, 8, 3,10, 9,
    13.         13,5,12,13, 5,12, 9,13
    14. };
    复制代码
    控制向某个方向运动,用4个按键(其中有一个电容按钮)就可以,只是要注意是否到了边界、是否有墙。所以做这样的定义:
    1. #define BTN_GO_LEFT  KEYBOARD_ENTER
    2. #define BTN_GO_UP    KEYBOARD_UP
    3. #define BTN_GO_DOWN  KEYBOARD_BACK
    4. #define BTN_GO_RIGHT KEYBOARD_DOWN
    复制代码
    还定义了一个结构用于存储“位置”,比如人所在的位置、起点的、终点:
    1. struct position
    2. {
    3.         unsigned int x;
    4.         unsigned int y;
    5. }cusor_pos;
    6. struct position pos_start={0,0};
    7. struct position pos_end={7,7};
    复制代码
    画出人所在的位置用这个函数,同时在98,18的位置画一个当前位置的环境图:
    1. void paintCursor(enum gfx_mono_color color)
    2. {
    3.         unsigned int k=maze_data[cusor_pos.y][cusor_pos.x];
    4.         if(k&WALL_LEFT )gfx_mono_generic_draw_line(100,20,100,24,color);
    5.         if(k&WALL_UP)   gfx_mono_generic_draw_line(100,20,104,20,color);
    6.         if(k&WALL_RIGHT)gfx_mono_generic_draw_line(104,20,104,24,color);
    7.         if(k&WALL_DOWN) gfx_mono_generic_draw_line(100,24,104,24,color);
    8.         gfx_mono_generic_draw_rect(98,18,9,9,color);
    9. /*
    10.         gfx_mono_generic_draw_line(96,20,96,20+cusor_pos.y,color);
    11.         gfx_mono_generic_draw_line(100,16,100+cusor_pos.x,16,color);
    12. */
    13.         gfx_mono_draw_pixel( MAZE_LEFT+cusor_pos.x*4+2 , MAZE_TOP+cusor_pos.y*4+2 , color);
    14.         
    15. }
    复制代码
    color的定义有3种:
    GFX_PIXEL_CLR清除,相当于白色
    GFX_PIXEL_SET设置,相当于黑色
    GFX_PIXEL_XOR异或,相当于反显
    这样画图的时候输入的color是GFX_PIXEL_SET,擦除的时候也用相同的函数,但color变成了GFX_PIXEL_CLR。
    下面是处理方向键的方式:
    1. char when_key_up(void)
    2. {
    3.         if(cusor_pos.y>0 && !(maze_data[cusor_pos.y][cusor_pos.x]&WALL_UP) )
    4.         {
    5.                 paintCursor(GFX_PIXEL_CLR);
    6.                 cusor_pos.y--;
    7.                 paintCursor(GFX_PIXEL_SET);
    8.                 return LOGIC_TRUE;
    9.         }
    10.         else
    11.         {
    12.                 return LOGIC_FALSE;
    13.         }
    14. }
    15. char when_key_down(void){
    16.         if(cusor_pos.y<MAZE_HEIGHT-1 && !(maze_data[cusor_pos.y][cusor_pos.x]&WALL_DOWN) )
    17.         {
    18.                 paintCursor(GFX_PIXEL_CLR);
    19.                 cusor_pos.y++;
    20.                 paintCursor(GFX_PIXEL_SET);
    21.                 return LOGIC_TRUE;
    22.         }
    23.         else
    24.         {
    25.                 return LOGIC_FALSE;
    26.         }
    27. }
    28. char when_key_left(void){
    29.         if(cusor_pos.x>0 && !(maze_data[cusor_pos.y][cusor_pos.x]&WALL_LEFT) )
    30.         {
    31.                 paintCursor(GFX_PIXEL_CLR);
    32.                 cusor_pos.x--;
    33.                 paintCursor(GFX_PIXEL_SET);
    34.                 return LOGIC_TRUE;
    35.         }
    36.         else
    37.         {
    38.                 return LOGIC_FALSE;
    39.         }
    40. }
    41. char when_key_right(void){
    42.         if(cusor_pos.x<MAZE_WIDTH-1 && !(maze_data[cusor_pos.y][cusor_pos.x]&WALL_RIGHT) )
    43.         {
    44.                 paintCursor(GFX_PIXEL_CLR);
    45.                 cusor_pos.x++;
    46.                 paintCursor(GFX_PIXEL_SET);
    47.                 return LOGIC_TRUE;
    48.         }
    49.         else
    50.         {
    51.                 return LOGIC_FALSE;
    52.         }
    53. }
    复制代码
    游戏初始化并绘制地图:
    1. void init_Maze(void)
    2. {
    3.         int i,j,k;
    4.         // Clear screen
    5.         gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
    6.         
    7.         //光标位置
    8.         cusor_pos.x=pos_start.x;//0;
    9.         cusor_pos.y=pos_start.y;//0;
    10.         paintCursor(GFX_PIXEL_SET);
    11.         
    12.         for(i=0;i<MAZE_WIDTH;i++)
    13.         {
    14.                 for(j=0;j<MAZE_HEIGHT;j++)
    15.                 {
    16.                         k=maze_data[i][j];
    17.                         if(k&WALL_LEFT )gfx_mono_generic_draw_line(MAZE_LEFT+j*4,MAZE_TOP+4*i,MAZE_LEFT+j*4,MAZE_TOP+4*i+4,GFX_PIXEL_SET);
    18.                         if(k&WALL_UP)   gfx_mono_generic_draw_line(MAZE_LEFT+j*4,MAZE_TOP+4*i,MAZE_LEFT+j*4+4,MAZE_TOP+4*i,GFX_PIXEL_SET);
    19.                 }
    20.                 // 画一下最右边的竖线
    21.                 gfx_mono_generic_draw_line( MAZE_LEFT+MAZE_WIDTH*4,MAZE_TOP+4*i ,MAZE_LEFT+MAZE_WIDTH*4,MAZE_TOP+4*i+3,GFX_PIXEL_SET);
    22.         }
    23. }
    复制代码
    最后是主函数,注意要在按钮的循环里判断游戏是否结束以及是否选择了退出:
    1. void game_0_maze_play (void)
    2. {
    3.         struct keyboard_event input;
    4.         init_Maze();
    5.         while(1)
    6.         {
    7.                 do {
    8.                         //exit when 5th button pressed
    9.                         if( get_lightsensor_value()<100)
    10.                         {
    11.                                 return;
    12.                         }
    13.                         //exit when game passed
    14.                         if(cusor_pos.x==pos_end.x && cusor_pos.y==pos_end.y)
    15.                         {
    16.                                 gfx_mono_draw_filled_rect(0, 0, 128, 32, GFX_PIXEL_CLR);
    17.                                 gfx_mono_draw_string("YOU WIN !", 8, 16, &sysfont);
    18.                                 delay_ms(1000);
    19.                                 return;
    20.                         }
    21.                         
    22.                         keyboard_get_key_state(&input);
    23.                         // Wait for key release
    24.                 } while (input.type != KEYBOARD_RELEASE);

    25.                 switch (input.keycode)
    26.                 {
    27.                         case BTN_GO_LEFT:
    28.                                 when_key_left();
    29.                                 break;

    30.                         case BTN_GO_UP:
    31.                                 when_key_up();
    32.                                 break;

    33.                         case BTN_GO_DOWN:
    34.                                 when_key_down();
    35.                                 break;

    36.                         case BTN_GO_RIGHT:
    37.                                 when_key_right();
    38.                                 break;

    39.                         default:
    40.                                 
    41.                                 break;
    42.                 }
    43.         }
    44. }
    复制代码
    自己先玩一下。开始——


    此处略去一个月……

    终于出来了……信春哥,出迷宫!






























    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2015-12-14 11:43
  • 签到天数: 556 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2013-5-10 19:12:22 | 显示全部楼层
    这么爽的帖子,一定要顶起啊         
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2013-5-10 21:19
  • 签到天数: 6 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2013-5-10 19:55:14 | 显示全部楼层
    神一样的存在啊
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2024-9-30 02:33
  • 签到天数: 444 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2013-5-22 16:34:25 | 显示全部楼层
    大神级别的人物   膜拜!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 01:52 , Processed in 0.135364 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.