001-Paint_FreePythonGames項目代碼詳解(每行都有注釋!!!)


一 turtle庫

https://www.cnblogs.com/chen0307/articles/9645138.html

https://www.cnblogs.com/nier2b/p/10793235.html

1 基本概念:Turtle庫是Python語言中一個很流行的繪制圖像的函數庫,

2 原理:想象一個小烏龜,在一個橫軸為x、縱軸為y的坐標系原點,(0,0)位置開始,它根據一組函數指令的控制,在這個平面坐標系中移動,從而在它爬行的路徑上繪制了圖形。

3 常用命令:

turtle庫包含100多個功能函數,主要包括窗體函數、畫筆狀態函數和畫筆運動函數三類

  • 畫布:畫布就是turtle為我們展開用於繪圖區域,我們可以設置它的大小和初始位置。
    • 設置畫布大小: turtle.screensize(canvwidth, canvheight, bg),參數分別為畫布的寬(單位像素), 高, 背景顏色。
    • 設置畫布初始位置:turtle.setup(width, height, startx, starty),參數:width, height: 輸入寬和高為整數時, 表示像素; 為小數時, 表示占據電腦屏幕的比例,(startx, starty): 這一坐標表示矩形窗口左上角頂點的位置, 如果為空,則窗口位於屏幕中心。
  • 畫筆:
    • 畫筆的狀態:坐標原點(位置),面朝x軸正方向(方向), turtle繪圖中,就是使用位置方向描述小烏龜(畫筆)的狀態。
    • 畫筆的屬性
      • turtle.pensize():設置畫筆的寬度
      • turtle.pencolor():沒有參數傳入,返回當前畫筆顏色,傳入參數設置畫筆顏色,可以是字符串如"green", "red",也可以是RGB 3元組。
      • turtle.speed(speed):設置畫筆移動速度,畫筆繪制的速度范圍[0,10]整數,數字越大越快。
    • 繪圖命令
      • 畫筆運動命令
      • 畫筆控制命令
      • 全局控制命令
      •  其他命令

4 庫的導入https://www.jianshu.com/p/b502c89132dd

  • import turtle
    • 則對turtle庫中函數調用采用turtle.<函數名>( )形式
    • import turtle
      turtle.circle(200)
  • from turtle import *
    • 則對turtle庫中函數調用采用<函數名>( )形式,不再使用turtle.作為前導
    • 1 from  turtle  import  *
      2 circle(200)
    • 或者僅導入所使用的函數
    • 1 from  turtle  import  circle
      2 circle(200)
  • import turtle as t
    • 保留字as將turtle庫給予別名t, 則對turtle庫中函數調用采用更簡潔的t.<函數名>( )形式
    • 1 import turtle as t
      2 t.circle(200)

5 相關函數

(1)turtle.circle()函數

  • 功能:根據半徑radius繪制extent角度的弧形
  • 語法:turtle.circle(radius, extent=None)
  • 參數:正正左順,負負右逆
    • radius :弧形半徑(當radius值為正數時,圓心在當前位置/小海龜左側;當radius值為負數時,圓心在當前位置/小海龜右側。)
    • extent :弧形角度。當無該參數或參數為None時,繪制整個圓形。(當extent值為正數時,順小海龜當前方向繪制;當extent值為負數時,逆小海龜當前方向繪制。)

(2)使用屏幕事件相關函數

1) listen()函數

  • 語法:turtle.listen(xdummy=Noneydummy=None)
  • 功能:設置焦點到 TurtleScreen (以便接收按鍵事件)。使用兩個 Dummy 參數以便能夠傳遞 listen() 給 onclick 方法。

2) onkey()函數

  • 語法:turtle.onkey(fun,key)
  • 參數:
    • fun -- 一個無參數的函數或 None
    • key -- 一個字符串: 鍵 (例如 "a") 或鍵標 (例如 "space")
  • 功能:綁定 fun 指定的函數到按鍵釋放事件。如果 fun 值為 None,則移除事件綁定。注: 為了能夠注冊按鍵事件,TurtleScreen 必須得到焦點。(參見 method listen() 方法。)

