如何修复Pygame(Python)中窗口左上角闪烁的方块问题?
问题解决:下落方块卡在左上角闪烁
问题根源
你的代码存在两个关键错误,直接导致方块异常卡顿:
- 障碍物销毁条件错误:
Obstacle类的update方法中,判断方块是否超出屏幕的逻辑用了SCREEN_WIDTH(宽度),但方块是垂直下落,应该判断是否超出屏幕底部的SCREEN_HEIGHT(高度)。这个错误让本该被销毁的方块一直留在精灵组中,后续位置计算出现异常,表现为卡在左上角闪烁。 - 初始化位置语义错误:虽然当前
OBSTACLE_WIDTH和OBSTACLE_HEIGHT数值相同,但初始化self.y时用-OBSTACLE_HEIGHT更贴合垂直方向的逻辑,避免后续修改尺寸时出现隐性问题。
修正后的完整代码
import pygame, sys import random # Initialize Pygame pygame.init() # 屏幕尺寸设置 SCREEN_WIDTH = 1920 SCREEN_HEIGHT = 1080 FPS = 60 # 创建游戏窗口 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('Dodge') # 时钟初始化 clock = pygame.time.Clock() class Player(pygame.sprite.Sprite): def __init__(self): super(Player, self).__init__() self.surf = pygame.image.load('graphics\\player.png') self.rect = self.surf.get_rect() self.x = SCREEN_WIDTH / 2 self.y = SCREEN_HEIGHT / 10 * 9 self.rect.center = (self.x, self.y) self.max_speed = 15 self.velX = 0 self.velY = 0 self.acceleration = 0.7 self.friction = 0.9 def update(self): keys = pygame.key.get_pressed() if keys[pygame.K_a]: if self.velX > -self.max_speed: self.velX -= self.acceleration if keys[pygame.K_d]: if self.velX < self.max_speed: self.velX += self.acceleration if keys[pygame.K_w]: if self.velY > -self.max_speed: self.velY -= self.acceleration if keys[pygame.K_s]: if self.velY < self.max_speed: self.velY += self.acceleration self.x += self.velX self.y += self.velY self.velX *= self.friction self.velY *= self.friction self.rect.center = (self.x, self.y) if self.rect.left < 0: self.rect.left = 0 if self.rect.right > SCREEN_WIDTH: self.rect.right = SCREEN_WIDTH if self.rect.top <= 0: self.rect.top = 0 if self.rect.bottom >= SCREEN_HEIGHT: self.rect.bottom = SCREEN_HEIGHT class Obstacle(pygame.sprite.Sprite): def __init__(self): super(Obstacle, self).__init__() OBSTACLE_WIDTH = 64 OBSTACLE_HEIGHT = 64 self.surf = pygame.Surface((OBSTACLE_WIDTH, OBSTACLE_HEIGHT)) self.surf.fill('white') self.rect = self.surf.get_rect() self.x = random.randint(5, SCREEN_WIDTH - OBSTACLE_WIDTH - 5) self.y = -OBSTACLE_HEIGHT # 修正垂直方向初始化语义 self.velY = random.randint(15, 20) def update(self): self.y += self.velY self.rect.topleft = (self.x, self.y) # 修正销毁条件:判断是否超出屏幕底部 if self.rect.top > SCREEN_HEIGHT + 5: self.kill() ADD_OBSTACLE = pygame.USEREVENT + 1 pygame.time.set_timer(ADD_OBSTACLE, 250) # 玩家实例 player = Player() # 障碍物精灵组 obstacles = pygame.sprite.Group() # 游戏主循环 run = True while run: # 事件处理 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: run = False elif event.type == ADD_OBSTACLE: new_obstacle = Obstacle() obstacles.add(new_obstacle) # 清空屏幕 screen.fill((0, 0, 0)) # 绘制玩家和障碍物 screen.blit(player.surf, player.rect) for obs in obstacles: screen.blit(obs.surf, obs.rect) # 碰撞检测 if pygame.sprite.spritecollideany(player, obstacles): player.kill() run = False # 更新角色状态 player.update() obstacles.update() # 更新显示 pygame.display.flip() clock.tick(FPS) # 退出游戏 pygame.quit() sys.exit()
额外优化建议
- 将
OBSTACLE_WIDTH和OBSTACLE_HEIGHT设为全局常量,方便后续统一调整尺寸。 - 玩家移动逻辑可以直接操作
rect属性,无需单独维护x、y变量,减少坐标同步出错的可能。
内容的提问来源于stack exchange,提问作者rukenup
相关产品推荐
相关产品推荐

