当编程与艺术相遇,会碰撞出怎样的火花?本文将带你走进一个充满趣味的编程世界——用Python的turtle模块绘制家喻户晓的皮卡丘。这段代码不仅是编程逻辑的体现,更是一场用代码描绘像素艺术的创意实践。
整个绘制过程始于一个基础的交互设计——getPosition函数,它就像一个隐形的坐标记录仪:
def getPosition(x, y):
turtle.setx(x)
turtle.sety(y)
print(x, y)
这个函数会在鼠标拖动时记录画布上的坐标位置,就像画家在素描前用铅笔标记关键点。而Pikachu类则是整个绘制的核心,它的初始化方法完成了画笔的"整装待发":
class Pikachu:
def __init__(self):
self.t = turtle.Turtle()
t = self.t
t.pensize(3) # 画笔粗细设为3
t.speed(9) # 绘制速度设为9
t.ondrag(getPosition) # 绑定鼠标拖动事件
这里设置了画笔粗细、绘制速度,并将鼠标拖动与坐标记录功能绑定,为后续精确绘制埋下伏笔。noTrace_goto方法则实现了"提笔移动"的效果,就像画家提起画笔调整位置时不留下痕迹:
def noTrace_goto(self, x, y):
self.t.penup() # 提起画笔
self.t.goto(x, y) # 移动到指定坐标
self.t.pendown() # 放下画笔开始绘制
皮卡丘的眼睛采用三层结构:深灰色眼眶、黑色瞳孔与白色高光,代码通过三次画圆实现层次感:
def leftEye(self, x, y):
self.noTrace_goto(x, y)
t = self.t
t.seth(0) # 朝向正东
t.fillcolor('#333333') # 深灰色
t.begin_fill()
t.circle(22) # 画22像素的圆作为眼眶
t.end_fill()
self.noTrace_goto(x, y + 10)
t.fillcolor('#000000') # 黑色
t.begin_fill()
t.circle(10) # 10像素的瞳孔
t.end_fill()
self.noTrace_goto(x + 6, y + 22)
t.fillcolor('#ffffff') # 白色
t.begin_fill()
t.circle(10) # 10像素的高光
t.end_fill()
左右眼的绘制逻辑相似,但坐标略有不同(如右眼的高光位置在x-6处),这种镜像处理让双眼保持对称。
皮卡丘的嘴巴是绘制中最复杂的部分,代码通过参数化曲线勾勒出微笑轮廓:
def mouth(self, x, y):
self.noTrace_goto(x, y)
t = self.t
t.fillcolor('#88141D') # 暗红色嘴唇
t.begin_fill()
# 下嘴唇:通过循环绘制参数化曲线
l1 = []
t.seth(190)
a = 0.7
for i in range(28):
a += 0.1
t.right(3)
t.fd(a)
l1.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.noTrace_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()
这里的关键是通过循环for i in range(28)逐步调整画笔角度和步长,形成自然的曲线,就像画家一笔一划勾勒嘴唇的弧度。
皮卡丘标志性的红色脸颊采用了更复杂的参数化绘制:
def leftCheek(self, x, y):
turtle.tracer(False) # 关闭动画刷新
t = self.t
self.noTrace_goto(x, y)
t.seth(300)
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) # 恢复动画刷新
技巧提示: turtle.tracer(False)用于关闭绘制过程的动画显示,可以显著提升绘制效率,特别是在绘制复杂图形时。
皮卡丘的身体绘制是一个长达数百行的连贯过程,代码通过"提笔-移动-落笔"的方式勾勒轮廓:
def body(self):
t = self.t
t.fillcolor('#F6D02F') # 亮黄色
t.begin_fill()
# 右脸轮廓
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(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)
# ...(继续绘制手指细节)
这里的核心技巧是通过circle(r, angle)方法绘制圆弧,通过seth(angle)调整画笔方向,实现流畅的曲线连接。身体部分的代码就像画家的速写本,记录着从头部到脚部的每一个转折。
尾巴的绘制分为两部分:黄色主体与黑色花纹,代码通过坐标计算实现精准定位:
# 尾巴主体
self.noTrace_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.fillcolor('#923E24') # 棕红色花纹
self.noTrace_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)
# ...(通过坐标点连接形成闪电形状)
尾巴的花纹部分尤其精妙,通过一系列坐标点和角度调整,勾勒出皮卡丘独特的闪电形尾巴,这是整个绘制的点睛之笔。
皮卡丘的红色帽子通过多层填充实现立体感:
def cap(self, x, y):
self.noTrace_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(50)
# ...(继续绘制帽子轮廓)
# 帽子上的黑色条纹
t.fillcolor('#444444')
t.begin_fill()
t.left(180)
t.circle(80, 197)
t.left(58)
t.circle(200, 45)
t.end_fill()
# 绿色帽徽
self.noTrace_goto(-58, 270)
t.pencolor('#228B22')
t.dot(35)
帽子的绘制包含了红色主体、黑色条纹和绿色帽徽,色彩对比鲜明,细节丰富。
耳朵的绘制采用"先画外轮廓,再填充内耳"的方式:
def colorLeftEar(self, x, y):
t = self.t
self.noTrace_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()
黑色内耳与黄色耳朵主体形成鲜明对比,增强了耳朵的立体感。
整个绘制过程采用面向对象设计,将皮卡丘的各个部位封装为独立方法:
leftEye/rightEye:负责双眼绘制mouth:负责嘴巴与舌头绘制leftCheek/rightCheek:负责脸颊绘制body:负责主体轮廓绘制cap:负责帽子绘制colorLeftEar/colorRightEar:负责耳朵细节这种设计就像画家将一幅画分解为多个局部,逐个完成后再组合成整体。主函数main则像导演,协调各个部分的绘制:
def main():
print('Painting the Pikachu... ')
turtle.screensize(800, 600) # 设置800x600的画布
turtle.title('Pikachu') # 窗口标题
pikachu = Pikachu() # 创建皮卡丘实例
pikachu.start() # 开始绘制
turtle.mainloop() # 进入事件循环
这段代码不仅是皮卡丘的绘制指南,更是编程创意的起点。你可以尝试:
fillcolor的RGB值,创造不同毛色的皮卡丘getPosition功能,实现点击绘制特定元素当你运行这段代码时,看着画笔在屏幕上逐步勾勒出皮卡丘的轮廓,会真切感受到编程与艺术的奇妙融合。这不仅是一段代码,更是一次用逻辑思维创造视觉艺术的旅程——每个circle都是像素级的笔触,每次goto都是创意的移动,最终在屏幕上凝结成那个充满活力的黄色身影。
if __name__ == '__main__':
main()
运行提示: 要运行这段代码,请确保已安装Python和turtle模块。将代码保存为.py文件后直接运行即可看到皮卡丘逐步绘制的神奇过程!