(本文為前一篇文章《理解編程語(yǔ)言只需四個(gè)詞-編程知識(shí)體系介紹(帶python及scratch案例)》的說(shuō)明案例之一)
我們的這個(gè)案例要通過Python實(shí)現(xiàn),通過控制一只小烏龜喝不同顏色的墨水,當(dāng)小烏龜爬行的時(shí)候,會(huì)在身后留下不同顏色的痕跡。

8.1 程序編寫步驟
第一步:確定程序目標(biāo)
一只愛喝墨水的小烏龜,爬的過程中留下痕跡,爬行的過程就是畫線的過程。
第二步:目標(biāo)分解
我們需要讓小烏龜具備下面功能:
1.爬行到相應(yīng)的位置;
2.更換爬行痕跡的顏色;
3.蘸不同顏色的墨水;
第三步:設(shè)計(jì)原型
設(shè)計(jì)一個(gè)能爬行能變顏色的小烏龜,作為原型。
第四步:完善程序
豐富墨水顏色數(shù)量,改變?yōu)觚數(shù)耐庥^
第五步:擴(kuò)展程序
這個(gè)案例的進(jìn)一步擴(kuò)展,比如添加功能、以此為基礎(chǔ)改成其他程序等。
8.2 原型設(shè)計(jì)
下面我們開始我們的原型制作,打開IDLE,輸入以下代碼:
from turtle import *
pencolor('red')
goto(100,100)
運(yùn)行程序,我們看到了一個(gè)箭頭在屏幕上移動(dòng),并在其身后留下來(lái)一條紅色的線。這個(gè)箭頭就是我們的小烏龜了,一會(huì)而我們會(huì)讓它真的變成烏龜?shù)男螤畹?。解釋下代碼,第一行代碼from turtle import *是引入turtle類,其實(shí)這個(gè)語(yǔ)言本身已經(jīng)為我們轉(zhuǎn)備好了很多已經(jīng)完成的命令,我們只需要告訴電腦我們想使用它們就可以了,這行程序就是告訴電腦我們想使用“烏龜(turtle)”類了。第二行代碼pencolor('red')是告訴電腦把烏龜看成一只鋼筆,并把鋼筆的顏色設(shè)置成紅色。第三行代碼goto(100,100)是告訴小烏龜爬到坐標(biāo)(100,100)的位置。
這里說(shuō)一下Python Turtle的坐標(biāo)系,屏幕中央是原點(diǎn)(0,0),水平方向X軸向右方向?yàn)檎较?,垂直方向Y軸向上為正方向。
8.3 聽懂更多命令
其實(shí)小烏龜還能聽懂很多命令,我們繼續(xù)完善原型,輸入以下代碼:
from turtle import *
pencolor('red')
goto(100,100)
pencolor('green')
right(90)
forward(100)
left(45)
backward(100)
goto(100,-50)
運(yùn)行程序之后,小烏龜爬出了新的花樣,如下圖所示,變了角度,變了顏色。他是怎么做到的?
pencolor('green')這行代碼我們很熟悉了,就是把顏色由紅色變成了綠色,你也可以設(shè)置其他你喜歡的顏色。right(90)、left(45)這兩行就是告訴烏龜向右或向右旋轉(zhuǎn),括號(hào)中的數(shù)值是旋轉(zhuǎn)的角度數(shù)值。forward(100)、backward(100)是告訴小烏龜前進(jìn)或后退,括號(hào)中的數(shù)值是前進(jìn)或后退的距離。最后一行代碼goto(100,-50)我們也熟悉了,爬到坐標(biāo)(100,-50)的位置。這些命令我們以后會(huì)經(jīng)常用到,這里我們知道他們的作用就可以了。
8.4 開始蘸墨水
現(xiàn)在我們對(duì)照一下前文的目標(biāo)分解部分,基本上實(shí)現(xiàn)了三個(gè)分解目標(biāo)。下面我們完善一下功能。當(dāng)小烏龜停在X軸大于零的地方,讓它蘸紅色的墨水,當(dāng)她停在X軸小于零的地方,它蘸上藍(lán)色的墨水。添加的代碼如下,其中xcor()用于獲取小烏龜?shù)腦坐標(biāo),if語(yǔ)句用于條件判斷,“If xcor()>0”就是告訴小烏龜當(dāng)它的X坐標(biāo)大于零的時(shí)候需要做什么。
If xcor()>0:
pencolor('red')
else:
pencolor('blue')
8.5 用函數(shù)實(shí)現(xiàn)自動(dòng)蘸墨水
我們上面蘸墨水的代碼加入到一個(gè)函數(shù)中,簡(jiǎn)化我們的操作步驟。關(guān)于函數(shù)的具體細(xì)節(jié)我們會(huì)在后面的章節(jié)講解,這里我們只需要理解函數(shù)是一個(gè)能夠把很多命令放在一塊的程序塊,只要寫出程序塊的名字,就能運(yùn)行它所包含的所有程序。我們將goto命令與上述的蘸墨水命令集合在一個(gè)函數(shù)mgt(這個(gè)名字可以改變,這里是my_goto的簡(jiǎn)寫)里面。
def mgt(myx,myy):
if xcor()>0:
pencolor('red')
else:
pencolor('blue')
goto(myx,myy)
我們讓烏龜達(dá)到某一坐標(biāo),直接調(diào)用函數(shù)mgt就可以,并在括號(hào)里填上坐標(biāo)值。例如myt(100,100)就是讓烏龜爬到坐標(biāo)(100,100)的位置,這個(gè)過程中,烏龜會(huì)自己判斷該用什么顏色留下痕跡。
我們可以用同樣的方式,對(duì)forward、backward進(jìn)行處理,分別命名為mfw和mbw結(jié)果如下:
def mfd(num):
if xcor()>0:
pencolor('red')
else:
pencolor('blue')
forward(num)
def mbd(num):
if xcor()>0:
pencolor('red')
else:
pencolor('blue')
backward(num)
當(dāng)我們用mfd(150)的時(shí)候,烏龜會(huì)向前爬行150,并選擇相應(yīng)的顏色。
8.6 添加墨水池
下面我們開始第四步完善程序的部分。為了讓操作更直觀,我們?cè)谖枧_(tái)上放置兩個(gè)墨水池。代碼中大部分領(lǐng)命我們都熟悉,只有少數(shù)新的命令。其中penup()為抬起筆,烏龜爬行就不會(huì)劃線,pendown()為落筆,烏龜爬下劃線。begin_fill()與end_fill()用于填充顏色,在兩個(gè)語(yǔ)句中間畫上框架,就會(huì)用fillcolor命令設(shè)置的顏色進(jìn)行填充。
#舞臺(tái)布置
#畫第一個(gè)墨水池
penup()
goto(-300,300)
pendown()
fillcolor('red')
begin_fill()
forward(100)
right(90)
forward(100)
right(90)
forward(100)
right(90)
forward(100)
end_fill()
#畫第二個(gè)墨水池
penup()
right(90)
goto(100,300)
pendown()
fillcolor('blue')
begin_fill()
forward(100)
right(90)
forward(100)
right(90)
forward(100)
right(90)
forward(100)
end_fill()
8.7 在墨水池蘸上墨水的方法
烏龜需爬到墨水池中,爬行時(shí)候才會(huì)變?yōu)橄鄳?yīng)的顏色,這個(gè)主要通過坐標(biāo)判斷。
if xcor()>-300 and xcor()<-200 and ycor()<300 and ycor()>200:
pencolor('red')
if xcor()>100 and xcor()<200 and ycor()<300 and ycor()>200:
pencolor('blue')
這里的ycor()用于獲取烏龜?shù)腨坐標(biāo),與xcor()對(duì)應(yīng)。 條件語(yǔ)句中and 屬于邏輯運(yùn)算中的“且”關(guān)系,表示前后兩個(gè)語(yǔ)句都滿足條件才可以執(zhí)行相應(yīng)的程序。這部分內(nèi)容在后續(xù)章節(jié)中也有詳細(xì)的講解。我們需要將原型中mgt、mfd、mbd函數(shù)中用于設(shè)定顏色的語(yǔ)句改成現(xiàn)在的代碼。
8.8 烏龜現(xiàn)身
下面我們讓主角小烏龜變身,一行代碼就可以實(shí)現(xiàn)。
shape('turtle')
現(xiàn)在的代碼是這個(gè)樣子的:
from turtle import *
#設(shè)置烏龜形狀
shape('turtle')
#舞臺(tái)布置
#畫第一個(gè)墨水池
penup()
goto(-300,300)
pendown()
fillcolor('red')
begin_fill()
forward(100)
right(90)
forward(100)
right(90)
forward(100)
right(90)
forward(100)
end_fill()
#畫第二個(gè)墨水池
penup()
right(90)
goto(100,300)
pendown()
fillcolor('blue')
begin_fill()
forward(100)
right(90)
forward(100)
right(90)
forward(100)
right(90)
forward(100)
end_fill()
def mgt(myx,myy):
if xcor()>-300 and xcor()<-200 and ycor()<300 and ycor()>200:
pencolor('red')
if xcor()>100 and xcor()<200 and ycor()<300 and ycor()>200:
pencolor('blue')
goto(myx,myy)
def mfd(num):
if xcor()>-300 and xcor()<-200 and ycor()<300 and ycor()>200:
pencolor('red')
if xcor()>100 and xcor()<200 and ycor()<300 and ycor()>200:
pencolor('blue')
forward(num)
def mbd(num):
if xcor()>-300 and xcor()<-200 and ycor()<300 and ycor()>200:
pencolor('red')
if xcor()>100 and xcor()<200 and ycor()<300 and ycor()>200:
pencolor('blue')
backward(num)
#看效果
mgt(-250,250)
mbd(200)
mgt(150,250)
mbd(200)
運(yùn)行效果圖如圖4.12所示。
8.9 更多可能
我們可以嘗試讓小烏龜做出更多種可能,比如:讓小烏龜畫出一個(gè)對(duì)稱的圖形,如三角形、空心十字架、心形等;讓小烏龜畫出復(fù)雜的具體圖形,比如笑臉;畫一幅現(xiàn)代藝術(shù)的線條畫等。
8.10 輔助工具
像上一個(gè)案例一樣,為了編程方便,這里我們也用了一個(gè)輔助輔助工具:
print(xcor(),ycor())
這行代碼可以輸出烏龜?shù)腦坐標(biāo)和Y坐標(biāo)。
8.11 案例中的編程系統(tǒng)分析
我們來(lái)分析一下代碼,所有涉及到數(shù)字、顏色的地方都屬于“數(shù)據(jù)”部分。條件判斷部分屬于“控制”部分,比判斷烏龜是否在墨水池的坐標(biāo)范圍內(nèi)。而控制部分的條件則屬于“運(yùn)算”部分,如通過and進(jìn)行的邏輯運(yùn)算。其他的所有我們看得見的效果的實(shí)現(xiàn)語(yǔ)句就是“執(zhí)行”部分,如移動(dòng)距離,畫直線、變顏色等。