超酷!用 Python 教你绘制皮卡丘和哆啦A梦

简介: 本文利用 Python 绘制两个卡通角色,并带大家熟悉一下绘图程序包 turtle 的一些用法

在使用之前请确保 turtle 已经安装成功,第一次安装 turtle 时,用的是 pip 安装包,但总会出现下面的错误,

经查阅资料找到了一种可行的解决方法:

微信图片_20220520110048.jpg



  • 2,解压 1 中的压缩包,修改其中的 setup.py 脚本:修改方法在40行处的 ValueError,ve;微信图片_20220520110105.jpg
except ValueError, ve:


  • 改为
except (ValueError, ve):


  • 3, 使用 pip 命令对本地下载文件进行安装
pip install C:\Users\XXX\Desktop\turtle-0.0.2


2, turtle 命令介绍

turtle 绘图时有个特点,代码行数看起来比较大,但用到的也就是命令操作,来回使用;这里我提前把 turtle 几个常用的命令罗列出来,并在旁边简单介绍一下其用法,方便大家的学习:

Func(函数) Para type(参数类型) Desc(描述)
turtle.screensize(a,b,bg) int;int;colorstring /tuple 创建一个 a*b 大小的画布,bg为背景颜色,为 r,g,b 组成的元组;
turtle.title(name) string 画布窗口名字设为 name
turtle.mainloop() -(表示无参数) 启动事件循环,该语句使用时必须放在最后一句
turtle.Turtle() - RawTurtle()的子类,是画笔的对象,l来设置画笔相关属性
turtle.Turtle().tracer(bool) bool bool = False ,表示绘制开始前调用;bool=True 表示绘制开始后调用
turtle.Turtle().pensize(size) int 把画笔大小设置为 size ;
turtle.Turtle().seth(to_angle)
/turtle.Turtle().sething(to_angle)
float/int turtle 方向角度设为 to_angle
turtle.Turtle().setx(x) int/float 设置 turtle 的横坐标 x, y保持不变
turtle.Turtle().sety(y) int/float 设置 turtle 的纵坐标 y, x保持不变
turtle.Turtle().forward(distance)
turtle.Turtle().fd(distance)
int/float 画笔按原来方向向前移动 distance 个单位
turtle.Turtle().backward(distance)
turtle.Turtle().bk(distance)
turtle.Turtle().back(distance)
int/float 画笔按原来方向向后移动 distance 个单位
turtle.Turtle().left(distance)
turtle.Turtle().lt(distance)
int/float 画笔按原来方向向左移动 distance 个单位
turtle.Turtle().right(distance)
turtle.Turtle().rt(distance)
int/float 画笔按原来方向向右移动 distance 个单位
turtle.Turtle().goto(x,y) float/int,float/int 画笔跳到指定坐标位置(x,y)
turtle.Turtle().circle(radius,extends) int/float,int/float/None 绘制一个指定半径(radius)的圆,圆心根据半径、画笔方向,绘制圆角度三者决定;extends 为绘制的角度(小于360 表示绘制部分圆弧),extend为正值绘制方向为逆时针方向,否则顺时针;
turtle.Turtle().speed(num) int/float 设定画笔绘制速度为 num
turtle.Turtle().penup()
turtle.Turtle().up()
- 抬起画笔,停止绘制
turtle.Turtle().pendown()
turtle.Turtle().down()
- 放下画笔,开始绘制
turtle.Turtle().fillcolor(color) string/tuple/colorname 设置画笔填充颜色 color ,输入格式支持四种:颜色代码字符串('#000000'),rgb元组((r,g,b)),tk指定颜色字符串("红色")
turtle.Turtle().begin_fill() - 调用后开始对绘制的形状填充颜色
turtle.Turtle().end_fill() - 调用后停止填充颜色


: func 中换行表示或的意思,每种函数名有它的缩写,所以存在函数 有2-3 种 不同写法,但函数功能是一样的, - 表示无参数;