3) onscreenclink()函數

  • 語法:turtle.onclick(fun,btn=1,add=None)
  • 參數:
    • fun -- 一個函數,調用時將傳入兩個參數表示在畫布上點擊的坐標。
    • btn -- 鼠標按鈕編號,默認值為 1 (鼠標左鍵)
    • add -- True 或 False -- 如為 True 則將添加一個新綁定,否則將取代先前的綁定
  • 功能:綁定 fun 指定的函數到鼠標點擊屏幕事件。如果 fun 值為 None,則移除現有的綁定。

二 代碼內容

  1 """Paint, for drawing shapes.
  2 
  3 Exercises
  4 
  5 1. Add a color.
  6 2. Complete circle.
  7 3. Complete rectangle.
  8 4. Complete triangle.
  9 5. Add width parameter.
 10 
 11 """
 12 
 13 from turtle import *                   # 導入turtle庫
 14 from freegames import vector           # 引入向量,用來定義坐標
 15 
 16 def line(start, end):                  # 定義一個畫一條線的函數,參數類型只能是向量
 17     "Draw line from start to end."
 18     penup()                            # 畫筆提起操作
 19     goto(start.x, start.y)             # 將畫筆移動到起點坐標為(x,y)的位置
 20     pendown()                          # 畫筆放下操作
 21     goto(end.x, end.y)                 # 將畫筆移動到終點坐標為(x,y)的位置
 22 
 23 def square(start, end):                # 定義一個畫正方形的函數,參數類型只能是向量
 24     "Draw square from start to end."
 25     up()                               # 畫筆提起操作
 26     goto(start.x, start.y)             # 將畫筆移動到起點坐標為(x,y)的位置
 27     down()                             # 畫筆放下操作
 28     begin_fill()                       # 准備開始填充圖形
 29 
 30     for count in range(4):             # 循環4次,用於畫矩形
 31         forward(end.x - start.x)       # 向當前畫筆方向移動一段距離,該距離是第二次點擊鼠標所在位置的橫坐標減去第一次點擊鼠標所在位置的橫坐標
 32         left(90)                       # 調整畫筆方向:逆時針移動90°
 33 
 34     end_fill()                         # 填充圖形結束
 35 
 36 def paint_circle(start, end):          # 畫圓,半徑為正(負),表示圓心在畫筆的左邊(右邊)畫圓
 37     "Draw circle from start to end."
 38     up()                               # 畫筆提起操作
 39     goto(start.x,start.y)              # 將畫筆移動到起點坐標為(x,y)的位置
 40     down()                             # 畫筆放下操作
 41     begin_fill()                       # 准備開始填充圖形
 42     fillcolor("pink")                  # 將填充顏色設置為粉色
 43     radius = end.x - start.x           # 圓的半徑是第二次點擊屏幕所在位置的橫坐標減去第一次點擊屏幕所在位置的橫坐標
 44     circle(radius)                     # radius為正,逆時針畫一個半徑為radius的圓;radius為負,順時針畫一個半徑為radius的圓
 45     end_fill()                         # 填充圖形結束
 46     # pass # TODO                      # 內容需要自己補充
 47 
 48 def rectangle(start, end):             # 畫矩形
 49     "Draw rectangle from start to end."
 50     up()                               # 畫筆提起操作
 51     goto(start.x,start.y)              # 將畫筆移動到起點坐標為(x,y)的位置
 52     down()                             # 畫筆放下操作
 53     begin_fill()                       # 准備開始填充圖形
 54 
 55     fillcolor("purple")                # 將填充顏色設置為紫色
 56     for count in range(2):             # 循環2次,用於畫矩形
 57         forward(end.x-start.x)         # 向當前畫筆方向移動一段距離
 58         left(90)                       # 調整畫筆方向:逆時針移動90°
 59         forward(end.y-start.y)         # 向當前畫筆方向移動一段距離
 60         left(90)                       # 調整畫筆方向:逆時針移動90°
 61 
 62     end_fill()
 63     # pass  # TODO
 64 
 65 def triangle(start, end):              # 畫三角形
 66     "Draw triangle from start to end."
 67     up()                               # 畫筆提起操作
 68     goto(start.x,start.y)              # 將畫筆移動到起點坐標為(x,y)的位置
 69     down()                             # 畫筆放下操作
 70     begin_fill()                       # 准備開始填充圖形
 71 
 72     fillcolor("blue")                  # 將填充顏色設置為藍色
 73     for count in range(3):             # 循環3次,用於畫正三角形
 74         forward(end.x-start.x)         # 向當前畫筆方向移動一段距離,該距離是第二次點擊鼠標所在位置的橫坐標減去第一次點擊鼠標所在位置的橫坐標
 75         left(120)                      # 調整畫筆方向:逆時針移動120°
 76 
 77     end_fill()                         # 填充圖形結束
 78     #pass  # TODO
 79 
 80 def tap(x, y):                         # 用來存儲鼠標的初始位置或者要畫的圖形
 81     "Store starting point or draw shape."
 82     start = state['start']
 83 
 84     if start is None:
 85         state['start'] = vector(x, y)   # 將字典中'start'初始化為一個向量
 86     else:
 87         shape = state['shape']          # 將字典中'shape'的值賦給shape變量
 88         end = vector(x, y)              # 定義畫圖結束位置的向量
 89         shape(start, end)               # 調用shape變量對應的函數繪制圖形
 90         state['start'] = None           # 將start字典的'start'元素值重置為None
 91 
 92 def store(key, value):                  # 用來接收鍵盤輸入的數據
 93     "Store value in state at key."
 94     state[key] = value                  # 通過更改state列表的key的值來控制畫筆的顏色和畫出的圖形
 95 
 96 state = {'start': None, 'shape': rectangle}# 定義一個字典類型state變量用來告訴程序要繪制什么圖形
 97 setup(500, 500, 500,0)                  # 設置畫布初始位置
 98 onscreenclick(tap)                      # 綁定tap函數到鼠標點擊屏幕事件,即鼠標點擊一次屏幕調用一次tap函數
 99                                         # 可能這句代碼的意思是每次在畫布上敲擊鼠標,都調用一次tap函數;
