陳斌 陳天翔



Python語言中內置的海龜作圖turtle模塊設計巧妙,作圖模型簡單強大,能夠讓程序設計初學者很快編寫出趣味生動的作圖程序,極大提高編程學習的興趣和積極性,在練習過程中培養和提高計算思維。除了繪制圖形之外,Python turtle模塊還具有基本的交互功能,加上學習門檻低,又是Python語言內置的標準模塊,所以非常適合作為創意編程的學習和開發平臺。本文以Python turtle模塊為核心,展示和分析交互游戲、數學對象可視化等學科領域的創意編程實例,并介紹turtle模塊的深入編程,以供創意編程的教學參考,也可用于高中Python程序設計課程的教學案例。
本文實例所涉及的代碼和截圖,均可通過鏈 接(https://github. com/chbpku/bdfz.courses/wiki)訪問獲取。
交互游戲:接蘋果
本作品是一個通過鼠標控制的交互游戲。程序運行后,在turtle窗口中會有隨機數量和位置的紅色蘋果從頂端向下掉落,掉落速度各不相同。用戶需要通過鼠標拖動窗口中間的三角形狀“托籃”接住每一個蘋果。托籃可以在窗口中隨意移功,如果接住蘋果,則加10分,分數在窗口左下角實時更新顯示,但如果未能接住蘋果使其掉出窗口下沿的話,則懲罰性地減100分。由于蘋果產生的位置和速度均為隨機,數量不定,懲罰性減分幅度大,游戲還是有相當難度的,想一直保持正分不太容易。最后點擊關閉窗口即可退出游戲。游戲運行效果如圖1所示。
turtle功能
本作品涉及到的turtle模塊功能主要有5個。
第1個是海龜繪圖加速功能,通過在程序前部加tracer方法調用禁止動畫顯示。
將海龜basket的拖動事件綁定到basket的goto函數,這樣,當用戶用鼠標點擊這個海龜并進行拖動的時候,會觸發drag事件,實現調用basket.goto函數,并將事件發生時海龜的坐標作為參數傳遞給basket. goto函數,從而實現鼠標拖動到哪里,海龜asket就跟到哪里的交互效果。海龜的鼠標交互事件還有點擊事件onclick、釋放事件nrelease,都可以綁定處理函數,從而實現點擊、釋放鼠標各個按鈕的交互。
第3個是海龜克隆功能,如程序中的第14行,海龜model的clone方法,可以將model對象復制1個,賦值給basket,克隆會產生新的海龜對象,并且保留原海龜對象的所有屬性值。利用克隆功能,能夠很方便地復制出相互獨立而又具有相同初始屬性的多個海龜,這些海龜后續修改屬性并不會相互影響。
第4個是海龜形狀設定功能,如程序中的第13、15行,由于鼠標交互需要整體拖動一個圖形,我們就可以將一個海龜的形狀設置為這個圖形,實現圖形的動畫和接受鼠標拖動事件。第13行在程序中用addshape函數添加注冊1個名字為“basket”的形狀,從代碼可以看出,這是1個以海龜坐標為中心的倒三角形。第15行用shape函數將海龜basket設置成名稱為“basket”的形狀。
我們也可以用shape函數將海龜的形狀改為turtle模塊內置的形狀,如箭頭"arrowl"、海龜"turtle"、圓"circle"、方形"square"、三角形"triangle"和經典形狀"classic"。
第5個是海龜的“蓋戳”復印功能,如程序中的第43行,設定好紅色蘋果形狀的海龜mould作為印模,可以在海龜當前位置上留下自身的形狀。即便移走海龜,這個形狀仍然保持在原地。
40 #蘋果下落,并用印模畫出蘋果
41 apple[1] -=apple[2]
42 mould. goto(apple[0],apple[1])
43 mould.stamp()
stamp函數將返回一個stampid,如果需要清除這個形狀,則可以調用clearstamp豳數清除指定stampid的形狀,或者調用clearstamps函數清除所有形狀。
程序代碼分析
程序可以分為2個部分:第1-28行為初始化部分,第30-57行為循環體部分。
初始化部分中,第1-2行導入了必要的運行庫。
1 import turtle, time
2 form random import randrange
第4-7行關閉了turtle的動畫效果,并創建了基礎的畫筆對象,用于后續的復制。
4 turtle.tracer(0)
5 model=turtle.Turtle( )
6 model.hideturtle()
7 model.penup()
第9-10行設置了幾個游戲參數。
9 FPS=30 #每秒30幀刷新率
10 FREQ=FPS//2#平均每秒生成2個蘋果
第12-18行創建了果籃對象,將其設置為自定義形狀,并綁定至鼠標拖動事件上。
12 #接蘋果的籃子
13 turtle.addshape('basket', ((-100,0),(100,0),(0,-25)))
14 basket=model.clone()
15 basket.shape('basket')
16 basket.setheading(90)
17 basket.ondrag(basket.goto) #把goto函數綁定到鼠標拖動事件上
18 basket.showturtle()
第20-23行創建了繪制蘋果印模的畫筆對象,并設置了其顏色與形狀。
20 #用來顯示蘋果的印模
21 mould=model.clone()
22 mouldcolor('red')
23 mould.shape('circle')
第25-28行創建了繪制得分文字的畫筆,設置了顏色與位置。
26 board = model.clone()
27 board.goto(-300,-300)
28 board.color('blue')
循環體部分前聲明了蘋果列表與當前得分,隨后進入無限循環;循環體內首先清除了上一幀繪制的蘋果。
30 apples=[]
31 score=0
32 while True:
33 mould.clearstamps()
隨后,根據隨機數值確定當前幀是否生成蘋果,并將相應生成的蘋果加入列表內,每個對象記錄了橫縱坐標與下落速度。
34 if randrange(FREQ)==0:
35 #生成蘋果[x,y,s]加入列表,s是一次下落高度
36 apples.append([randrange(-350,350),400,5+ randrange(10)])
38-52行為主要的濤戲邏輯:首先記錄籃子橫縱坐標為b_x與b_y,隨后遍歷蘋果列表中每個對象。
38 b_x. b_y=basket.pos()
39 for apple in apples:
對每個蘋果,在40-43行,首先使其下落相應高度,并在下落后的位置使用stamp繪制。
40 #蘋果下落,并用印模畫出蘋果
41 apple[1]-=apple[2]
42 mould.goto(apple[0], apple[1])
43 mould.stamp()
之后,44-52行中判斷了每個蘋果的位置,若在籃子內則加分并移除;若落出底邊則扣分并移除。
44 #判斷蘋果的位置
45 if,abs(apple[0]-b_x)<=100 and -<=apple[1]-b_y<=25:
46 #籃子碰上了蘋果,加分
47 score+=10
48 apples.remove(apple)
49 elif apple[1]<-400:
50 #蘋果掉出底線,沒接到,減分
51 score-= 100
52 apples.remove(apple)
最后,在54-57行,由得分板畫筆寫出當前得分,并刷新屏幕呈現內容,最后按幀率停頓相應時間。
54 board.clear()
55 board.write(f'SCORE: {score}',font=('SYSTEM', 40,'normal'))
56 turtle.update()
57 time.sleep(1/FPS)
【因篇幅所限,以下創意編程實例中的“程序代碼分析”部分,請訪問雜志官網閱讀。】
數學對象可視化:玫瑰曲線
本作品通過玫瑰曲線的數學定義,使用turtle庫繪制出來。通過改變代碼內參數可繪制不同的玫瑰曲線。程序運行結果如圖2。
turtle功能
本作品涉及的turtle功能有2個。
第1個是通過pencolor與pensize函數設置畫筆顏色與大小,此外還有fillcolor設
置填充色,color同時設置畫筆色與填充色,shapesize設置畫筆形狀大小等函數。例如程序10-11行。
10 rose.pencolor('red')
11 rose.pensize(7)
第2個是設置動畫移動速度,如第12行設置其為最快。
12 rose.speed('fastest')
數學財象可視化:分形Koch雪花
本作品通過科赫曲線的定義,將3條科赫曲線繪制成為雪花形狀的分形進行呈現。程序運行效果如圖3。
turtle功能
本作品涉及到的turtle模塊功能主要有2個。
第1個是取消動畫效果與手動更新。
3 turtle.tracer(0)#取消動畫加快繪圖速度
35 turtle.update()#與tracer配合使用
第2個是turtle中的顏色系統,不僅可以指定RGB值設置顏色,也包括很多由顏色名稱預置的顏色,如"sky blue"與"snow";此外,可以通過bgcolor設置畫布顏色,以及begin_fill與end_fill填充多邊形內部。
4 turtle.bgcolor('sky blue')
26
snow.flllcolor('snow')
27 snow.begin_fill()
數學對象可視化:蒙特卡洛法求圓周率
本作品模擬了經典的平面授點求圓周率的過程,將投點的過程與相應的估算圓周率通過turtle可視化為動畫。程序運行效果如圖4。
turtle功能
本作品涉及到的turtle模塊功能主要有4個。
首先是繪圖加速功能,通過turtle.tracer(0)關閉動畫效果,輔以手動的turtle。update()更新畫面。
3
turtle.tracer(0)
42
#刷新屏幕
43
turtle.update()
其次是移動系統,包括坐標移動函數goto,前進轉向等控制方式forward. left等,以及預定義的軌跡移動,如circle函數。
14 t.goto(0, -R)
15 t.pendown()
16 t.circle(R)
17 for i in range(4):
18
t.forward(R)
19
t.left(90)
20
t.forward(R)
21 t.penup()
第3個是dot畫點的功能,可以輸入參數指定點大小與顏色。
29 if x **2+y**2<=R**2:
30 n+=1
31 t.dot(3,'red')
32 else:
33 t.dont(.,'black')
最后是write繪制文字的功能。
38
#顯示文字
39
label.clear()
40
label.write(f'pi~={pi: .6f}({n:7):{m 6}),font=FONT)
物理仿真:拋物和碰撞
本作品通過歐拉法逐幀模擬了一個小球受到重力與空氣阻尼(正比于速度)作用,進行斜拋運動,并在墻面與地面發生彈性碰撞的現象。通過turtle庫可視化了墻面與地面的位置,以及小球的運動路線,并且保留繪制了小球從發射到減速停止的運動軌跡。程序運行效果如圖5。
turtle功能
本作品涉及到的turtle功能主要有3個。
第1個是繪制加速和千動更新畫面。
3
turtle.tracer(0)
42
turtle.update()
第2個是繪制路徑的基本功能。
14 #繪制地面和墻
15 ball.pencolor('blue')
16 ball.penup()
17
ball.goto(-500,GROUND_Y)
18 ball.pendown()
19
ball.goto(WALL_X,GROUND_Y)
20 ball.goto(WALL_X,500)
第3個是更改形狀與形狀大小。
12
ball = turtle.Turtle ('circle')
13 ball.shapesize(R / 10)
地球空間信息可視化:地圖繪制
本作品結合了shapefile庫(通過pip install pyshp安裝)的功能,讀取ESRI Shapefile (shp)地圖矢量圖文件,并使用turtle庫將其繪制出來。程序運行效果如圖6。
turtle功能
本作品涉及的turtle功能有3個。
第1個是海龜繪圖加速功能。
1
import turtle, random
2
import shapefile#需要安裝shapefile模塊,讀取
4 turtle.tracer(0) #海龜加速,無動畫
47 turtle.update()
第2個是turtle畫布的設置,包括第17行設置窗口寬高,與第21行謾置坐標系。
17 turtle.setup(w+20,h+30)
18
19 #將海龜坐標系設置為與地圖坐標相同
20
#turtle. setworldcoordinates (layer.bbox[0], layer.bbox[l], layer.bbox[2], layer bbox[3])
21
turtle. setworldcoordinates( *layer. bbox)
第3個是多邊形的繪制與上色,turtle中要繪制復雜邊界的區域,并對其內部進行上色時,使用begin_fill與end_fill函數標記區域邊界的起止,在落筆前調用beginfill()并在結束繪制后調用end_fill()就會根據畫筆當前通過color或fillcolor函數設置的填充顏色對其間經過的區域進行上色。如代碼中32-43行。
32 for xy in f.shape.points:
33 map_pen.goto(xy)
34 if new_polygon :
35
start xy
36 map_pen.pendown()
37 map_pen.fillcolor(random. choice(colors))
38 map_pen.begin_fill()
39 new_polygon = False
40 elif xy == start:
41 map_pen.endjll()
42 map_pen.penup()
43 new_polygon = True
生物學仿真:標記重捕法
櫟記重捕法是生物學上用于研究一個地區種群數量的方法,通過捕捉少量的個體進行標記并放回,一段時間后重新捕捉,并通過重捕數、重捕的標記數與標記總數估算出整個種群的數量。本作品通過turtle可視化了標記重捕法中標記、放回、重捕的動態過程,并且即時地進行數量估算,與實際數量進行對比,將估算公式與結果以文字形式輸出。程序運行截圖如圖7。
turtle功能
本作品涉及到的turtle模塊功能主要有4個。
首先是繪圖加速功能,通過turtletracer(0)關閉動畫效果,輔以手動的turtle.tracer(0)關閉動畫效果,輔以手動的turtle.update()更新畫面。
4
turtle.tracer(0)
75
turtle.update()
其次是基礎的坐標移動與畫線功能。
27
for x in SIZEC, SIZEP:
28
tt.goto(-x, x)
29
tt.pendown()
30
tt.goto(-x, -x)
31
tt.goto(x, -x)
32
tt.goto(x, x)
33
tt.goto(-x, x)
34
tt.penup()
第3個是dot畫點的功能。
59
#繪制
60
t_dot.goto(pos)
61
t_dot.dot()
最后是write繪制文字的功能。
71
t_text.clear()
72
t_text.write(
73
'Actual: %\nEstimated: %s= %s'%(N, n_calc, formula), font=FON)
Python語言是一種語法簡潔、功能強大而又對初學者友好的通用型編程語言,在標準的Python語言發行版中,內置了入門快、表現力強的turtle模塊,讓初學者通過幾行代碼就能繪出精美的圖形,再通過簡單的邏輯即可進行鍵盤鼠標的交互。Python語言及turtle模塊的組合非常適合初學者進行創意編程的起點和創作工具,本文展示了藝術化的數字圖形之外,在基礎教育中各學科創意編程的實例,希望以此拋磚引玉,讀者們可以創作出更多面向科學探索的創意編程作品。