… 关于 turtle 相关方法和类还有很多,这里列出来的只是常用的一部分,有兴趣的可以仔细去看一下官网文档,链接为:https://docs.python.org/3.7/library/turtle.html?highlight=screensize#turtle.seth


3,绘制皮卡丘


代码部分

'''
绘制皮卡丘
'''
import turtle
def getPosition(x,y):
    turtle.setx(x)
    turtle.sety(y)
    print(x,y)
class Pikachu:
    def __init__(self):
         self.t = turtle.Turtle()
         t = self.t
         t.pensize(3) # 画笔大小
         t.speed(9) #画笔速度
         t.ondrag(getPosition)
    def onTrace_goto(self,x,y):
        self.t.penup()
        self.t.goto(x,y)
        self.t.pendown()
    def leftEye(self,x,y):
        self.onTrace_goto(x,y)
        t = self.t
        t.seth(0)
        t.fillcolor('#333333')
        t.begin_fill()
        t.circle(22)
        t.end_fill()
        self.onTrace_goto(x,y+10)
        t.fillcolor('#000000')
        t.begin_fill()
        t.circle(10)
        t.end_fill()
        self.onTrace_goto(x+6,y+22)
        t.fillcolor('#ffffff')
        t.begin_fill()
        t.circle(10)
        t.end_fill()
    def rightEye(self,x,y):
        self.onTrace_goto(x,y)
        t = self.t
        t.seth(0)
        t.fillcolor('#333333')
        t.begin_fill()
        t.circle(22)
        t.end_fill()
        self.onTrace_goto(x,y+10)
        t.fillcolor('#000000')
        t.begin_fill()
        t.circle(10)
        t.end_fill()
        self.onTrace_goto(x-6,y+22)
        t.fillcolor('#ffffff')
        t.begin_fill()
        t.circle(10)
        t.end_fill()
    def mouth(self,x,y):
        self.onTrace_goto(x,y)
        t = self.t
        t.fillcolor('#88141D')
        t.begin_fill()
        # 下嘴唇
        l1 = []
        l2 = []
        t.seth(190)
        a = 0.7
        for i in range(28):
            a +=0.1
            t.right(3)
            t.fd(a)
            l1.append(t.position())
        self.onTrace_goto(x,y)
        t.seth(10)
        a = 0.7
        for i in range(28):
            a +=0.1
            t.left(3)
            t.fd(a)
            l2.append(t.position())
        #上嘴唇
        t.seth(10)
        t.circle(50,15)
        t.left(180)
        t.circle(-50,15)
        t.circle(-50,40)
        t.seth(233)
        t.circle(-50,55)
        t.left(180)
        t.circle(50,12.1)
        t.end_fill()
        # 舌头
        self.onTrace_goto(17,54)
        t.fillcolor('#DD716F')
        t.begin_fill()
        t.seth(145)
        t.circle(40,86)
        t.penup()
        for pos in reversed(l1[:20]):
            t.goto(pos[0],pos[1]+1.5)
        for pos in l2[:20]:
            t.goto(pos[0],pos[1]+1.5)
        t.pendown()
        t.end_fill()
        # 鼻子
        self.onTrace_goto(-17,94)
        t.seth(8)
        t.fd(4)
        t.back(8)
    # 红脸颊
    def leftCheck(self,x,y):
        turtle.tracer(False)
        t = self.t
        self.onTrace_goto(x,y)
        t.seth(60)
        t.fillcolor('#DD4D28')
        t.begin_fill()
        a = 2.3
        for i in range(120):
            if 0 <= i <30 or 60 <= i <90:
                a -= 0.05
                t.lt(3)
                t.fd(a)
            else:
                a += 0.05
                t.lt(3)
                t.fd(a)
        t.end_fill()
        turtle.tracer(True)
    def rightCheck(self,x,y):
        t = self.t
        turtle.tracer(False)
        self.onTrace_goto(x,y)
        t.seth(60)
        t.fillcolor('#DD4D28')
        t.begin_fill()
        a = 2.3
        for i in range(120):
            if 0<= i<30 or 60 <= i< 90:
                a -= 0.05
                t.lt(3)
                t.fd(a)
            else:
                a += 0.05
                t.lt(3)
                t.fd(a)
        t.end_fill()
        turtle.tracer(True)
    def colorLeftEar(self,x,y):
        t = self.t
        self.onTrace_goto(x,y)
        t.fillcolor('#000000')
        t.begin_fill()
        t.seth(330)
        t.circle(100,35)
        t.seth(219)
        t.circle(-300,19)
        t.seth(110)
        t.circle(-30,50)
        t.circle(-300,10)
        t.end_fill()
    def colorRightEar(self,x,y):
        t = self.t
        self.onTrace_goto(x,y)
        t.fillcolor('#000000')
        t.begin_fill()
        t.seth(300)
        t.circle(-100,30)
        t.seth(35)
        t.circle(300,15)
        t.circle(30,50)
        t.seth(190)
        t.circle(300,17)
        t.end_fill()
    def body(self):
        t = self.t
        t.fillcolor('#F6D02F')
        # 右脸轮廓
        t.penup()
        t.circle(130,40)
        t.pendown()
        t.circle(100,105)
        t.left(180)
        t.circle(-100,5)
        # 右耳朵
        t.seth(20)
        t.circle(300,30)
        t.circle(30,50)
        t.seth(190)
        t.circle(300,36)
        # 上轮廓
        t.seth(150)
        t.circle(150,70)
        #左耳朵
        t.seth(200)
        t.circle(300,40)
        t.circle(30,50)
        t.seth(20)
        t.circle(300,35)
        # 左脸轮廓
        t.seth(240)
        t.circle(105,95)
        t.left(180)
        t.circle(-105,5)
        #左手
        t.seth(210)
        t.circle(500,18)
        t.seth(200)
        t.fd(10)
        t.seth(280)
        t.fd(7)
        t.seth(210)
        t.seth(300)
        t.circle(10,80)
        t.seth(220)
        t.seth(10)
        t.seth(300)
        t.circle(10,80)
        t.seth(240)
        t.fd(12)
        t.seth(0)
        t.fd(13)
        t.seth(240)
        t.circle(10,70)
        t.seth(10)
        t.circle(10,70)
        t.seth(10)
        t.circle(300,18)
        t.seth(75)
        t.circle(500,8)
        t.left(180)
        t.circle(-500,15)
        t.seth(250)
        t.circle(100,65)
        # 左脚
        t.seth(320)
        t.circle(100,5)
        t.left(180)
        t.circle(-100,5)
        t.seth(220)
        t.circle(200,20)
        t.circle(20,70)
        t.seth(60)
        t.circle(-100,20)
        t.left(180)
        t.circle(100,20)
        t.seth(300)
        t.circle(10,70)
        t.seth(60)
        t.circle(-100,20)
        t.left(180)
        t.circle(100,20)
        t.seth(10)
        t.circle(100,60)
        # 横向
        t.seth(180)
        t.circle(-100,10)
        t.left(180)
        t.circle(100,10)
        t.seth(5)
        t.circle(100,10)
        t.circle(-100,40)
        t.circle(100,35)
        t.left(180)
        t.circle(-100,10)
        # 右脚
        t.seth(290)
        t.circle(100,55)
        t.circle(10,50)
        t.seth(120)
        t.circle(100,20)
        t.left(180)
        t.circle(-100,20)
        t.seth(0)
        t.circle(10,50)
        t.seth(110)
        t.circle(110,20)
        t.left(180)
        t.circle(-100,20)
        t.seth(30)
        t.circle(20,50)
        t.seth(100)
        t.circle(100,40)
        # 右侧身体轮廓
        t.seth(200)
        t.circle(-100,5)
        t.left(180)
        t.circle(100,5)
        t.left(30)
        t.circle(100,75)
        t.right(15)
        t.circle(-300,21)
        t.left(180)
        t.circle(300,3)
        # 右手
        t.seth(43)
        t.circle(200,60)
        t.right(10)
        t.fd(10)
        t.circle(5,160)
        t.seth(90)
        t.circle(5,160)
        t.seth(90)
        t.fd(10)
        t.seth(90)
        t.circle(5,180)
        t.fd(10)
        t.left(180)
        t.left(20)
        t.fd(10)
        t.circle(5,170)
        t.fd(10)
        t.seth(240)
        t.circle(50,30)
        t.end_fill()
        self.onTrace_goto(130,125)
        t.seth(-20)
        t.fd(5)
        t.circle(-5,160)
        t.fd(5)
        # 手指纹
        self.onTrace_goto(166,130)
        t.seth(-90)
        t.fd(3)
        t.circle(-4,180)
        t.fd(3)
        t.seth(-90)
        t.fd(3)
        t.circle(-4,180)
        t.fd(3)
        # 尾巴
        self.onTrace_goto(168,134)
        t.fillcolor('#F6D02F')
        t.begin_fill()
        t.seth(40)
        t.fd(200)
        t.seth(-80)
        t.fd(150)
        t.seth(210)
        t.fd(150)
        t.left(90)
        t.fd(100)
        t.right(95)
        t.fd(100)
        t.left(110)
        t.fd(70)
        t.right(110)
        t.fd(80)
        t.left(110)
        t.fd(30)
        t.right(110)
        t.fd(32)
        t.right(106)
        t.circle(100,25)
        t.right(15)
        t.circle(-300,2)
        t.seth(30)
        t.fd(40)
        t.left(100)
        t.fd(70)
        t.right(100)
        t.fd(80)
        t.left(100)
        t.fd(46)
        t.seth(66)
        t.circle(200,38)
        t.right(10)
        t.end_fill()
        # 尾巴花纹
        t.fillcolor('#923E24')
        self.onTrace_goto(126.82,-156.84)
        t.begin_fill()
        t.seth(30)
        t.fd(40)
        t.left(100)
        t.fd(40)
        t.pencolor('#923e24')
        t.seth(-30)
        t.fd(30)
        t.left(140)
        t.fd(20)
        t.left(150)
        t.fd(20)
        t.right(150)
        t.fd(20)
        t.left(130)
        t.fd(18)
        t.pencolor('#000000')
        t.seth(-45)
        t.fd(67)
        t.right(110)
        t.fd(30)
        t.left(110)
        t.fd(32)
        t.right(106)
        t.circle(100,25)
        t.right(15)
        t.circle(-300,2)
        t.end_fill()
        # 帽子、眼睛、嘴巴、脸颊
        self.cap(-134.07,147.81)
        self.mouth(-5,25)
        self.leftCheck(-126,32)
        self.rightCheck(107,63)
        self.colorLeftEar(-250,100)
        self.colorRightEar(150,270)
        self.leftEye(-85,90)
        self.rightEye(50,110)
        t.hideturtle()
    def cap(self,x,y):
        self.onTrace_goto(x,y)
        t = self.t
        t.fillcolor('#CD0000')
        t.begin_fill()
        t.seth(200)
        t.circle(400,7)
        t.left(180)
        t.circle(-400,30)
        t.circle(30,60)
        t.fd(60)
        t.circle(30,45)
        t.fd(60)
        t.left(5)
        t.circle(30,70)
        t.right(20)
        t.circle(200,70)
        t.circle(30,60)
        t.fd(70)
        t.right(35)
        t.fd(50)
        t.right(35)
        t.fd(50)
        t.circle(8,100)
        t.end_fill()
        self.onTrace_goto(-168.47,185.52)
        t.seth(36)
        t.circle(-270,54)
        t.left(180)
        t.circle(270,27)
        t.circle(-80,98)
        t.fillcolor('#444444')
        t.begin_fill()
        t.left(180)
        t.circle(80,197)
        t.left(58)
        t.circle(200,45)
        t.end_fill()
        self.onTrace_goto(-58,270)
        t.pencolor('#228B22')
        t.dot(35)
        self.onTrace_goto(-30,280)
        t.fillcolor('#228B22')
        t.begin_fill()
        t.seth(100)
        t.circle(30,180)
        t.seth(190)
        t.fd(15)
        t.seth(100)
        t.circle(-45,180)
        t.right(90)
        t.fd(15)
        t.end_fill()
        t.fillcolor('#228B22')
    def start(self):
        self.body()
