Python turtle 实现小球碰撞控制与自定义形状绘制
本文详解如何使用 Python 内置的 turtle 模块开发一款基于键盘控制的球类小游戏。通过注册自定义圆形画笔、绑定键盘事件与定时器循环,实现红球的移动控制以及绿蓝小球的随机生成与碰撞交互,掌握 turtle 在简易图形交互程序中的核心应用技巧。
目标与运行效果
利用 turtle 模块不仅可绘制静态图形,还能构建基础交互程序。本示例将制作一个球类小游戏:画布中随机生成绿色与蓝色小球向固定方向运动,红色小球默认向右移动。用户可通过键盘上下左右键改变红球朝向。当红球触碰绿球时体积增大,触碰蓝球时体积缩小;若缩小至临界值则判定游戏结束。

第1步:导入依赖模块与初始化全局变量
目的:建立游戏运行所需的数学运算库与全局状态记录容器。
入口/动作:在脚本头部导入标准库,定义画布尺寸、网格单位及各类小球的初始参数。
import turtle
import random
import math
# 画布尺寸设置
game_wid = 600
game_hei = 400
cell = 20
# 核心状态变量
red_size = cell
red_ball = None
green_balls = []
blue_balls = []
dir = 0 # 当前红球移动方向(0右, 90上, 180左, -90下)
完成状态:所有变量在内存中就绪,后续函数可通过 global 关键字直接读写。
第2步:注册自定义圆形画笔与绘制游戏边界
目的:突破 turtle 默认海龟形状限制,为角色定制圆形外观,并围出活动区域。
入口/动作:调用 turtle.begin_poly() 记录轨迹起点,绘制指定半径后以 turtle.end_poly() 闭合,最后使用 turtle.register_shape(name, cs) 注册命名形状。随后由主画笔循环绘制灰方块作为墙体。
def custom_shape(name, size):
turtle.begin_poly()
turtle.penup()
turtle.circle(size)
turtle.end_poly()
cs = turtle.get_poly()
turtle.register_shape(name, cs)
def draw_square(color):
if color is not None:
turtle.fillcolor(color)
turtle.begin_fill()
for _ in range(4):
turtle.fd(cell)
turtle.left(90)
if color is not None:
turtle.end_fill()
def draw_blocks():
turtle.hideturtle()
for j in [30, 20, 30, 20]:
for i in range(j):
draw_square('gray')
turtle.fd(cell)
turtle.right(90)
turtle.fd(-cell)
turtle.goto(0, 0)
完成状态:画布左侧出现连续灰块围成的矩形框,'ball' 与 'red' 形状已存入 turtle 渲染缓存。
第3步:绑定键盘响应与坐标碰撞计算
目的:实现玩家输入到方向变量的映射,并提供基于坐标的碰撞判定框架。
入口/动作:使用 turtle.onkey(callback, key) 将四个方向键与回调函数绑定,turtle.listen() 激活事件监听。碰撞检测通过 math.fabs() 计算圆心距离差值,与预设碰撞阈值比对。
def dir_right(): global dir; dir = 0
def dir_left(): global dir; dir = 180
def dir_up(): global dir; dir = 90
def dir_down(): global dir; dir = -90
def register_event():
for key, f in {"Up": dir_up, "Down": dir_down, "Left": dir_left, "Right": dir_right}.items():
turtle.onkey(f, key)
turtle.listen()
def is_meet_qt():
global dir
x, y = red_ball.xcor(), red_ball.ycor()
if x < -220: dir = 0
elif x > 240: dir = 180
elif y > 140: dir = -90
elif y < -120: dir = 90
def r_g_b_meet():
global red_size
s_x, s_y = red_ball.pos()
for bs in [green_balls, blue_balls]:
for b in bs:
f_x, f_y = b.pos()
x_, y_ = abs(s_x - f_x), abs(s_y - f_y)
h = cell + red_size
if 0 <= x_ <= h and y_ <= h:
if b in green_balls: red_size += 2
else: red_size -= 2
custom_shape('red', red_size)
return True
return False
完成状态:按下方向键屏幕光标聚焦成功,红球触底或碰壁时方向自动修正,碰撞后红球半径变量与形状同步更新。
第4步:构建游戏主循环与启动程序
目的:通过定时器递归驱动画面刷新,整合角色生成、移动与判定逻辑。
入口/动作:定义 ball_move() 函数执行单帧逻辑,调用 turtle.ontimer(ball_move, 100) 设置 100 毫秒刷新间隔。主入口关闭初始绘制闪烁,按序执行初始化后开启实时渲染。
def ran_gb_ball(balls, color):
if random.randint(1, 5) == 5:
turtle.tracer(False)
ball = init_ball(rand_pos(), color, 'ball')
ball.seth(random.randint(0, 360))
balls.append(ball)
turtle.tracer(True)
def gb_ball_m(balls):
for b in balls:
b.fd(20)
if b.xcor() < -220 or b.xcor() > 240 or b.ycor() > 140 or b.ycor() < -120:
b.goto(rand_pos())
def ball_move():
red_ball.seth(dir)
red_ball.fd(40)
is_meet_qt()
ran_gb_ball(green_balls, 'green')
ran_gb_ball(blue_balls, 'blue')
gb_ball_m(green_balls)
gb_ball_m(blue_balls)
r_g_b_meet()
turtle.ontimer(ball_move, 100)
if __name__ == "__main__":
turtle.tracer(False)
register_event()
for name in ['red', 'ball']:
custom_shape(name, cell)
draw_blocks()
red_ball = init_ball(rand_pos(), 'red', 'red')
turtle.tracer(True)
ball_move()
turtle.done()
完成状态:窗口弹出,小球开始连续平滑运动,交互逻辑进入持续运转态。
关键机制说明与排错参考
turtle.tracer(False/True):用于临时冻结画面刷新,避免批量创建对象或绘制边界时产生卡顿闪烁。turtle.ontimer(func, delay):替代多线程实现游戏主循环的核心 API,delay 单位为毫秒。turtle.register_shape:必须先用begin_poly()和end_poly()勾勒轮廓,否则注册的形状为空或沿用旧路径。
常见运行异常排查:
- 按下方向键无反应:检查是否遗漏
turtle.listen(),或窗口焦点未集中在 turtle 渲染窗口上。 - 画面黑屏/不刷新:确认代码末尾调用了
turtle.done(),该语句会阻塞线程以保持窗口常驻。
总结
以上就是使用 Python turtle 编写简单球类小游戏的详细内容,更多关于 Python turtle 进阶玩法与交互式绘图的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









