综合项目
运用所学知识
现在我们已经学习了海龟绘图的各种技巧,让我们通过一些综合项目来练习所学知识!
项目一:海底世界
让我们创建一个美丽的海底世界:
import turtle
# 设置背景
turtle.bgcolor("darkblue")
screen = turtle.Screen()
# 创建海龟
t = turtle.Turtle()
t.speed(5)
# 画海底
t.penup()
t.goto(-300, -200)
t.pendown()
t.fillcolor("brown")
t.pencolor("brown")
t.begin_fill()
t.goto(300, -200)
t.goto(300, -100)
t.goto(-300, -100)
t.goto(-300, -200)
t.end_fill()
# 画海草
def draw_seaweed(x, y, height):
t.penup()
t.goto(x, y)
t.pendown()
t.fillcolor("green")
t.pencolor("green")
t.begin_fill()
t.setheading(90)
t.forward(height)
t.right(45)
t.forward(20)
t.right(90)
t.forward(20)
t.right(45)
t.forward(height)
t.end_fill()
# 画多根海草
draw_seaweed(-200, -100, 80)
draw_seaweed(-100, -100, 120)
draw_seaweed(0, -100, 100)
draw_seaweed(100, -100, 90)
draw_seaweed(200, -100, 110)
# 画鱼(彻底修正眼睛位置:严格贴合鱼身圆形)
def draw_fish(x, y, size, color):
# x,y 是鱼身体(圆形)的中心坐标,size是鱼身半径
t.penup()
t.goto(x, y)
t.pendown()
# 1. 画鱼身体(圆形,鱼身朝右,尾巴在左)
t.fillcolor(color)
t.pencolor(color)
t.begin_fill()
t.circle(size) # 以(x,y)为中心画圆形身体
t.end_fill()
# 2. 画鱼尾(精准衔接鱼身左侧,分叉形鱼尾)
t.penup()
t.goto(x - size, y + size * 0.2) # 鱼尾根部上沿
t.pendown()
t.begin_fill()
t.setheading(150) # 朝左上方
t.forward(size * 1.5) # 左上鱼尾边
t.goto(x - size, y) # 回到鱼尾根部中点
t.setheading(210) # 朝左下方
t.forward(size * 1.5) # 左下鱼尾边
t.goto(x - size, y - size * 0.2) # 鱼尾根部下沿
t.setheading(150) # 回朝上左
t.forward(size * 1.5) # 闭合鱼尾
t.end_fill()
# 3. 画鱼嘴(小弧线,鱼头部右侧)
t.penup()
t.goto(x + size, y) # 鱼头部最右侧
t.pendown()
t.pencolor("black")
t.setheading(20) # 朝上偏右
t.circle(size * 0.3, 40) # 小弧线鱼嘴
t.pencolor(color) # 恢复鱼身颜色
# 4. 画眼睛(核心修正:严格落在鱼身右上方,不超出边界)
# 眼睛中心坐标:鱼身中心(x,y) 向右偏移 size*0.5,向上偏移 size*0.4
# 这个比例确保眼睛完全在鱼身圆形内,且位置自然
eye_x = x + size * 0.5
eye_y = y + size * 0.4
# 画眼白(大小随鱼身自适应,完全在鱼身上)
t.penup()
t.goto(eye_x, eye_y)
t.pendown()
t.fillcolor("white")
t.begin_fill()
t.circle(size / 10) # 眼白半径=鱼身半径的1/10,不会超出
t.end_fill()
# 画眼珠(在眼白中心,更聚焦)
t.penup()
t.goto(eye_x + size/20, eye_y + size/20)
t.pendown()
t.fillcolor("black")
t.begin_fill()
t.circle(size / 20) # 眼珠半径=鱼身半径的1/20
t.end_fill()
# 画多条鱼(测试不同尺寸,眼睛都能精准落在鱼身上)
draw_fish(-150, 50, 30, "orange")
draw_fish(50, 80, 25, "yellow")
draw_fish(100, 20, 35, "red")
# 画气泡
def draw_bubble(x, y, size):
t.penup()
t.goto(x, y)
t.pendown()
t.fillcolor("white")
t.pencolor("white")
t.begin_fill()
t.circle(size)
t.end_fill()
# 画多个气泡
draw_bubble(-100, 150, 10)
draw_bubble(-80, 180, 5)
draw_bubble(150, 120, 8)
draw_bubble(170, 150, 12)
# 写标题
t.penup()
t.goto(0, 250)
t.pendown()
t.pencolor("white")
t.write("海底世界", font=("Arial", 24, "bold"), align="center")
# 隐藏海龟
t.hideturtle()
# 保持窗口显示
turtle.done()
项目二:四季树
让我们画一棵展示四季变化的树:
import turtle
# 创建屏幕和海龟
screen = turtle.Screen()
t = turtle.Turtle()
t.speed(5)
# 定义当前季节,用于循环切换
current_season = 0 # 0:春天, 1:夏天, 2:秋天, 3:冬天
# 画树干
def draw_trunk():
t.penup()
t.goto(0, -100)
t.pendown()
t.fillcolor("brown")
t.pencolor("brown")
t.begin_fill()
t.setheading(90)
t.forward(100)
t.right(90)
t.forward(20)
t.right(90)
t.forward(100)
t.end_fill()
# 画树叶
def draw_leaves(color):
t.penup()
t.goto(-50, 0)
t.pendown()
t.fillcolor(color)
t.pencolor(color)
t.begin_fill()
t.circle(60)
t.end_fill()
# 春天树
def draw_spring():
t.reset()
t.speed(5) # 重置后恢复速度
screen.bgcolor("lightblue")
draw_trunk()
draw_leaves("lightgreen")
t.penup()
t.goto(0, 150)
t.pendown()
t.write("春天", font=("Arial", 20, "bold"), align="center")
# 夏天树
def draw_summer():
t.reset()
t.speed(5)
screen.bgcolor("skyblue")
draw_trunk()
draw_leaves("green")
t.penup()
t.goto(0, 150)
t.pendown()
t.write("夏天", font=("Arial", 20, "bold"), align="center")
# 秋天树
def draw_autumn():
t.reset()
t.speed(5)
screen.bgcolor("lightyellow")
draw_trunk()
draw_leaves("orange")
t.penup()
t.goto(0, 150)
t.pendown()
t.write("秋天", font=("Arial", 20, "bold"), align="center")
# 冬天树
def draw_winter():
t.reset()
t.speed(5)
screen.bgcolor("lightgray")
draw_trunk()
# 冬天没有树叶
t.penup()
t.goto(0, 150)
t.pendown()
t.write("冬天", font=("Arial", 20, "bold"), align="center")
# 画雪
for i in range(50):
if current_season == 3:
x = -200 + i * 8
y = 50 + (i % 5) * 20
t.penup()
t.goto(x, y)
t.pendown()
t.fillcolor("white")
t.begin_fill()
t.circle(3)
t.end_fill()
# 点击屏幕切换季节的核心函数
def switch_season(x, y):
global current_season
# 根据当前季节切换到下一个
current_season = (current_season + 1) % 4
if current_season == 0:
draw_spring()
elif current_season == 1:
draw_summer()
elif current_season == 2:
draw_autumn()
elif current_season == 3:
draw_winter()
# 初始化显示春天
draw_spring()
# 设置点击事件:点击屏幕任意位置触发季节切换
screen.onscreenclick(switch_season)
# 保持窗口显示
turtle.done()
项目三:太空冒险
让我们创建一个太空冒险场景:
import turtle
import random
# 设置背景
turtle.bgcolor("black")
screen = turtle.Screen()
# 创建海龟
t = turtle.Turtle()
t.speed(0) # 最快速度
# 画星星
def draw_star(x, y, size, color):
t.penup()
t.goto(x, y)
t.pendown()
t.fillcolor(color)
t.pencolor(color)
t.begin_fill()
# 画五角星
for i in range(5):
t.forward(size)
t.right(144)
t.end_fill()
# 画多个星星
for i in range(30):
x = random.randint(-300, 300)
y = random.randint(50, 300)
size = random.randint(5, 20)
color = random.choice(["white", "yellow", "lightblue"])
draw_star(x, y, size, color)
# 画地球
t.penup()
t.goto(0, -50)
t.pendown()
t.fillcolor("blue")
t.pencolor("blue")
t.begin_fill()
t.circle(50)
t.end_fill()
# 画地球上的陆地
t.penup()
t.goto(-30, -30)
t.pendown()
t.fillcolor("green")
t.pencolor("green")
t.begin_fill()
t.circle(20)
t.end_fill()
# 画火箭(彻底修正顶部:用坐标定位绘制三角形顶部)
def draw_rocket(x, y):
# x,y 是火箭底部左侧的起点坐标
t.penup()
t.goto(x, y)
t.pendown()
# 1. 绘制火箭主体(红色矩形)
t.fillcolor("red")
t.pencolor("red")
t.begin_fill()
# 从(x,y)开始,按顺时针画矩形
t.setheading(90) # 朝上
t.forward(60) # 向上到(x, y+60) → 顶部左侧
t.right(90) # 朝右
t.forward(20) # 向右到(x+20, y+60) → 顶部右侧
t.right(90) # 朝下
t.forward(60) # 向下到(x+20, y) → 底部右侧
t.right(90) # 朝左
t.forward(20) # 向左回到(x,y) → 底部左侧
t.end_fill()
# 2. 绘制火箭顶部(白色三角形,精准覆盖主体顶端)
t.fillcolor("white")
t.pencolor("white")
t.begin_fill()
# 手动定位三角形的三个顶点,确保和主体匹配
t.penup()
t.goto(x, y+60) # 第一个点:火箭主体顶部左侧
t.pendown()
t.goto(x+10, y+75) # 第二个点:火箭顶部顶点(中间向上延伸)
t.goto(x+20, y+60) # 第三个点:火箭主体顶部右侧
t.goto(x, y+60) # 回到第一个点,闭合三角形
t.end_fill()
# 3. 绘制火箭窗口
t.penup()
t.goto(x + 10, y + 30) # 窗口在火箭中心位置
t.pendown()
t.fillcolor("lightblue")
t.pencolor("lightblue")
t.begin_fill()
t.circle(8)
t.end_fill()
# 画火箭
draw_rocket(-150, -100)
# 画卫星(太阳能板以中心对称)
def draw_satellite(x, y):
t.penup()
t.goto(x, y)
t.pendown()
# 卫星主体(圆形)
t.fillcolor("gray")
t.pencolor("gray")
t.begin_fill()
t.circle(15)
t.end_fill()
# 太阳能板(以卫星中心为对称轴)
# 左侧板
t.penup()
t.goto(x, y)
t.setheading(180)
t.forward(15)
t.pendown()
t.forward(40)
# 右侧板
t.penup()
t.goto(x, y)
t.setheading(0)
t.forward(15)
t.pendown()
t.forward(40)
# 上侧板
t.penup()
t.goto(x, y)
t.setheading(90)
t.forward(15)
t.pendown()
t.forward(30)
# 下侧板
t.penup()
t.goto(x, y)
t.setheading(270)
t.forward(15)
t.pendown()
t.forward(30)
# 画卫星
draw_satellite(150, 50)
# 写标题
t.penup()
t.goto(0, 200)
t.pendown()
t.pencolor("white")
t.write("太空冒险", font=("Arial", 24, "bold"), align="center")
# 隐藏海龟
t.hideturtle()
# 保持窗口显示
turtle.done()
项目四:互动游戏
让我们创建一个简单的互动游戏:海龟接球游戏
import turtle
import random # 用于生成随机角度
# 设置屏幕
screen = turtle.Screen()
screen.bgcolor("lightblue")
screen.title("海龟接球游戏")
screen.tracer(0) # 关闭自动刷新,提升动画流畅度
# 创建玩家海龟
player = turtle.Turtle()
player.shape("turtle")
player.color("green")
player.penup()
player.goto(0, -200)
# 创建球
ball = turtle.Turtle()
ball.shape("circle")
ball.color("red")
ball.penup()
ball.goto(0, 200)
# 分数
score = 0
score_turtle = turtle.Turtle()
score_turtle.hideturtle()
score_turtle.penup()
score_turtle.goto(-200, 250)
score_turtle.write("分数: 0", font=("Arial", 16, "normal"))
# 游戏状态标志
game_over = False
ball_returning = False # 标记球是否正在返回上方
return_angle = 0 # 球返回时的水平偏移角度
# 游戏结束提示海龟
game_over_turtle = turtle.Turtle()
game_over_turtle.hideturtle()
game_over_turtle.penup()
game_over_turtle.goto(0, 0)
# 重新开始提示海龟
restart_turtle = turtle.Turtle()
restart_turtle.hideturtle()
restart_turtle.penup()
restart_turtle.goto(0, -50)
# 游戏说明
instructions = turtle.Turtle()
instructions.hideturtle()
instructions.penup()
instructions.goto(0, -250)
instructions.write("使用左右方向键移动海龟接球", font=("Arial", 12, "normal"), align="center")
# 移动玩家
def move_left():
if not game_over: # 游戏未结束时才能移动
x = player.xcor()
if x > -280: # 限制左边界,防止移出屏幕
player.setx(x - 20)
def move_right():
if not game_over: # 游戏未结束时才能移动
x = player.xcor()
if x < 280: # 限制右边界,防止移出屏幕
player.setx(x + 20)
# 重置游戏(重新开始)
def reset_game():
global score, game_over, ball_returning
# 重置游戏状态
game_over = False
ball_returning = False
score = 0
# 清空游戏结束提示
game_over_turtle.clear()
restart_turtle.clear()
# 显示玩家和球
player.showturtle()
ball.showturtle()
# 重置位置
player.goto(0, -200)
ball.goto(0, 200)
# 重置分数显示
score_turtle.clear()
score_turtle.write("分数: 0", font=("Arial", 16, "normal"))
# 球返回上方的逻辑(带角度缓慢移动)
def move_ball_up():
global ball_returning, return_angle
# 球的当前位置
x, y = ball.pos()
# 还没到目标高度,继续移动
if y < 195: # 目标高度(略低于200,避免重复触发)
# 按角度向上+水平移动
ball.setx(x + return_angle)
ball.sety(y + 5) # 上升速度
else:
# 到达目标高度,停止返回
ball_returning = False
# 游戏循环
def game_loop():
global score, game_over, ball_returning, return_angle
if not game_over:
# 如果球正在返回上方,执行返回逻辑
if ball_returning:
move_ball_up()
else:
# 球正常下落
y = ball.ycor()
ball.sety(y - 5)
# 检查是否接到球
if ball.distance(player) < 30:
score += 1
score_turtle.clear()
score_turtle.write(f"分数: {score}", font=("Arial", 16, "normal"))
# 触发球返回逻辑:生成随机角度(-3到3之间,控制水平偏移)
ball_returning = True
return_angle = random.uniform(-3, 3) # 随机左右偏移角度
# 检查球是否落地(游戏结束条件)
if ball.ycor() < -220:
game_over = True
# 隐藏玩家和球
player.hideturtle()
ball.hideturtle()
# 显示游戏结束提示
game_over_turtle.write("Game Over", font=("Arial", 30, "bold"), align="center")
# 显示重新开始提示
restart_turtle.write("按空格键重新开始", font=("Arial", 16, "normal"), align="center")
screen.update() # 手动刷新屏幕
# 继续游戏循环(50ms执行一次)
screen.ontimer(game_loop, 50)
# 键盘控制
screen.listen()
screen.onkey(move_left, "Left")
screen.onkey(move_right, "Right")
screen.onkey(reset_game, "space") # 按空格键重新开始
# 开始游戏
reset_game() # 初始化游戏
game_loop()
# 保持窗口显示
turtle.done()
练习
- 创建你自己的海底世界,添加更多海洋生物
- 创建一个城市场景,有建筑物、汽车和树木
- 创建一个简单的迷宫游戏
- 创建你自己的互动项目
小提示
- 使用函数来组织代码,使它更易读
- 使用注释来解释复杂部分
- 尝试添加用户交互,如键盘控制或鼠标点击
- 使用颜色和形状使你的项目更加生动
思考题
如果你想创建一个多关卡的游戏,应该如何组织代码呢?
恭喜你完成了所有教程!继续探索和创造更多有趣的海龟图形吧!🐢
Python 工具/在线模拟器/Python海龟绘图可视化
Python海龟绘图可视化 - https://www.cnbbx.com/python-editor/