def main():
    print(" Painting the Pikachu....")
    turtle.screensize(800,600)
    turtle.title("Pickachu")
    pickachu = Pikachu()
    pickachu.start()
    turtle.mainloop() # running
if __name__ =='__main__':
    main()


4,绘制 哆啦A梦

微信图片_20220520110141.gif

代码部分

#五轨迹跳跃
def my_goto(x,y):
    penup()
    goto(x,y)
    pendown()
def eyes():
    fillcolor('#ffffff')
    begin_fill()
    tracer(False)
    a = 2.5
    for i in range(120):
        if 0<= i<30 or 60 <= i <90:
            a -= 0.05
            lt(3)
            fd(a)
        else:
            a += 0.05
            lt(3)
            fd(a)
    tracer(True)
    end_fill()
#胡须
def beard():
    my_goto(-32,135)
    seth(165)
    fd(60)
    my_goto(-32,125)
    seth(180)
    fd(60)
    my_goto(-32,115)
    seth(193)
    fd(60)
    my_goto(37,135)
    seth(15)
    fd(60)
    my_goto(37,125)
    seth(0)
    fd(60)
    my_goto(37,115)
    seth(-13)
    fd(60)
#嘴巴
def mouth():
    my_goto(5,148)
    seth(270)
    fd(100)
    seth(0)
    circle(120,50)
    seth(230)
    circle(-120,100)
