namiachy's profilenamiachy's(王玉聪)PhotosBlogLists Tools Help

Blog


    打破循环的僵局

    goto语句仿佛只有在Basic和flash中出现过,但绝对是一种很直观的运行线索。
    这几天学习用Lua编写游戏脚本,他当然也不会有goto循环。
    Lua主要用于游戏编程,并可以Lua Player运行游戏于PSP中,在假设按键的被按下时写'pad:'按键名'()'(此前需要“pad = Controls.read()”来关注按键状态)。
    问题:很多时候按键被按下一次某个事件只需要被触发一次,不管按住它多久;另外一些时候按键被按下,if循环中的事件就一次次地被循环触发,直至松开它为止,如续力、行走、连射等。
    pad:"按键名"()属于后者,他可以使事件被持续循环触发,如何使按键按下时循环中的事件仅仅被触发一次?Lua教程的例程如下:
     
    首先在代码顶端的数据表之前添加此代码行:
    oldpad = Controls.read()
    其次将条件代码行
    if pad:'按键名'() then改为:
    if pad:'按键名'() and oldpad:'按键名'() ~= pad:'按键名'() then
    最后在"screen.flip()"和"end"之间添加代码行
    oldpad = pad
     
    当然这或许是最标致的方法。
     
    其他方式?引入一个类似Basic里面行号的参数,比如"d"。
     
    [例]在第1个页面下按cross键退出程序,按circle键进入第2个页面;在第2个页面时按cross返回第1个页面,按circle键进入第3个页面……
     
    [错误特征]错误循环代码片断:
    01 d = 0
    02
    03 if d == 0 then
    04 screen:print(0,0,page1)
    05 if pad:cross() then
    06 break
    07 end
    08 if pad:circle() then
    09 d = 1
    10 end
    11 end
    12
    13 if d == 1 then
    14 screen:print(0,0,page2)
    15 if pad:cross() then
    16 d = 0
    17 end
    18 if pad:circle() then
    19 d = 2
    20 end
    21 end
    22
    23 if d == 2 then
    24 screen:print(0,0,page3)
    25 end
     
    [问题分析]d=0时当按住circle键,d由第8~10行被赋值1并因为第13~14行进入页面2,但此时circle键还没来得及被松开,于是d又由第18~20行被赋值2并因未第23~24行进入了页面3,导致页面2实际上无法出现;另外,假使处于页面2,按住cross键后会因第15~16行将d赋值为0并因第3~4行进入页面1,但此时cross键还没来得及被松开,于是又由第5~6行直接退出了程序,导致页面1实际上无法返回。
     
    [解]
    d = 0
    if d == -0.5 and pad:cross() == false then
    d = 0
    end
    if d == 0 then
    screen:print(0,0,page1)
    if pad:cross() then
    break
    end
    if pad:circle() then
    d = 0.5
    end
    end
    if d == 0.5 and pad:circle() == false then
    d = 1
    end
    if d == 1 then
    screen:print(0,0,page2)
    if pad:cross() then
    d = -0.5
    end
    if pad:circle() then
    d = 2
    end
    end
    if d == 2 then
    screen:print(0,0,page3)
    end
     
    [说明]添加了d等于-0.5以及0.5的条件检索是否按键已经被松开并且直至按键松开才继续执行程序。
     
    "d"很类似Basic中的行号的概念。
     
    原创笔记/引用请注明出处,谢谢!