玩家移动时子弹运动不符合预期的PyGame技术问题
问题搞定!相机偏移是罪魁祸首
我一眼就看出问题所在了——你的鼠标方向计算完全没考虑相机的偏移量!当玩家静止时,相机和屏幕中心对齐,所以用屏幕中心算角度没问题;但玩家斜向移动后,相机跟着偏移,此时屏幕上的鼠标位置对应的游戏世界坐标已经变了,你还拿屏幕中心来算角度,子弹不歪才怪呢!
具体修复步骤
1. 修正鼠标世界坐标的计算
在Player类的player_turning方法里,你需要把屏幕上的鼠标位置转换成游戏世界坐标(加上相机的偏移量),再和玩家的实际位置计算角度:
原来的错误代码:
self.x_change_mouse_player = (self.mouse_coords[0] - (WIDTH // 2)) self.y_change_mouse_player = (self.mouse_coords[1] - (HEIGHT // 2))
替换成:
# 把屏幕鼠标坐标转成游戏世界里的真实位置 mouse_world_pos = pygame.math.Vector2(self.mouse_coords) + camera.offset # 计算玩家和鼠标在世界中的位置差 self.x_change_mouse_player = mouse_world_pos.x - self.base_player_rect.centerx self.y_change_mouse_player = mouse_world_pos.y - self.base_player_rect.centery
2. 修复事件处理的作用域问题
另外,你在player_input方法里直接用了event变量,但这个变量只在主循环的事件遍历里存在,运行时会报错!得把空格键抬起的处理移到主循环里:
在主循环的事件处理块里添加:
if event.type == pygame.KEYUP: if event.key == pygame.K_SPACE: player.shoot = False
然后删掉player_input里的这段错误代码:
if event.type == pygame.KEYUP: if event.key == pygame.K_SPACE: self.shoot = False
修改后的关键代码片段
Player类的player_turning方法
def player_turning(self): self.mouse_coords = pygame.mouse.get_pos() # 核心修正:转换鼠标坐标到游戏世界 mouse_world_pos = pygame.math.Vector2(self.mouse_coords) + camera.offset self.x_change_mouse_player = mouse_world_pos.x - self.base_player_rect.centerx self.y_change_mouse_player = mouse_world_pos.y - self.base_player_rect.centery self.angle = int(math.degrees(math.atan2(self.y_change_mouse_player, self.x_change_mouse_player))) self.angle = (self.angle) % 360 self.image = pygame.transform.rotate(self.base_player_image, -self.angle) self.rect = self.image.get_rect(center=self.base_player_rect.center)
Player类的player_input方法(移除错误的event处理)
def player_input(self): self.velocity_x = 0 self.velocity_y = 0 keys = pygame.key.get_pressed() if keys[pygame.K_w]: self.velocity_y = -self.player_speed if keys[pygame.K_s]: self.velocity_y = self.player_speed if keys[pygame.K_d]: self.velocity_x = self.player_speed if keys[pygame.K_a]: self.velocity_x = -self.player_speed if self.velocity_x != 0 and self.velocity_y != 0: # 斜向移动时减速,保持速度一致 self.velocity_x /= math.sqrt(2) self.velocity_y /= math.sqrt(2) if keys[pygame.K_SPACE]: self.shoot = True self.is_shooting() else: self.shoot = False
主循环的事件处理
while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # 移到这里处理空格键抬起事件,避免作用域错误 if event.type == pygame.KEYUP: if event.key == pygame.K_SPACE: player.shoot = False
原理说明
- 相机的
offset是玩家位置与屏幕中心的差值,所以屏幕鼠标位置加上offset,就能得到鼠标在游戏世界中的真实坐标。 - 用世界坐标计算玩家和鼠标的角度,不管玩家怎么移动、相机怎么偏移,角度都是准确的,子弹自然就会精准指向鼠标位置。
- 把事件处理移到主循环,解决了变量作用域的问题,避免运行时崩溃。
内容的提问来源于stack exchange,提问作者juba1029
相关产品推荐
相关产品推荐