#围巾
def scarf():
    fillcolor('#e70010')
    begin_fill()
    seth(0)
    fd(200)
    circle(-5,90)
    fd(10)
    circle(-5,90)
    fd(207)
    circle(-5,90)
    fd(10)
    circle(-5,90)
    end_fill()
#鼻子
def nose():
    my_goto(-10,158)
    seth(315)
    fillcolor('#e70010')
    begin_fill()
    circle(20)
    end_fill()
#黑眼睛
def black_eyes():
    seth(0)
    my_goto(-20,195)
    fillcolor('#000000')
    begin_fill()
    circle(13)
    end_fill()
    pensize(6)
    my_goto(20,205)
    seth(75)
    circle(-10,150)
    pensize(3)
    my_goto(-17,200)
    seth(0)
    fillcolor('#ffffff')
    begin_fill()
    circle(5)
    end_fill()
    my_goto(0,0)
def face():
    fd(183)
    lt(45)
    fillcolor('#ffffff')
    begin_fill()
    circle(120,100)
    seth(180)
    fd(121)
    pendown()
    seth(215)
    circle(120,100)
    end_fill()
    my_goto(63.56,218.24)
    seth(90)
    eyes()
    seth(180)
    penup()
    fd(60)
    pendown()
    seth(90)
    eyes()
    penup()
    seth(180)
    fd(64)
def head():
    penup()
    circle(150,40)
    pendown()
    fillcolor('#00a0de')
    begin_fill()
    circle(150,280)
    end_fill()
# body
def Doraemon():
    head()
    scarf()
    face()
    nose()
    mouth()
    beard()
    my_goto(0,0)
    seth(0)
    penup()
    circle(150,50)
    pendown()
    seth(30)
    fd(40)
    seth(70)
    circle(-30,270)
    fillcolor('#00a0de')
    begin_fill()
    seth(230)
    fd(80)
    seth(90)
    circle(1000,1)
    seth(-89)
    circle(-1000,10)
    seth(180)
    fd(70)
    seth(90)
    circle(30,180)
    seth(180)
    fd(70)
    seth(100)
    circle(-1000,9)
    seth(-86)
    circle(1000,2)
    seth(230)
    fd(40)
    circle(-30,230)
    seth(45)
    fd(81)
    seth(0)
    fd(203)
    circle(5,90)
    fd(10)
    circle(5,90)
    fd(7)
    seth(40)
    circle(150,10)
    seth(30)
    fd(40)
    end_fill()
    seth(70)
    fillcolor('#ffffff')
    begin_fill()
    circle(-30)
    end_fill()
    my_goto(103.74,-182.59)
    seth(0)
    fillcolor('#ffffff')
    begin_fill()
    fd(15)
    circle(-15,180)
    fd(90)
    circle(-15,180)
    fd(10)
    end_fill()
    #右手
    my_goto(-103.42,15.09)
    seth(0)
    fd(38)
    seth(230)
    begin_fill()
    circle(90,260)
    end_fill()
    my_goto(5,-40)
    seth(0)
    fd(70)
    seth(-90)
    circle(-70,180)
    seth(0)
    fd(70)
    #铃铛
    my_goto(-103.42,15.09)
    fd(90)
    seth(70)
    fillcolor('#ffd200')
    begin_fill()
    circle(-20)
    end_fill()
    seth(170)
    fillcolor('#ffd200')
    begin_fill()
    circle(-2,180)
    seth(10)
    circle(-100,22)
    circle(-2,180)
    seth(180-10)
    circle(100,22)
    end_fill()
    goto(-13.42,15.09)
    seth(250)
    circle(20,110)
    seth(90)
    fd(15)
    dot(10)
    my_goto(0,-150)
    #画眼睛
    black_eyes()
