Pygame平台游戏玩家静止消失问题求助(疑与vitesse_x/vitesse_y相关)
解决平台类游戏中玩家静止后消失的问题
我仔细看了你的代码,发现玩家静止后消失的问题主要出在碰撞处理时没有重置垂直速度,加上松开方向键时错误地重置了垂直速度这两个点上,下面一步步给你分析和修复:
问题根源解析
- 碰撞后未重置垂直速度:当玩家落在平台上时,你的代码只调整了玩家的位置
self.rect.bottom = bloc.rect.top,但没有把vitesse_y重置为0。这意味着每帧vitesse_y都会持续累加(主循环里else: perso.vitesse_y +=1),时间一长,这个速度会变得非常大,哪怕碰撞时调整了位置,下一帧玩家的rect.y加上超大的vitesse_y会直接穿过平台,掉出屏幕导致消失。 - 方向键松开时错误重置垂直速度:在
KEYUP事件处理中,你松开左右键时同时把vitesse_y设为0,这会干扰正常的下落逻辑,比如玩家站在平台上时,这个操作会让vitesse_y暂时为0,但之后又开始累加,同样会导致速度异常积累。
修复后的完整代码
import pygame from pygame.locals import * pygame.init() fenetre = pygame.display.set_mode((1024,768)) pygame.display.set_caption("Portal Escape") class Perso(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = pygame.Surface((50,50)) self.rect = self.image.get_rect(bottomleft=(0,740)) self.image.fill((255, 0, 0)) self.doit_monter = False self.vitesse_x = 0 self.vitesse_y = 0 def update(self): self.rect.x += self.vitesse_x self.rect.y += self.vitesse_y touche = pygame.key.get_pressed() if touche[pygame.K_RIGHT] and self.rect.x < 920: self.vitesse_x += 1 if touche[pygame.K_LEFT] and self.rect.x > 0: self.vitesse_x -= 1 collision = pygame.sprite.spritecollide(self, blocs, False) for bloc in collision: if self.vitesse_y >= 0: self.rect.bottom = bloc.rect.top self.vitesse_y = 0 # 碰撞后重置垂直速度,防止速度累加 elif self.vitesse_y < 0: self.rect.top = bloc.rect.bottom self.vitesse_y = 0 # 碰到平台顶部也重置速度 perso = Perso() class Bloc(pygame.sprite.Sprite): #pour creer un obstacle et éléments du jeu def __init__(self, x, y, w, h): super().__init__() self.image = pygame.Surface((w,h)) self.image.fill((0, 255, 0)) self.rect = self.image.get_rect(topleft=(x, y)) all_sprites = pygame.sprite.Group() blocs = pygame.sprite.Group() all_sprites.add(perso) b1 = Bloc(200,500,250,50) b2 = Bloc(500,600,200,50) b3 = Bloc(0,740,1024,30) blocs.add(b1,b2,b3) all_sprites.add(b1,b2,b3) new_y = 0 continuer = True clock = pygame.time.Clock() # 把Clock实例移到循环外,避免每次创建新实例 while continuer: clock.tick(60) for event in pygame.event.get(): if event.type == QUIT: continuer = False if event.type == KEYDOWN: if event.key == pygame.K_SPACE: perso.doit_monter = True new_y = perso.rect.y - 100 if event.type == KEYUP: if event.key == pygame.K_LEFT and perso.vitesse_x < 0: perso.vitesse_x = 0 # 移除错误的vitesse_y重置 if event.key == pygame.K_RIGHT and perso.vitesse_x > 0: perso.vitesse_x = 0 # 移除错误的vitesse_y重置 if event.key == pygame.K_SPACE and perso.vitesse_y < 0: perso.vitesse_y = 0 if perso.doit_monter == True: if perso.rect.y > new_y and perso.rect.y > 0: perso.vitesse_y -= 5 else: perso.doit_monter = False else: perso.vitesse_y += 1 all_sprites.update() fenetre.fill((0,0,0)) all_sprites.draw(fenetre) pygame.display.flip() pygame.quit()
关键修改点说明
- 碰撞时重置垂直速度:在
Perso类的update方法中,碰撞处理部分添加了self.vitesse_y = 0,无论是落在平台上还是头顶撞到平台,都把垂直速度清零,这样就不会出现速度持续累加的情况。 - 移除方向键UP时的vitesse_y重置:删除了
KEYUP事件中松开左右键时设置perso.vitesse_y = 0的代码,避免干扰正常的下落和碰撞逻辑。 - 优化Clock实例:把
pygame.time.Clock()移到循环外创建,避免每次循环都生成新的时钟实例,这是一个小的性能优化。
这样修改后,玩家站在平台上静止时,垂直速度会被碰撞逻辑保持为0,不会再出现速度积累导致穿过平台消失的问题了。
内容的提问来源于stack exchange,提问作者kevin0304
相关产品推荐
相关产品推荐

