在 MicroPython 中使用 microbit 模块时出现索引错误

Index Error when using microbit module in MicroPython

目前正在尝试为 BBC 开发一款小型双键游戏 micro:bit。由于 micro:kit 没有广泛使用,我将尝试详细解释我的问题。

我正在尝试为播放器创建控件,'movable' 灯卡在网格的最后一行。 A 按钮应该将灯向左移动一列,B 按钮应该将灯向右移动一列。

我为矩阵创建了 5 个单独的图像 (称为 player_loc#,每个图像都是一个可能的位置对于 LED。

from microbit import *
import random

player_index = 2

player_loc0 = Image('00000:00000:00000:00000:50000')
player_loc1 = Image('00000:00000:00000:00000:05000')
player_loc2 = Image('00000:00000:00000:00000:00500')
player_loc3 = Image('00000:00000:00000:00000:00050')
player_loc4 = Image('00000:00000:00000:00000:00005')

player_locs = [player_loc0, player_loc1, player_loc2, player_loc3, player_loc4]
# Indexes            0             1           2             3            4

while True:
    display.show(player_locs[player_index])
    if button_a.is_pressed():
        player_index += 1
    elif button_b.is_pressed():
        player_index -= 1    

A按钮应该从player_index中减去1(等于2),从而使display.show(player_locs[player_index]) 显示图像 player_loc1 而不是 player_loc2.
B 按钮做相反的事情,它加一,这应该导致 player_loc3 被显示。


我遇到的问题是,当我按下 A 或 B 按钮时,出现 IndexError,列表索引超出范围,在第 17 行,display.show(player_locs[player_index])。该指数不应超出范围。在列表 player_locs 上,我的索引范围为 0-4。索引 1 和 3 没有超出范围,但它显示 IndexError 超出范围消息。当我用任何整数 0-4 删除 player_index 和 运行 时,它起作用了。


这是我 运行 脚本未按任何按钮时的图像。只要按下按钮,就会显示错误消息。 任何帮助将不胜感激。

LEDpicture

您在没有任何延迟的 while 循环中使用 is_pressed 方法,所以基本上发生的情况是循环执行得非常快并且有足够的时间在您按下任何按钮时迭代多次,即使您认为新闻界真的很快。在这些迭代的每一次中,循环读取按钮状态为按下状态,并且它增加或减少 player_index 足够的次数以使其超出其有效范围。

或者,您可以使用 was_pressed,它会跟踪各个按键并按您期望的方式工作。

如果您想确保您的索引永远不会超出范围,您甚至可以添加额外的检查以确保程序不会崩溃:

while True:
    display.show(player_locs[player_index])
    if button_a.was_pressed() and player_index < (len(player_locs) - 1):
        player_index += 1
    elif button_b.was_pressed() and player_index > 0:
        player_index -= 1

我是业余爱好者,所以我还在学习中。我废弃了我的旧代码,因为我对这么早就陷入困境感到沮丧。我想出了一个更 "integer based" 的脚本,而不是使用会改变的预设图像。我认为使用简单的整数可以更轻松地使用控制流、操作整数(以及图像),而不必更改和测试图像。我还想用这两个按钮创建一个计算器,所以这些建议会派上用场。谢谢你帮助我!


如果您想知道,这里是更新后的代码。我目前正在尝试添加随机 enemy/wall 代:

from microbit import *
import random

game_over == False

player_x = 2
player_y = 4
#starting coords for 'player' pixel

light = 5
wall_light = 7
#brightness. self explanatory

wall_pos_x = [0, 1, 2, 3, 4]
wall_y = 0
#all possible coords of wall. y coords
#are changed in function

#generates enemy wall with a randomly generated hole
def enemy_wall():

    open_x = random.randint(0,4)
    open_y = 0

    for wall_xs in range(open_x-1, open_x, -1)
        wall_pos_x[wall_xs]
        pass
    #for loops will iterate over all possible x coords except
    #the open hole's coords. for loop will use iteration and
    #display all possible x coords except open_x.

def player(x, y, bright):

    if x <= -1:
        x = 0
    elif x >= 5:
        x = 4
    display.set_pixel(x,y,bright)
    return x
    #if x coord is +- 1 more than available coords,
    #doesnt move/change position at edge

#updated newer player control. push of button changes x coord by -+ 1
#cannot change y coord
while game_over != True:

    player(player_x,player_y,light)
    sleep(750)
    #player coords re/displayed, and button cooldown 750ms

    if button_a.is_pressed():
        player_x = player(player_x-1,player_y,light)
        display.clear()
        #runs through player(), then clears display of
        #previous pixel *player*.
    elif button_b.is_pressed():
        player_x = player(player_x+1,player_y,light)
        display.clear()