100                                         # 第一次敲擊鼠標調用tap函數后,將畫筆的起點位置狀態由None改變為一個向量vector(x, y)
101                                         # 第二次敲擊鼠標調用tap函數后,在tap函數內部調用shape值對應的函數進行畫圖
102 
103 listen()                                          # 設置焦點到 TurtleScreen (以便接收按鍵事件)
104 onkey(undo, 'u')                                  # 撤銷上一個turtle動作
105 onkey(lambda: color('black'), 'K')                # 在畫圖過程中,第一次點擊鼠標后,輸入大寫字母'K'可將畫筆的顏色設置為黑色
106 onkey(lambda: color('white'), 'W')                # 在畫圖過程中,第一次點擊鼠標后,輸入大寫字母'W'可將畫筆的顏色設置為白色
107 onkey(lambda: color('green'), 'G')                # 在畫圖過程中,第一次點擊鼠標后,輸入大寫字母'G'可將畫筆的顏色設置為綠色
108 onkey(lambda: color('blue'), 'B')                 # 在畫圖過程中,第一次點擊鼠標后,輸入大寫字母'B'可將畫筆的顏色設置為藍色
109 onkey(lambda: color('red'), 'R')                  # 在畫圖過程中,第一次點擊鼠標后,輸入大寫字母'R'可將畫筆的顏色設置為紅色
110 onkey(lambda: store('shape', line), 'l')          # 在畫圖過程中,第一次點擊鼠標后,輸入小寫字母'l'可將畫出的圖形設置為直線
111 onkey(lambda: store('shape', square), 's')        # 在畫圖過程中,第一次點擊鼠標后,輸入小寫字母's'可將畫出的圖形設置為正方形
112 onkey(lambda: store('shape', paint_circle), 'c')  # 在畫圖過程中,第一次點擊鼠標后,輸入小寫字母'c'可將畫出的圖形設置為圓
113 onkey(lambda: store('shape', rectangle), 'r')     # 在畫圖過程中,第一次點擊鼠標后,輸入小寫字母'r'可將畫出的圖形設置為矩形
114 onkey(lambda: store('shape', triangle), 't')      # 在畫圖過程中,第一次點擊鼠標后,輸入小寫字母't'可將畫出的圖形設置為三角形
115 
116 done()                                            #  必須是烏龜圖形程序中的最后一個語句。

花了三天,大概5個小時左右吧,搞懂了代碼,本來寫了三個博客,發現有完整代碼的那個博客沒人看,所以把三個博客合在一起了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM