2026/9/8 18:33:39

用Python turtle库从零绘制一条中国龙:坐标、函数与配色实战

用Python turtle库从零绘制一条中国龙:坐标、函数与配色实战 简介利用Python turtle绘制中国龙形象的完整源代码项目适合Python初学者、图形编程爱好者及对传统文化题材感兴趣的学习者。项目中包含4个文件压缩包约720KB主体为带详细注释的draw_dragon.py源码另配有效果示意图png、动态演示gif及说明文档md可直观对照运行结果与绘图逻辑。turtle模块作为Python标准库代码通过海龟移动控制绘制龙的头身四肢与尾巴并利用循环、函数和参数调整实现不同颜色与线条样式注释细致到每个函数与逻辑段便于逐行理解画法组织方式。已有1158人学习/下载适合作为教学案例或节日创意编程参考。通过这份资料读者既能演练图形绘制与代码组织技巧也能体会中国龙符号的视觉化表达是一份兼具趣味与讲解深度的入门实践资源。 第一次把这条龙跑出来的时候屏幕上那根金色描边从左侧滑到右侧红色块跟着一裹一条脑袋顶着两只角的龙就立在深蓝色背景上了。用Python画中国龙听起来像节日整活其实特别适合练手turtle是Python自带的标准库不需要装第三方依赖源代码逻辑足够清晰稍微加点注释就能当教材。这个项目的核心不是“背代码”而是搞懂坐标、填充、循环和函数封装这几件事。我建议两类人来抄作业第一种是刚学Python不久、想找个有成就感项目的新手第二种是已经会基础语法、想练代码组织和注释规范的开发者。1. 这个项目到底在画什么需求拆解与整体思路1.1 为什么是turtle而不是pygame很多人一看到“画龙”这两个字第一反应是用pygame或者matplotlib。其实都不太合适。pygame能力很强但它是做游戏和交互的画一张静态吉祥物你要处理窗口事件、surface对象、图像加载这属于杀鸡用牛刀matplotlib擅长数据可视化画出来是图表思维颜色和线条控制起来也别扭。turtle的定位恰好是“用脚本控制一支笔”你让它抬笔、落笔、换颜色、画圆、写文字它就在画布上一笔一笔给你画。它不需要第三方库Python安装好就能用这在教学和分享场景里是极大的优势。另外turtle还有一个隐性好处你能亲眼看到绘制过程。龙身先出现然后是龙头、眼睛、鳞片一层层叠上去这种“从无到有”的过程本身就是视觉反馈。写代码最怕没有反馈turtle把每一行代码的效果直接摆在屏幕上对初学者来说这种即时成就感比任何IDE的“语法高亮”都管用。1.2 中国龙的视觉结构拆解一条龙能不能被一眼认出来取决于四个核心细节。第一是龙身必须有起伏流线不能是一根直棍常见做法是带波峰的折线或曲线越自然越有神。第二是鳞片龙身上整齐错开的半圆或小椭圆负责质感和层次感没有鳞片的龙看起来更像蛇。第三是龙头眼睛、须、角是记忆点画好这三样辨识度立刻上来。第四是背景氛围深色底、红日、祥云、文字把画面从“图形”变成“吉祥物”。这些细节不是一次性画完的而是分层次叠加的。我见过很多初学者一上来就盯着龙头的胡须调坐标结果龙身还没画画面重心已经偏了。正确思路是先保证大结构成立再慢慢加小元素最后用背景把整体气氛撑起来。1.3 绘图顺序从背景到细节我的固定顺序是先铺背景底色再画龙身主体然后补头尾细节最后加鳞片和装饰。背景色定了后面所有颜色才能跟着协调主体轮廓先落地头尾的位置才有参考小小的鳞片和大面积的装饰最后放不容易破坏整体构图。这就跟装修先刷墙再摆家具一个道理。turtle画布默认是白色白色背景下红色龙的视觉效果会弱很多所以我第一件事就是把画布改成深色。深色背景还有一个好处金色描边会被衬得很亮整体画风立刻向“国潮海报”靠拢。2. 核心代码模块解析初始化、函数与龙身龙鳞2.1 初始化海龟和两个核心公共函数turtle默认状态是落笔、初始方向朝右、坐标原点在屏幕中心。如果每个部件都从头写penup/goto/pendown代码会又乱又容易漏。我习惯把最基础的两件事封装成公共函数import turtle t turtle.Turtle() t.screen.setup(900, 600) # 窗口宽900、高600 t.screen.bgcolor(#1B1B3A) # 深蓝背景衬托红金色 t.speed(8) t.hideturtle() def move(x, y): t.penup() t.goto(x, y) t.pendown() def polygon(points, fill, outline): t.pencolor(outline) t.fillcolor(fill) t.begin_fill() for x, y in points: t.goto(x, y) t.goto(points[0]) t.end_fill()move函数负责抬笔移动避免海龟在画布上拖出一条长线polygon函数接受一个坐标点列表画一个闭合多边形并填充颜色。这两件事是整个项目的基石后面画龙身、龙头、龙尾全都要用到。注意turtle内部有两条颜色通道pencolor是线条颜色fillcolor是填充颜色很多人一开始搞混画出来发现描边颜色跟填充完全对不上。2.2 龙身轮廓数学曲线和坐标点两条路线龙身是整条龙视觉占比最大的部分画法有两条路线。第一条是数学曲线路线用for循环遍历x坐标用正弦函数算出对应的y坐标import math # 沿着x坐标用正弦函数算y步长越小曲线越顺 for x in range(-300, 301, 6): y 80 * math.sin(x * 0.015) t.goto(x, y)这条路线的好处是曲线连续平滑改一个振幅参数就能调整身体起伏坏处是调起来不直观你盯着公式想象半天不如肉眼直接看效果。第二条路线是手工坐标点列表直接把几个关键转折点写到数组里例如[(-320, 20), (-230, 75), (-130, 95), ...]然后用polygon函数连线填充。这条路线的优势是“所见即所得”哪个点高了、低了改数字就能看到效果适合手工调造型。我的建议是新手先用坐标点列表把大形打出来再看情况用曲线函数替换其中某一段。纯坐标列表虽然一开始画出来歪歪扭扭但它能让你充分理解“每个点都决定形状”这件事这个手感比任何理论都重要。2.3 鳞片、龙角和其他装饰的绘制逻辑鳞片是龙身能不能“立起来”的关键。实现逻辑不复杂就是循环画半圆def scales(points, size7): for x, y in points: t.penup() t.goto(x, y) t.setheading(90) t.pendown() t.pencolor(#F1C40F) t.fillcolor(#F39C12) t.begin_fill() t.circle(size, 180) t.end_fill()size通常控制在6到9之间小于6鳞片远看像麻点大于9鳞片会把身体轮廓整个盖住层次就糊了。每一行鳞片要错开半格像屋顶的瓦片一样整齐中又带一点节奏。半圆的凸起方向由setheading控制想换方向就把90改成270试一次这种“改一个数看一次效果”的调试方式就是turtle最核心的玩法。龙角和龙须也是同样思路不需要专门的库。龙角用两三条短折线模拟分叉龙须用t.circle(半径, 角度)截一段弧线视觉上比直线柔和很多。这些全是基础图形的组合你只要记住一个原则复杂造型一定是由若干个简单图形叠加出来的。2.4 代码注释怎么写才不算白写很多初学者写turtle代码从头到尾只有变量名和数字过一天自己都看不懂。注释不是把代码翻译成中文而是回答三个问题这段在做什么、为什么这么做、改动哪里会受影响。举个例子下面这条注释就比“#画龙身”有用得多# 身体坐标点x从左到右y控制起伏 # 改第3个点之前先看会不会和后面的脸重叠 body [(-320, 20), (-230, 75), (-130, 95), (-40, 65), ...] # size控制在6~9小于6鳞片看不清大于9会盖住身体轮廓 def scales(points, size7):好的注释是在给“未来的自己”留线索。尤其是那种“踩过坑才知道”的参数坑一定要写在对应代码旁边否则三个月后你回来看只会问自己“这个7到底是什么意思”。3. 从空画布到成品完整实操演示3.1 运行前要检查的3个点在跑代码之前先确认三件事。第一Python环境正常命令行输入python --version能输出版本号turtle不需要额外安装但如果你用的是某些精简版或嵌入式Python环境可能缺失tkinter模块提示No module named turtle这种情况建议安装官方完整版PythonLinux用户还需要关注python3-tk这个系统包。第二代码文件名不要起成turtle.py以前有人把脚本保存成turtle.py结果import进来的变成自己各种诡异报错。第三代码末尾一定要有t.screen.mainloop()否则程序跑完窗口直接关闭你只能看到屏幕闪一下。3.2 简化版源码一次跑通的骨架下面这段代码可以直接复制保存成dragon.py运行。它没有做到像素级精修但足以让你看清整条龙的绘制顺序也方便你在这个基础上改坐标、改颜色。import turtle # ---------- 初始化 ---------- t turtle.Turtle() t.screen.setup(900, 600) t.screen.bgcolor(#1B1B3A) t.speed(8) t.hideturtle() def move(x, y): t.penup() t.goto(x, y) t.pendown() def polygon(points, fill, outline): t.pencolor(outline) t.fillcolor(fill) t.begin_fill() for x, y in points: t.goto(x, y) t.goto(points[0]) t.end_fill() # ---------- 龙身 ---------- body [(-320, 20), (-230, 75), (-130, 95), (-40, 65), (60, 105), (160, 125), (260, 75), (330, 15), (280, -25), (180, -10), (80, 15), (-30, -10), (-140, -35), (-240, -45), (-310, -15)] polygon(body, #C8102E, #F1C40F) # ---------- 龙尾 ---------- tail [(330, 15), (390, -10), (360, -45), (410, -55), (340, -60)] polygon(tail, #C8102E, #F1C40F) # ---------- 龙头 ---------- face [(-85, 85), (-25, 130), (55, 105), (75, 15), (0, -15), (-70, 25)] polygon(face, #C8102E, #F1C40F) # 眼睛左 move(-20, 75) t.color(white) t.begin_fill() t.circle(12) t.end_fill() move(-12, 75) t.color(black) t.begin_fill() t.circle(5) t.end_fill() # 眼睛右 move(45, 75) t.color(white) t.begin_fill() t.circle(12) t.end_fill() move(53, 75) t.color(black) t.begin_fill() t.circle(5) t.end_fill() # ---------- 龙角 ---------- move(-55, 105) t.setheading(160) t.pencolor(#F1C40F) t.pensize(4) t.forward(35) t.right(30) t.forward(20) t.penup() move(-55, 105) t.setheading(140) t.pendown() t.forward(28) t.penup() move(45, 120) t.setheading(20) t.pendown() t.forward(35) t.left(30) t.forward(20) t.penup() # ---------- 龙鳞 ---------- def scales(points, size7): for x, y in points: t.penup() t.goto(x, y) t.setheading(90) t.pendown() t.pencolor(#F1C40F) t.fillcolor(#F39C12) t.begin_fill() t.circle(size, 180) t.end_fill() scales([(-270, 40), (-190, 62), (-110, 72), (-10, 50), (85, 62), (180, 62)]) scales([(-210, 10), (-120, 30), (-30, 15), (60, 28)]) scales([(-150, -25), (-60, -20), (20, -8)]) # ---------- 红日和文字 ---------- move(280, 180) t.color(#E74C3C) t.begin_fill() t.circle(50) t.end_fill() move(-80, -160) t.color(white) t.write(龙年大吉, aligncenter, font(楷体, 36, bold)) t.screen.mainloop()跑起来以后你会看到深蓝画布上先出现金边红身然后龙头、眼睛、角依次出现最后鳞片一格一格地铺上去像在贴瓷砖。这条龙不算精致但骨架结构已经完整接下来就是纯调参阶段了。3.3 用配色和层次把“骨架龙”变“节日龙”第一次跑通后别急着分享先改三个地方感受参数变化。把背景色从#1B1B3A换成#5D1A1A整条龙会立刻变成“国潮红”画风把scales(points, size7)里的size改成9鳞片瞬间变大视觉冲击力强很多把文字从“龙年大吉”改成你自己想写的话就成了定制贺卡。我整理了一份常用配色表直接照着用就行用途颜色值使用场景建议背景#1B1B3A深蓝夜空突出红金色龙身主体#C8102E正红色节日主视觉描边#F1C40F金色线条提亮整体鳞片#F39C12橙金色与描边区分红日#E74C3C圆形装饰增加年味文字#FFFFFF白色字体不抢主体如果你想加祥云可以用几个大小不一的半圆拼出来想加灯笼红色圆加黄色短线就能解决。记住一个原则主色控制在三种以内点缀色最多再加两种颜色一多必乱。4. 高频问题排查实录窗口、坐标和颜色4.1 画到一半窗口闪退或卡住初学者最常遇到的坑是代码明明没有报错图形一闪就没了。原因多半是程序跑完Python进程退出画布跟着关了。解法是在代码最后加t.mainloop()或者t.screen.exitonclick()前者保持窗口打开后者点击窗口时退出。还有一种情况是窗口一直卡着不动通常是因为代码里死循环了比如for循环步长写成0或者坐标列表里有重复点导致海龟在两点之间反复横跳。遇到卡顿直接关掉窗口看控制台报错Python会把错误位置和原因打在屏幕上照着提示找那一行就行。4.2 线断了、坐标对不上、叠圈位置不对图形歪七扭八、部件之间对不上几乎都是坐标问题。turtle的坐标原点默认在窗口中心x向右为正、y向上为正。写坐标前先在脑子里把画布分成大致的网格龙头在哪个区间龙身从哪个点绕回来龙尾朝哪个方向翘。所有部件都用move()抬笔移动不用move的话海龟会从上一个位置直接画线过来出现莫名其妙的“拉丝”现象。坐标问题有个很有效的排查方法把对应部件的points列表打印出来或者临时把填充颜色设成半透明看每个多边形实际落在什么位置再逐一修正。4.3 颜色脏、层次乱根本原因是这三点龙为什么看着廉价多数是颜色太多、明度相近的红橙混在一起缺少对比。我的习惯是整幅画只保留三种主色深色背景、一种主体色、一种描边色点缀色最多再加两种。红配金配深蓝就是经典搭配比十几种颜色“炫彩”效果干净得多。第二个原因是描边颜色和填充颜色太接近龙身红配红边轮廓就糊了一定要让描边明显比填充亮或比填充暗。第三个原因是元素堆叠乱鳞片、祥云、文字互相遮挡。处理办法是画完一层再画下一层大面积的元素永远先画小元素后画保证后画的不会被大面积色块盖住。5. 这套代码还能怎么玩扩展方向与个人经验5.1 让龙动起来turtle虽然不擅长复杂游戏但做简单动画完全够用。你可以把龙身坐标整体存成一个列表绑定键盘事件按方向键修改一个基准偏移量然后调用t.clear()清除画布用新坐标重新绘制。核心思路是不要在事件回调里写一长串绘制逻辑而是先更新数据再统一重绘。这个“数据与绘制分离”的思想等你以后写pygame或者其他图形程序时会反复用到。5.2 拿来当节日贺卡或教学案例把write函数里的文字改一改背景换成浅色系再画两个灯笼就是一张可分享的节日贺卡。教学场景更好玩把这份源码的注释删掉把坐标点顺序打乱让学生自己恢复图形原貌。这个任务同时练到了坐标理解、列表操作、函数封装和代码注释四件事比单独做选择题有意思得多。每次分享这套代码我都会让人先跑起来。跑通之后改三个参数感受一下背景色换中国红鳞片size调到9龙身整体上移40像素。光是这三个改动画风就会完全不同。画一条龙从来不是目的真正有用的是你开始调第一个参数时养成的“拆解问题、定位参数、验证效果”的习惯。这个习惯才是这条龙送你的礼物。本文还有配套的精品资源点击获取