if __name__ =='__main__':
    screensize(800,600,'#f0f0f0')
    pensize(3) # size of pen
    speed(9) # speed of pen
    Doraemon()
    my_goto(100,-300)
    write("by zeroing",font = ("Bladley Hand ITC",30,'bold'))
    mainloop()


从上面的代码行数应该了解一点, turtle 最难的地方不是它的用法,而是使用者对于整个物体的几何整体塑造,必须全局把握地非常准,否则最终很难绘制出比较满意的图案

感兴趣的同学可以直接把上面代码复制到自己的 IDE 中,直接运行就可以,以上就是本篇文章的所有内容啦,最后感谢大家的阅读!

相关文章
|
编解码 Python
python--海温、OLR数据分布做显著性检验,绘制空间分布并打点
使用python对海洋气象数据做显著性检验,并绘制空间pattern
python--海温、OLR数据分布做显著性检验,绘制空间分布并打点
|
测试技术 Python
Python:使用nltk统计词频并绘制统计图
Python:使用nltk统计词频并绘制统计图
122 0
Python:使用nltk统计词频并绘制统计图
|
Linux 定位技术 Python
python--使用cnmaps绘制省界地图(快速上手,简单有效)
cnmaps是一个致力于让中国地图的获取和使用更丝滑的python扩展包。
python--使用cnmaps绘制省界地图(快速上手,简单有效)
|
存储 数据处理 Python
python--对站点数据做EOF并做插值绘制填色图
最近,师弟在学习使用python复现毕设论文,正好之前没有处理过站点数据,也没咋用过EOF,特此记录下使用python处理站的数据的过程。
python--对站点数据做EOF并做插值绘制填色图
python--循环绘制ERA5风场的空间分布图
使用python封装绘图函数循环绘制ERA5风场资料的空间分布图
python--循环绘制ERA5风场的空间分布图
|
存储 Python
python绘图--由逐日风场数据计算月平均风场数据并绘制二维填色图
python绘图--由逐日风场数据计算月平均风场数据并绘制二维填色图
python绘图--由逐日风场数据计算月平均风场数据并绘制二维填色图
python 循环绘制子图时,设置共享x、y轴
通常在阅读文献时,发现对于一些图片的绘制时,如果存在多个子图,通常为了美观、简洁,只保留最后一列的以及最左一侧的子图的刻度
python 循环绘制子图时,设置共享x、y轴
python绘图——绘制正负区分的柱形图[ax.bar()]
python绘图——绘制正负区分的柱形图[ax.bar()]
python绘图——绘制正负区分的柱形图[ax.bar()]
|
定位技术 Python
python 绘制封装函数绘制南海小地图
python 绘制封装函数绘制南海小地图
python 绘制封装函数绘制南海小地图