如何实现所有Sprite持续移动,避免新Sprite生成时旧Sprite停止?
问题描述
我原本计划实现圆形Sprite按固定间隔生成,并以指定速度向鼠标位置移动,目前生成功能已正常运行,但每当新Sprite生成时,之前的Sprite便会停止移动,仿佛不再被更新。我希望所有Sprite能够同时向鼠标位置移动,而非仅新Sprite移动。我是开发新手,若您发现代码中的其他问题也请不吝指出。
相关代码
# Enemy class Enemy (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.x = 0 self.y = 0 self.speed = 2 self.change_x = 0 self.change_y = 0 self.update() def update(self): dx, dy = (pygame.mouse.get_pos()[0]+8) - self.x, (pygame.mouse.get_pos()[1]+8) - self.y dist = math.hypot(dx, dy) dx, dy = dx / dist, dy / dist self.change_x += dx * self.speed self.change_y += dy * self.speed def make_enemies(): enemy = Enemy() enemy.change_x = random.randrange(0, 800) enemy.change_y = random.randrange(0, 600) enemy.speed = 2 return enemy enemy_list = [] spawn = make_enemies() enemy_list.append(spawn) add_enemy = pygame.USEREVENT + 1 pygame.time.set_timer(add_enemy, 1000) # Game loop done = False while not done: # RGB - RED, GREEN, BLUE (0-255) screen.fill(BACKGROUND) for event in pygame.event.get(): if event.type == pygame.QUIT: done = True if event.type == add_enemy: spawn = make_enemies() enemy_list.append(spawn) for enemy in enemy_list: enemy.x = enemy.change_x enemy.y = enemy.change_y pygame.draw.circle (screen, WHITE, [enemy.change_x, enemy.change_y], BALL_SIZE) enemy.update() clock.tick(100) pygame.display.update()
问题修复与优化建议
核心问题:仅更新单个敌人
游戏循环里的enemy.update()只调用了最后一个生成的敌人的更新方法,之前的敌人完全没被处理。必须遍历所有敌人逐个调用update:
# 替换原循环里的enemy.update() for enemy in enemy_list: enemy.update()
变量逻辑错误修正
初始位置赋值错误
make_enemies里把初始位置赋值给了change_x/change_y,但Enemy类中x/y才是记录当前位置的变量,应该修正为:def make_enemies(): enemy = Enemy() enemy.x = random.randrange(0, 800) enemy.y = random.randrange(0, 600) enemy.speed = 2 return enemy移动逻辑错误
原update方法里累加change_x/change_y会导致速度越来越快,且没有正确更新x/y位置。应该让change_x/change_y作为每帧的位移量,直接更新位置:def update(self): dx, dy = (pygame.mouse.get_pos()[0]+8) - self.x, (pygame.mouse.get_pos()[1]+8) - self.y dist = math.hypot(dx, dy) # 避免敌人与鼠标重合时除以0的错误 if dist != 0: dx, dy = dx / dist, dy / dist self.change_x = dx * self.speed self.change_y = dy * self.speed else: self.change_x = 0 self.change_y = 0 # 更新当前位置 self.x += self.change_x self.y += self.change_y绘制位置错误
绘制时应该使用x/y作为位置,而非change_x/change_y,同时要转成整数(pygame绘制坐标需要整数):for enemy in enemy_list: pygame.draw.circle(screen, WHITE, [int(enemy.x), int(enemy.y)], BALL_SIZE)原代码里把
x/y赋值为change_x/change_y的逻辑完全颠倒,也是移动异常的关键原因。
其他细节优化
- Enemy类继承自
pygame.sprite.Sprite,但缺少必需的image和rect属性,后续如果用精灵组做碰撞检测会出错,建议补上:def __init__(self): pygame.sprite.Sprite.__init__(self) self.x = 0 self.y = 0 self.speed = 2 self.change_x = 0 self.change_y = 0 # 添加Sprite必需的属性 self.image = pygame.Surface((BALL_SIZE*2, BALL_SIZE*2), pygame.SRCALPHA) pygame.draw.circle(self.image, WHITE, (BALL_SIZE, BALL_SIZE), BALL_SIZE) self.rect = self.image.get_rect() - 确保代码开头导入了必要模块:
import pygame、import math、import random,并且完成pygame初始化(pygame.init())、屏幕设置、颜色和常量定义,否则代码无法运行。
内容的提问来源于stack exchange,提问作者Nichamp
相关产品推荐
相关产品推荐

