2017-04-24 94 views
2

我想通過按空格鍵來啓動和停止龜的程序。我得到了啓動烏龜移動的代碼,但是當我再次按下它時,它並沒有停止。它似乎只是提高了速度。這是我的編碼要求和我輸入的代碼。用空格鍵啓動和停止Python龜

創建一個有三個功能的海龜程序來控制海龜。創建一個叫做turnLeft的函數,當鍵盤上的右箭頭被按下時,它會將烏龜向左旋轉90度。創建一個叫做turnRight的函數,當按下右箭頭時,它將右旋90度。創建第三個函數move(),當空格鍵被按下時向前移動烏龜,然後在空格鍵再次被按下時停止烏龜。

import turtle 

turtle.setup(400,500) 
wn = turtle.Screen() 
wn.title("Tess moves in space") 
wn.bgcolor("lightgreen") 
tess = turtle.Turtle() 

def leftTurtle(): 
    tess.left(90) 

def rightTurtle(): 
    tess.right(90) 

state_num = 0 

def advance_state_machine(): 
    global state_num 
    if state_num == 0:  
     tess.penup() 
     state_num = 1 
    else:  
     tess.pendown() 
     tess.forward(2) 
     state_num = 0 
    wn.ontimer(advance_state_machine, 25) 

def exitWindow(): 
    wn.bye() 

wn.onkey(advance_state_machine, "space") 
wn.onkey(exitWindow, "q") 
wn.onkey(leftTurtle, "Left") 
wn.onkey(rightTurtle, "Right") 

wn.listen()      
wn.mainloop() 

回答

1

你明白了,除了一些微小的細節改變。如果烏龜應該移動,全局變量state_numadvance_state_machine()函數中決定。你對轉彎有適當的邏輯,所以爲什麼不把相同的邏輯用於移動/暫停?

在您的原始代碼中,您只需將每個顯示的幀從全局變量值切換到另一個狀態,然後使用SPACE鍵啓動另一個實例,使龜更快。由於每個SPACE在advance_state_machine()中實施的進一步循環開始與現有的平行運行,所以龜變快了。

在功能movementControl()下面的代碼改變的SPACE的布爾should_move到相對一個值和advance_state_machine()評估should_move讓龜移動或停止:

import turtle 

turtle.setup(400,500) 
wn = turtle.Screen() 
wn.title("Tess moves in space") 
wn.bgcolor("lightgreen") 
tess = turtle.Turtle() 

def leftTurtle(): 
    tess.left(90) 

def rightTurtle(): 
    tess.right(90) 

should_move = False 

def movementControl(): 
    global should_move 
    should_move = not should_move 

def advance_state_machine(): 
    global should_move 
    if should_move:  
     tess.pendown() 
     tess.forward(2) 
    else:  
     tess.penup() 
    wn.ontimer(advance_state_machine, 25) 

def exitWindow(): 
    wn.bye() 

wn.onkey(movementControl, "space") 
wn.onkey(exitWindow, "q") 
wn.onkey(leftTurtle, "Left") 
wn.onkey(rightTurtle, "Right") 

wn.listen()      
advance_state_machine() 

wn.mainloop() 

哇!!!用cdlane's的幫助,我們把這裏一個非常好的基本烏龜的例子放在一起。

現在我已經修改HIS代碼更多的一個簡約版本,並擺脫了moveControl()函數。

我個人不喜歡使用from turtle import *類型的導入語句,因爲它們提供了大量可用的方法和變量,它們是「不可見的」,因爲您無法直接看到它們來自哪裏,但是......有所有短代碼塊中的代碼都不值得嗎?

from turtle import * 
setup(400, 500); title('Turtle moves in space') 
bgcolor('lightgreen'); up() 
def advance_state_machine(): 
    if isdown(): fd(2) 
    ontimer(advance_state_machine, 25) 
onkey(lambda: (pd, pu)[isdown()](), 'space') 
onkey(bye, 'q') 
onkey(lambda: lt(90), 'Left') 
onkey(lambda: rt(90), 'Right') 
listen(); advance_state_machine(); done() 
+1

此外,重命名'state_num'到'should_draw'並使其成爲一個布爾使代碼讀取更好,並且切換成爲單行:'should_draw = not_draw_不是。 – 9000

+0

謝謝@Claudio和9000你們都很棒...我對編碼和python非常陌生,而這個人正在踢我的屁股。這工作完美。還有一個問題,是否可以將'def movementControl():'和'def advance_state_machine():'合併爲一個函數? –

+1

@DavidWilliam:我不這麼認爲,你需要在不同的時間調用'advance_state_machine'和'movementControl'。 (另外,爲了保持一致性,讓它們既可以是camelCase也可以是兩個underscore_case。) – 9000

1

方式狀態變量state_num和/或should_move上面使用可以看出與龜自身isdown()謂詞作爲冗餘。我據此重新克勞迪奧的解決方案,但使它的簡約所以isdown()邏輯脫穎而出:

from turtle import * 

def movementControl(): 
    (pd, pu)[isdown()]() 

def advance_state_machine(): 
    if isdown(): 
     fd(2) 
    ontimer(advance_state_machine, 25) 

setup(400, 500) 
title('Turtle moves in space') 
bgcolor('lightgreen') 
up() 

onkey(movementControl, 'space') 
onkey(bye, 'q') 
onkey(lambda: lt(90), 'Left') 
onkey(lambda: rt(90), 'Right') 

listen() 

advance_state_machine() 

done()