You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter飞机游戏:实现云朵自动循环移动与重生

解决方案

一、先修按键绑定的坑

你现在重复绑定了<d>键,最后只有move_fwd能生效,得改一下绑定逻辑,比如w对应上斜飞、s对应下斜飞、d对应向前飞:

window.bind("<w>", move_up_diagonally)
window.bind("<s>", move_down_diagonally)
window.bind("<d>", move_fwd)

二、云朵自动反向移动+循环重生

云朵移动别绑飞机按键,用tkinter的after()搞个循环动画就行——让云朵一直往左飞(飞机向前的反方向),飞出屏幕左边后,直接把它挪到屏幕右边随机位置重生:

  1. 先拿到云朵的实际宽度(之前你用空的PhotoImage取宽高是错的,得从cloud_image里拿)
  2. 写个云朵移动的函数,用after()反复调用它

三、飞机上下飞的旋转实现

tkinter自带的PhotoImage不能旋转,得装个pillow库(终端输pip install pillow),用它加载图片并生成不同旋转角度的版本,移动飞机时切换对应的图片就行。


改好的完整代码

from tkinter import *
import random
from PIL import Image, ImageTk

WIDTH = 1280
HEIGHT = 720
window = Tk()
window.title("飞机躲云朵")

canvas = Canvas(window, width=WIDTH, height=HEIGHT)
canvas.pack()

# 加载背景图
background_image = PhotoImage(file='sky_background.png')
canvas.create_image(0, 0, image=background_image, anchor=NW)

# 处理飞机旋转:用PIL生成不同角度的图片
original_plane = Image.open('plane.png')
plane_up = ImageTk.PhotoImage(original_plane.rotate(-15))  # 向上飞转-15度
plane_fwd = ImageTk.PhotoImage(original_plane)             # 向前飞不转
plane_down = ImageTk.PhotoImage(original_plane.rotate(15)) # 向下飞转15度
plane = canvas.create_image(0, 165, image=plane_fwd, anchor=NW)

# 加载云朵并获取宽度
cloud_image = PhotoImage(file='cloud.png')
cloud_width = cloud_image.width()
# 生成一个云朵,初始位置在屏幕右侧外的随机点
cloud = canvas.create_image(random.randint(WIDTH, WIDTH + 300), 
                            random.randint(50, HEIGHT - 100), 
                            image=cloud_image, anchor=NW)

def switch_plane_img(img):
    canvas.itemconfig(plane, image=img)
    # 必须存个引用,不然图片会被Python回收消失
    window.current_plane_img = img

def move_fwd(event):
    switch_plane_img(plane_fwd)
    canvas.move(plane, 3, 0)
    
def move_up_diagonally(event):
    switch_plane_img(plane_up)
    # 防止飞机飞出屏幕上方
    plane_y = canvas.coords(plane)[1]
    if plane_y > 20:
        canvas.move(plane, 1.7, -3)
    
def move_down_diagonally(event):
    switch_plane_img(plane_down)
    # 防止飞机飞出屏幕下方
    plane_y = canvas.coords(plane)[1]
    if plane_y < HEIGHT - 80:
        canvas.move(plane, 1.7, 3)

# 修正后的按键绑定
window.bind("<w>", move_up_diagonally)
window.bind("<s>", move_down_diagonally)
window.bind("<d>", move_fwd)

def update_clouds():
    # 云朵向左移动
    canvas.move(cloud, -2, 0)
    # 获取云朵当前的x坐标
    cloud_x = canvas.coords(cloud)[0]
    # 完全飞出左侧屏幕就重置到右侧
    if cloud_x < -cloud_width:
        canvas.coords(cloud, 
                      random.randint(WIDTH, WIDTH + 500), 
                      random.randint(50, HEIGHT - 100))
    # 每隔20毫秒调用一次,形成动画
    window.after(20, update_clouds)

# 启动云朵移动循环
update_clouds()

window.mainloop()

重点说明

  • 云朵动画:用after()循环代替time.sleep(),不会卡界面
  • 飞机旋转:提前生成旋转后的图片,切换时更新canvas上的飞机图片,注意要存引用防止图片消失
  • 边界限制:加了飞机的屏幕边界判断,不会飞出画面
  • 按键修复:每个按键对应唯一的移动函数,不会互相覆盖

内容的提问来源于stack exchange,提问作者lavish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:24:29