Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /var/www/blog.zhujinhui.net/wp-includes/functions.php on line 6114

Notice: 函数 _load_textdomain_just_in_time 的调用方法不正确twentyseventeen 域的翻译加载触发过早。这通常表示插件或主题中的某些代码运行过早。翻译应在 init 操作或之后加载。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.7.0 版本添加的。) in /var/www/blog.zhujinhui.net/wp-includes/functions.php on line 6114
turtle,一个让Python编程变得快乐的库 – 煅魂-JeffreyChu的修炼屋

turtle,一个让Python编程变得快乐的库

今天是六一儿童节,为了回归童心,所以今天学习下Python的turtle库,写几个小游戏玩玩。

简介

Python的turtle库源自Logo编程语言,用于绘制图形和制作简单动画。它通过控制“海龟”在屏幕上移动绘制图像而得名。

turtle绘图

turtle库广泛用于编程教学,可以帮助零基础的初学者理解编程概念和逻辑结构。它通过可视化反馈,增强学习体验,并用于绘制图形、创建简单游戏和模拟物理现象。

安装与设置

因为turtle库是Python标准库的一部分,所以大多数情况下只需要确保安装了Python,然后就可以直接使用turtle库了。

基础用法

要使用Turtle库绘图,首先需要创建一个Turtle图形窗口Screen

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
screen.title("Turtle图形窗口示例")  # 设置窗口标题
# 进入主循环,保持窗口打开
screen.mainloop()

创建Turtle对象后,可以开始绘图。以下是画一条线和一个圆的示例:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 画一条线
t.forward(100)  # 向前移动100像素
# 画一个圆
t.circle(50)  # 画一个半径为50像素的圆
# 进入主循环,保持窗口打开
screen.mainloop()

要创建一个Turtle对象并进行移动:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 向前移动150像素
t.forward(150)
# 向后移动50像素
t.backward(50)
# 进入主循环,保持窗口打开
screen.mainloop()

可以控制Turtle对象的方向和速度:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 向前移动100像素
t.forward(100)
# 向右转90度
t.right(90)
# 向前移动100像素
t.forward(100)
# 设置Turtle的移动速度(1到10,1最慢,10最快)
t.speed(5)
# 进入主循环,保持窗口打开
screen.mainloop()

可以改变Turtle对象的颜色和形状,使其更加有趣:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 改变Turtle的形状('turtle', 'arrow', 'circle', 'square', 'triangle', 'classic'等)
t.shape('turtle')
# 改变Turtle的颜色
t.color('blue')
# 改变Turtle的填充颜色
t.fillcolor('red')
# 向前移动100像素
t.forward(100)
# 画一个圆
t.circle(50)
# 进入主循环,保持窗口打开
screen.mainloop()

进阶用法

图形绘制

使用循环可以绘制出复杂且对称的图形,例如螺旋图案或对称的多边形。以下示例展示了如何使用循环绘制一个螺旋图形:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 设置Turtle的速度
t.speed(10)

# 使用循环绘制螺旋图形
for i in range(50):
    t.forward(i * 10)
    t.right(144)

# 进入主循环,保持窗口打开
screen.mainloop()

使用Turtle库可以很容易地绘制多边形和星形。以下是绘制五边形和五角星的示例:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 设置Turtle的速度
t.speed(5)

# 绘制五边形
for _ in range(5):
    t.forward(100)
    t.right(72)

# 移动Turtle到新位置绘制星形
t.penup()
t.goto(-200, 0)
t.pendown()

# 绘制五角星
for _ in range(5):
    t.forward(200)
    t.right(144)

# 进入主循环,保持窗口打开
screen.mainloop()

填充与颜色

使用begin_fill()end_fill()进行图形填充
turtle库允许使用begin_fill()end_fill()方法进行图形填充,比如填充一个矩形:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 设置填充颜色
t.fillcolor("yellow")
# 开始填充
t.begin_fill()

# 绘制矩形
for _ in range(4):
    t.forward(100)
    t.right(90)

# 结束填充
t.end_fill()
# 进入主循环,保持窗口打开
screen.mainloop()

虽然turtle库不直接支持渐变效果,但可以通过逐步改变颜色实现渐变效果:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
# 创建一个Turtle对象
t = turtle.Turtle()
# 设置初始颜色
r = 0
g = 0
b = 0
# 设置Turtle的速度
t.speed(10)

# 使用循环绘制渐变色螺旋图形
for i in range(50):
    t.pencolor(r/255, g/255, b/255)
    t.forward(i * 10)
    t.right(144)
    r = (r + 20) % 256
    g = (g + 25) % 256
    b = (b + 30) % 256


# 进入主循环,保持窗口打开
screen.mainloop()
五角星渐变色

文本和字体

turtle库提供了在绘图窗口中添加文本的方法。

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()

# 创建一个Turtle对象
t = turtle.Turtle()

# 在窗口中写入文本
t.penup()
t.goto(0, 0)
t.pendown()
t.write("Hello, Turtle!", align="center", font=("Arial", 24, "normal"))

# 进入主循环,保持窗口打开
screen.mainloop()

可以通过指定字体名称、大小和样式来自定义文本的外观:

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()

