如何在Python Pygame开发的游戏中正确实现动态云朵效果
问题诊断与修复方案
错误点梳理
- Cloud类update方法语法错误:
self.rect.x(-5, 0)的写法错误,rect.x是存储x坐标的数值属性,不是可调用方法,要实现云朵向左移动的效果应该改为self.rect.x -= 5 - 云朵生成事件配置错误:
ADDCLOUD自定义事件和定时器的定义被错误放在了Cloud类内部,且主循环的事件监听逻辑没有处理该事件,导致无法定时生成新云朵 - 云朵资源未回收:没有设置云朵移出屏幕左侧后的销毁逻辑,会持续占用内存
- 重复调用update方法:主循环中已经通过
all_sprites.update()执行了所有精灵的更新逻辑,额外单独调用clouds.update()会导致初始云朵每次循环移动两次,速度异常
修复后完整代码
from pygame.locals import * import pygame import os import random WIDTH = 1200 HEIGHT = 700 FPS = 60 usr_y = HEIGHT - 120 usr_x = WIDTH - 1120 BLUE = (0, 255, 255) GREEN = (34, 89, 76) NOTGREEN = (0, 128, 128) WHITE = (255, 255, 255) pygame.init() pygame.mixer.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Mini-games") clock = pygame.time.Clock() icon = pygame.image.load('icon.png') pygame.display.set_icon(icon) player_img = pygame.image.load('Sonic.actionp1.png').convert() pygame.mixer.music.load('Фоновая музыка.mp3') pygame.mixer.music.play(-1) clouds_jpg = pygame.image.load('Clouds.jpg').convert() # 自定义事件移到类外部定义 ADDCLOUD = pygame.USEREVENT + 1 pygame.time.set_timer(ADDCLOUD, 1000) class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = player_img self.image.set_colorkey(NOTGREEN) self.rect = self.image.get_rect() self.rect.centerx = usr_x self.rect.centery = usr_y self.y = self.rect.y def update(self): self.rect.y = round(self.y) self.speedx = 0 keystate = pygame.key.get_pressed() if keystate[pygame.K_LEFT]: self.speedx = -8 if keystate[pygame.K_RIGHT]: self.speedx = 8 self.rect.x += self.speedx if self.rect.right > WIDTH: self.rect.right = WIDTH if self.rect.left < 0: self.rect.left = 0 class Clouds(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = clouds_jpg self.image.set_colorkey(WHITE) self.rect = self.image.get_rect() self.rect.centerx = random.randint(0, WIDTH) self.rect.centery = random.randint(HEIGHT - 550, HEIGHT - 100) # 避免云刷到地面区域 def update(self): self.rect.x -= 5 # 移出屏幕左侧后自动销毁 if self.rect.right < 0: self.kill() all_sprites = pygame.sprite.Group() cloud_group = pygame.sprite.Group() # 单独建云朵组方便后续扩展逻辑 player = Player() all_sprites.add(player) jump = False counter = -20 def make(): global usr_y, counter, jump if counter >= -20: player.y -= counter counter -= 1 else: counter = 20 jump = False running = True while running: clock.tick(FPS) for event in pygame.event.get(): if event.type == KEYDOWN: if event.key == K_ESCAPE: running = False elif event.key == K_SPACE: jump = True elif event.type == pygame.QUIT: running = False # 新增监听生成云朵的事件 elif event.type == ADDCLOUD: new_cloud = Clouds() all_sprites.add(new_cloud) cloud_group.add(new_cloud) if jump: make() all_sprites.update() screen.fill(BLUE) all_sprites.draw(screen) pygame.display.flip() pygame.quit()
内容的提问来源于stack exchange,提问作者Вильдан Латыпов
相关产品推荐
相关产品推荐

