请求为Pygame基础平台游戏实现平滑跳跃功能
给你的Pygame基础平台游戏添加平滑跳跃
嘿,我懂你现在的处境——刚接触面向对象编程,不想搞复杂的类结构,就想给现有的简单平台游戏加个自然的平滑跳跃对吧?咱们直接在你现有代码的基础上改,不用加多余的类,只需要调整几个变量和逻辑就行。
问题分析
你现在的代码里只有pjump这个布尔变量,但平滑跳跃需要模拟真实的物理效果:跳跃时给玩家一个向上的初始速度,然后重力逐渐拉着玩家减速上升,直到速度变为0后开始加速下落。另外还要限制只能在地面上跳跃,不然玩家会一直跳个不停。
修改步骤
我会给你一步步说明要改的地方,然后附上完整的修改后代码:
添加必要的全局变量
y_velocity:记录玩家Y轴方向的速度(用来叠加重力和跳跃力)jump_force:跳跃时的向上力度(数值越大跳得越高)on_ground:标记玩家是否在地面上(防止连跳)
调整跳跃触发逻辑
在userInput里,只有当玩家在地面上时,按下跳跃键才触发跳跃。重构玩家移动逻辑
把原来直接给pcoors[1]加重力的方式,改成用y_velocity来计算:- 跳跃时给
y_velocity一个负的jump_force(因为Pygame的Y轴向下为正) - 每次循环给
y_velocity加上重力,模拟加速度 - 把
y_velocity加到玩家的Y坐标上
- 跳跃时给
更新碰撞检测逻辑
当玩家碰到地面时,重置y_velocity为0,设置on_ground为True,避免玩家穿地或者一直被重力拉扯。
完整修改后代码
import pygame import sys pygame.init() clock = pygame.time.Clock() # 窗口设置 ww = 760 wh = 520 wc = (135, 206, 250) w = pygame.display.set_mode((ww, wh)) tile_size = 40 # 玩家图片加载 player_img = pygame.image.load('player.png') player_img = pygame.transform.scale(player_img, (40, 40)) # 移动相关全局变量 pcoors = [400, 300] pleft = False pright = False pspeed = 2 gravity = 0.5 # 调小一点让重力更柔和,你可以自己调整 jump_force = -12 # 负数值代表向上(Y轴向下为正) y_velocity = 0 # Y轴速度,用来处理重力和跳跃 on_ground = False # 判断是否在地面,防止连跳 def userInput(): global pleft, pright, on_ground for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 按键按下事件 if event.type == pygame.KEYDOWN: if event.key == pygame.K_a: pleft = True if event.key == pygame.K_d: pright = True # 只有在地面上才能跳跃 if event.key == pygame.K_SPACE and on_ground: global y_velocity y_velocity = jump_force # 给跳跃的初始速度 on_ground = False # 离开地面,禁止连跳 # 按键松开事件 if event.type == pygame.KEYUP: if event.key == pygame.K_a: pleft = False if event.key == pygame.K_d: pright = False def player_movement(): global pcoors, y_velocity, gravity # 左右移动 if pleft: pcoors[0] -= pspeed if pright: pcoors[0] += pspeed # Y轴移动:应用速度,然后叠加重力 y_velocity += gravity pcoors[1] += y_velocity def col_detection(): global pcoors, y_velocity, on_ground # 底部碰撞检测:玩家碰到窗口底部 if pcoors[1] + 40 >= wh: pcoors[1] = wh - 40 # 把玩家放在地面上 y_velocity = 0 # 重置Y速度,防止继续下落 on_ground = True # 标记为在地面,允许再次跳跃 # 可选:顶部碰撞检测,防止玩家跳出窗口顶部 if pcoors[1] <= 0: pcoors[1] = 0 y_velocity = 0 def img_blit(): w.blit(player_img, (pcoors)) while True: w.fill(wc) userInput() player_movement() col_detection() img_blit() clock.tick(60) # 改成60帧更合理,360帧太快没必要 pygame.display.update()
关键改动说明
- 把
gravity调小到0.5,让下落和跳跃的手感更平滑(你可以根据自己的喜好调整数值) jump_force设为-12,这个数值决定跳跃高度,负数是因为Pygame的Y轴原点在左上角,向下为正,所以向上需要负的速度- 用
y_velocity来统一处理重力和跳跃的速度叠加,这样跳跃会有自然的减速上升、加速下落的效果 on_ground变量确保玩家只有在落地后才能再次跳跃,避免连跳Bug
你可以自己调整gravity和jump_force的数值,找到最舒服的跳跃手感。如果之后要加平台(不是只有窗口底部),只需要在col_detection里添加对应平台的碰撞判断就行,逻辑是一样的。
内容的提问来源于stack exchange,提问作者FatTony