# 创建一个Turtle对象
t = turtle.Turtle()

# 在窗口中写入文本,设置字体样式和大小
t.penup()
t.goto(0, 0)
t.pendown()
t.write("Custom Font!", align="center", font=("Times New Roman", 30, "bold"))

# 进入主循环,保持窗口打开
screen.mainloop()

更复杂应用

以上的使用场景都是没有加上键盘绑定事件的(即键盘按下某些按键后会触发一些变化事件),所以加了键盘绑定后会更加复杂。

以开发一个小时候都玩过的《井字棋》为例, 源码地址:

https://gitee.com/jeffrey2021/children-day20240601/blob/master/jingziqi.py

以下是部分源码展示(不全)

import turtle

# 创建一个屏幕对象
screen = turtle.Screen()
screen.title("井字棋游戏")
screen.setup(width=600, height=600)
screen.setworldcoordinates(-300, -300, 300, 300)
# 初始化游戏状态
board = [["" for _ in range(3)] for _ in range(3)]
current_player = "X"  # "X" starts the game
positions = {
    "1": (-200, 200), "2": (0, 200), "3": (200, 200),
    "4": (-200, 0), "5": (0, 0), "6": (200, 0),
    "7": (-200, -200), "8": (0, -200), "9": (200, -200)
}

# 画井字棋盘
def draw_board():
    board_drawer = turtle.Turtle()
    board_drawer.speed(0)
    board_drawer.hideturtle()
    for i in range(1, 3):
        board_drawer.penup()
        board_drawer.goto(-300, 200 * i - 300)
        board_drawer.pendown()
        board_drawer.goto(300, 200 * i - 300)
        board_drawer.penup()
        board_drawer.goto(200 * i - 300, -300)
        board_drawer.pendown()
        board_drawer.goto(200 * i - 300, 300)
    board_drawer.penup()

draw_board()

# 定义绘制X和O的函数
def draw_x(x, y):
    pen = turtle.Turtle()
    pen.pencolor("blue")
    pen.penup()
    pen.goto(x - 50, y - 50)
    pen.pendown()
    pen.setheading(45)
    pen.forward(141)
    pen.penup()
    pen.goto(x + 50, y - 50)
    pen.pendown()
    pen.setheading(135)
    pen.forward(141)
    pen.hideturtle()


def draw_o(x, y):
    pen = turtle.Turtle()
    pen.pencolor("red")
    pen.penup()
    pen.goto(x, y - 50)
    pen.pendown()
    pen.circle(50)
    pen.hideturtle()

# 检查胜利条件
def check_winner():
    pass

# 定义放置棋子的函数
def place_mark(key):
    global current_player

    if key not in positions:
        return

    x, y = positions[key]
    row = int((y + 300) // 200)
    col = int((x + 300) // 200)

    if board[row][col] == "":
        if current_player == "X":
            draw_x(x, y)
            board[row][col] = "X"
            current_player = "O"
        else:
            draw_o(x, y)
            board[row][col] = "O"
            current_player = "X"

        winner = check_winner()
        if winner:
            screen.title(f"井字棋游戏 - {winner} 赢了!")
            screen.ontimer(reset_game, 2000)
        elif all(all(cell != "" for cell in row) for row in board):
            screen.title("井字棋游戏 - 平局!")
            screen.ontimer(reset_game, 2000)

# 重置游戏
def reset_game():
    pass

def bind_key():
    # 键盘事件绑定
    for key in positions.keys():
        screen.onkey(lambda k=key: place_mark(k), key)

bind_key()
# 让屏幕开始监听键盘事件
screen.listen()
# 进入主循环,保持窗口打开
screen.mainloop()
井字棋

Turtle调试与优化

常见问题与解决方法

  • 图形显示异常:可能是因为坐标计算错误或绘制逻辑有误,检查坐标计算和绘制逻辑,确保每个图形元素的位置和大小正确。同时,使用try-except结构捕获异常,输出调试信息以排查错误。
  • Turtle响应慢的问题,可能是由于绘制过程中的重复计算或不必要的绘制操作。尽量减少不必要的绘制操作。使用合适的数据结构来缓存和重复利用计算结果。

性能优化

  • tracer()函数: 用于控制Turtle绘制过程的速度,可通过设置参数来调节绘制速度和刷新频率。
  • update()函数: 用于手动刷新Turtle窗口,可在绘制完成后调用以一次性刷新窗口,提高绘制效率。

控制绘制速度

  • 时间控制: 使用time模块来控制绘制速度,例如使用time.sleep()函数来在绘制过程中添加延迟,调节绘制速度。
  • 循环控制: 在绘制循环中适当添加条件判断,控制绘制过程的速度和流畅度,避免过快或过慢的绘制效果。

总结

Python的turtle库使用还是相对比较简单,很适合新手用来练习,主要是写完之后有结果出来,能刺激学习欲望。
除了开发《井字棋》以外,turtle库还可以开发其他经典游戏,比如《1024》、《贪吃蛇》、《坦克大战》等,都可以尝试用来练练手。

参考文献

  • Python官方文档:https://docs.python.org/zh-cn/3/library/turtle.html#turtle.onkeypress

最后,祝大家六一儿童节快乐,玩游戏快乐!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注