我想做的是创建两个玩家并使用 WASD 和箭头进行导航。对于一个玩家,我可以创建它,并且可以复制粘贴它,但我想要另一种更短的解决方案。
对于一名玩家来说,导航如下所示: (在此之前我创建了一只名为 t 的乌龟)
def up():
y = t.ycor()
y += 5
t.sety(y)
def down():
y = t.ycor()
y -= 5
t.sety(y)
def left():
x = t.xcor()
x -= 5
t.setx(x)
def right():
x = t.xcor()
x += 5
t.setx(x)
wn.listen()
wn.onkeypress(up, "Up")
wn.onkeypress(down, "Down")
wn.onkeypress(left, "Left")
wn.onkeypress(right, "Right")`
在我的第一次尝试中,我向其中添加了“模式”: (我只测试了它是否与“玩家”一起上升) (这里我创建了两只乌龟:p1和p2)
def up(mode="p1"):
if mode == "p1":
y = p1.ycor()
y += 5
p1.sety(y)
elif mode == "p2":
y = p2.ycor()
y += 5
p2.sety(y)
wn.listen()
fel("p2")
wn.onkeypress(up, 'Up')
fel("p1")
wn.onkeypress(up, "w")`
仅当我将 def 行中的 p1 更改为 p2 时才有效。
我可以这样更换球员吗?还有其他可行的解决办法吗?
一般来说,避免使用“布尔参数模式”。如果一个函数有一个在两个不相交的分支之间切换的标志,通常将其分成两个函数并删除
if
,或者向该函数传递一个更有意义的参数,如海龟。
我在这里看不到完整的上下文,所以我将从这个实时海龟样板开始,并添加第二个玩家
t2
,它的操作绑定到WASD键。
import turtle
def tick():
for action in keys_pressed:
actions[action]()
turtle.update()
win.ontimer(tick, frame_delay_ms)
t = turtle.Turtle()
t2 = turtle.Turtle()
turtle.tracer(0)
frame_delay_ms = 1000 // 30
step_speed = 10
actions = dict(
Up=lambda: t.sety(t.ycor() + step_speed),
Left=lambda: t.setx(t.xcor() - step_speed),
Down=lambda: t.sety(t.ycor() - step_speed),
Right=lambda: t.setx(t.xcor() + step_speed),
w=lambda: t2.sety(t2.ycor() + step_speed),
a=lambda: t2.setx(t2.xcor() - step_speed),
s=lambda: t2.sety(t2.ycor() - step_speed),
d=lambda: t2.setx(t2.xcor() + step_speed),
)
win = turtle.Screen()
keys_pressed = set()
def bind(key):
win.onkeypress(lambda: keys_pressed.add(key), key)
win.onkeyrelease(lambda: keys_pressed.remove(key), key)
for key in actions:
bind(key)
win.listen()
tick()
win.exitonclick()
我们可以通过将每个玩家的按键抽象到列表中来消除一点重复(
t
和t2
,以及移动 lambda),但这对我来说有点不成熟,因为列表只会迭代 2 次我们可能总共会节省一两行代码。