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()搞个循环动画就行——让云朵一直往左飞(飞机向前的反方向),飞出屏幕左边后,直接把它挪到屏幕右边随机位置重生:
- 先拿到云朵的实际宽度(之前你用空的
PhotoImage取宽高是错的,得从cloud_image里拿) - 写个云朵移动的函数,用
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
相关产品推荐
相关产品推荐

