图1:turtle 中的小海龟
# 导入turtle模块 import turtle # 创建一张画布 wn = turtle.Screen() # “告诉”小海龟, 向前移动150“步” turtle.forward(150) # 向左转90度 turtle.left(90) # 再向前移动75“步” turtle.forward(75) # 结束绘图 turtle.done() 首先,我们需要导入turtle模块。 import turtle提示:turtle 是一个内置模块,因此我们无须安装其他软件,就可以直接使用它。
wn = turtle.Screen()
画布分为 4 个象限,如图2所示,小海龟开始的位置是屏幕中心,也就是点 (0,0) 的位置,我们也常称这点为 Home。
图2:画布
turtle.forward(150)
接着左转 90 度。turtle.left(90)
再往前移动75“步”,如图3所示。turtle.forward(75)
最后通过 turtle.done() 结束绘图。
图3:绘制效果
import turtle wn = turtle.Screen() # 调整画笔的颜色为红色 turtle.pencolor('red') # 调整画笔的粗细为5 turtle.pensize(5) turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.done()调整画笔的颜色为红色。
turtle.pencolor('red')
调整画笔的粗细为 5。turtle.pensize(5)
提示:在 turtle 中,颜色的表示有 3 种方式:import turtle wn = turtle.Screen() turtle.pencolor('red') # 设置填充的颜色为黄色 turtle.fillcolor('yellow') # 开始填充颜色 turtle.begin_fill() # 使用循环绘制正方形的边 for i in range(4): turtle.forward(100) turtle.left(90) # 结束填充颜色 turtle.end_fill() turtle.done()由于正方形每一条边的绘制方式相同,我们用循环语句来代替重复的绘图指令。执行程序后,画布上的最终效果如图4所示。
图5:菱形
import turtle wn = turtle.Screen() turtle.pencolor('red') turtle.fillcolor('yellow') #将每次转动的角度保存为列表 degree_list = [-30, 60, 120, 60] turtle.begin_fill() for i in range(4): # 采用查表的方式获取转动角度 turtle.left(degree_list[i]) turtle.forward(100) turtle.end_fill() turtle.done()
import turtle wn = turtle.Screen() # 多边形的边数 edge_count = 6 # 多边形的边长(大小相近的多边形,边数越多,边长越小) edge_length = 500 / edge_count # 多边形每条边转动的角度等于360度除以边数 edge_angle = 360 / edge_count for i in range(edge_count): turtle.forward(edge_length) turtle.left(edge_angle) turtle.done()注意 edge_count 这个变量,它代表多边形的边数。我们将这个变量依次赋值为 6、8、12、16、60,并分别执行程序,可以看到依次绘制出图6所示的六边形、八边形、十二边形、十六边形、六十边形。
图6:多边形
import turtle wn = turtle.Screen() # 直接绘制半径为100的圆形 turtle.circle(100) turtle.done()直接使用 circle() 函数绘制圆形非常方便、简捷。但我们也要知道 circle() 函数的原理,用该函数画出的圆是由很多的小线段(或小点)组成的。另外,turtle 还提供一个 dot() 函数用于直接绘制实心圆。
import turtle wn = turtle.Screen() turtle.pencolor('silver') turtle.fillcolor('silver') # 分3行绘制 for i in range(3): # 分3列绘制 for j in range(3): # 提起画笔,避免画笔移动的时候“污染”画布 turtle.penup() # 将画笔移动到特定的位置 turtle.goto(j*150, 200 - i * 150) # 调整画笔的方向为向上 turtle.setheading(90) # 落下画笔,准备画图 turtle.pendown() turtle.begin_fill() # 绘制半径为50,角度依次增大 turtle.circle(50, (i * 3 + j + 1) * 40) turtle.end_fill() turtle.done()在以上的例子中,我们绘制了 9 个不同完整度的圆,如图7所示。
图7:设置不同角度参数的绘制效果
图8:椭圆
import turtle import math def myellipse(a,b, steps): """ 绘制椭圆的自定义函数 a: 椭圆宽度的一半 b: 椭圆高度的一半 steps: 绘制椭圆的步数,步数越多,椭圆绘制得越精细 """ # 每一步转动的角度 step_angle = (2*math.pi/360) * 360 / steps # 画笔放置到开始位置 turtle.penup() turtle.setpos(a,0) turtle.pendown() # 一步一步地勾勒出椭圆 for i in range(steps): next_point = [a*math.cos((i+1)*step_angle),-b*math.sin((i+1)* step_angle)] # 绘制一个点 turtle.setposition(next_point) wn = turtle.Screen() # 调用自定义函数,绘制椭圆 myellipse(100, 50, 200) turtle.done()
import turtle wn = turtle.Screen() turtle.pencolor('red') turtle.write('普通', font=('宋体', 24, 'normal')) turtle.penup() turtle.goto(0, -100) turtle.pendown() turtle.write('粗体', font=('宋体', 24, 'bold')) turtle.penup() turtle.goto(0, -200) turtle.pendown() turtle.write('粗体+斜体+下划线', font=('宋体', 24, 'bold', 'italic', 'underline')) turtle.done()程序执行结果如图9所示。
图9:程序执行效果
write(arg,move=false,align='left',font=('fontname,fontsize,fonttype'))
其中的参数说明如下:import turtle import math def mycircle(cx, cy, r, pencolor='black', fillcolor='white', pensize = 1): """ 在指定位置绘制指定大小和颜色的圆形 cx: 原点x坐标 cy: 原点y坐标 r: 圆的半径 pencolor: 画笔颜色,默认为黑色 fillcolor: 填充颜色,默认为白色 pensize: 画笔的粗细,默认为1 """ turtle.penup() turtle.goto(cx, cy) turtle.pendown() turtle.pensize(pensize) turtle.pencolor(pencolor) turtle.begin_fill() turtle.fillcolor(fillcolor) turtle.circle(r) turtle.end_fill() def myellipse(cx, cy, a, b, pencolor='black', fillcolor='white', pensize = 1, rotate = 0, from_angle = 0, to_angle = 360, steps = 60): """ 在指定位置绘制指定大小和颜色的椭圆 cx: 原点x坐标 cy: 原点y坐标 a: 椭圆宽度的一半 b: 椭圆高度的一半 pencolor: 画笔颜色,默认为黑色 fillcolor: 填充颜色,默认为白色,如果为None,则不填充 pensize: 画笔的粗细,默认为1 rotate: 椭圆旋转的角度 from_angle: 绘制的起始角度,默认为0 to_angle: 绘制的结束角度,默认为360 steps: 绘制椭圆的步数,步数越多,椭圆绘制得越精细 """ # 每一步转动的角度 step_angle = (2*math.pi/360) * 360 / steps from_step = int(steps * from_angle / 360) to_step = int(steps * to_angle / 360) rotate_angle = rotate*2*math.pi/360 # 将画笔放到开始位置 turtle.penup() angle = from_step*step_angle x = cx + a*math.cos(angle)*math.cos(rotate_angle)- b*math.sin(angle)*math.sin(rotate_angle) y = cy + a*math.cos(angle)*math.sin(rotate_angle)+ b*math.sin(angle)*math.cos(rotate_angle) turtle.goto(x, y) turtle.pendown() turtle.pensize(pensize) turtle.pencolor(pencolor) if not fillcolor is None: turtle.begin_fill() turtle.fillcolor(fillcolor) # 一步一步地勾勒出椭圆 for i in range(from_step, to_step): angle = (i + 1) * step_angle x = cx + a*math.cos(angle)*math.cos(rotate_angle)- b*math.sin(angle)*math.sin(rotate_angle) y = cy + a*math.cos(angle)*math.sin(rotate_angle)+ b*math.sin(angle)*math.cos(rotate_angle) # 绘制一个点 turtle.goto(x, y) if not fillcolor is None: turtle.end_fill() # 准备工作 wn = turtle.Screen() # 进行快速绘制 turtle.speed('fastest') # 隐藏绘制光标 turtle.hideturtle() # 画耳朵 mycircle(-150, 150, 100, 'black', 'black') mycircle(150, 150, 100, 'black', 'black') # 画整个头 mycircle(0, -80, 150, 'black', 'black') # 画下巴 myellipse(0, -40, 70, 90, 'black', 'navajowhite', 3) # 画两腮 myellipse(-100, -20, 50, 90, 'navajowhite', 'navajowhite', 3, 45) myellipse(100, -20, 50, 90, 'navajowhite', 'navajowhite', 3, 135) myellipse(-100, -20, 50, 90, 'black', None, 3, 45, 30, 250) myellipse(100, -20, 50, 90, 'black', None, 3, 135, 120, 340) # 画前额 myellipse(-30, 90, 70, 110, 'navajowhite', 'navajowhite') myellipse(30, 90, 70, 110, 'navajowhite', 'navajowhite') # 画眼眶 myellipse(-35, 80, 25, 45, 'black', 'navajowhite') myellipse(35, 80, 25, 45, 'black', 'navajowhite') # 画眼珠 myellipse(-35, 50, 10, 16, 'black', 'black') myellipse(35, 50, 10, 16, 'black', 'black') myellipse(0, -5, 100, 30, 'black', 'navajowhite', 3, 0, 60, 120) # 画嘴 mycircle(0, -100, 45, 'black', 'black') mycircle(0, -85, 20, 'black', 'red') myellipse(0, 0, 100, 70, 'black', 'navajowhite', 3, 0, 180, 360) # 画鼻子 myellipse(0, -15, 30, 25, 'black', 'black') myellipse(0, -10, 12, 8, 'white', 'white') turtle.done()程序执行后的结果如图 10 所示。
图10:卡通米奇
图11:六点连线游戏
图12:3条线组成一个三角形
import turtle import math # 设定6个点的总距离 EDGE_LENGTH = 300 screen = turtle.Screen() screen.setup(800,800) screen.title("六点连线游戏") screen.tracer(0,0) turtle.hideturtle() def gen_dots(): """ 创建6个小圆点 """ r = [] turtle.penup() turtle.goto(EDGE_LENGTH, 0) turtle.left(60) for i in range(6): r.append(turtle.position()) turtle.left(60) turtle.forward(EDGE_LENGTH) return r def draw_dot(x,y,color): """ 绘制小圆点 x: 小圆点x坐标 y: 小圆点y坐标 color: 小圆点的颜色 """ turtle.penup() turtle.goto(x,y) turtle.color(color) turtle.dot(15) def draw_line(p1,p2,color): """ 绘制连线 p1: 连线的端点1 p2: 连线的端点2 color: 连线的颜色 """ turtle.penup() turtle.pensize(3) turtle.goto(p1) turtle.pendown() turtle.color(color) turtle.goto(p2) def draw_play_dots(): """ 绘制游戏中的圆点 """ global selection for i in range(len(dots)): if i in selection: draw_dot(dots[i][0],dots[i][1],turn) else: draw_dot(dots[i][0],dots[i][1],'dark gray') def draw(): """ 绘制游戏界面 """ global dots draw_play_dots() for i in range(len(red)): draw_line(dots[red[i][0]], dots[red[i][1]], 'red') for i in range(len(blue)): draw_line(dots[blue[i][0]], dots[blue[i][1]], 'blue') screen.update() def play(x,y): """ 游戏处理 x: 鼠标单击点的x坐标 y: 鼠标单击点的y坐标 """ global selection,turn,red,blue # 计算每个点与鼠标单击点的距离 for i in range(len(dots)): dist = math.sqrt((dots[i][0]-x)**2 + (dots[i][1]-y)**2) if dist<8: # 如果距离小于圆点的半径 # 当某个圆点已经被选中,则从选中集合中删除该圆点 # 否则将该圆点放入选中集合 if i in selection: selection.remove(i) else: selection.append(i) break if len(selection)==2: # 如果选中了两个点,则首先对这两个点重新排列 # 编号小的排在前面,编号大的排在后面 selection=(min(selection),max(selection)) # 如果新选中的一对点不属于红方也不属于蓝方 # 则将这一对点归入红方或蓝方的集合,并清空选中的点的集合 if selection not in red and selection not in blue: if turn=='red': red.append(selection) else: blue.append(selection) turn = 'red' if turn=='blue' else 'blue' selection = [] draw() # 判断游戏胜负 r = gameover(red,blue) if r!=0: screen.textinput('游戏结束:',r+' 胜利!请输入获胜者的名字:') turtle.bye() def gameover(r,b): """ 游戏胜负判断 """ if len(r)<3: return 0 r.sort() for i in range(len(r)-2): for j in range(i+1,len(r)-1): for k in range(j+1,len(r)): if r[i][0]==r[j][0] and r[i][1]==r[k][0] and r[j] [1]== r[k][1]: return '蓝方' if len(b)<3: return 0 b.sort() for i in range(len(b)-2): for j in range(i+1,len(b)-1): for k in range(j+1,len(b)): if b[i][0]==b[j][0] and b[i][1]==b[k][0] and b[j] [1]== b[k][1]: return '红方' # 返回0,表示没有分出胜负 return 0 # ================ 游戏主程序 ================ # 当前选中点的集合 selection = [] # 当前的操作人:红方或蓝方 turn = 'red' # 6个点的位置 dots = gen_dots() # 红方选中的点的集合 red = [ ] # 蓝方选中的点的集合 blue = [ ] draw() # 通过处理游戏中的鼠标单击(onclick)事件,响应玩家的操作 screen.onclick(play)
本文链接:http://task.lmcjl.com/news/15803.html