Pygame开发射击功能时子弹无法向上、向左发射问题求助
问题描述
我是Pygame初学者,正尝试制作一个持枪的小人物角色,但子弹无法向上或向左发射,向右、向下的子弹移动逻辑完全正常,始终无法定位问题根源。
原代码
import pygame pygame.init() gameScreen = pygame.display.set_mode() pygame.display.set_caption('solo attempt') clock = pygame.time.Clock() class player(object): def __init__(self, x, y, width, height): self.x = x self.y = y self.width = width self.height = height self.vel = 8 self.facing = 1 def draw(self, gameScreen): pygame.draw.rect(gameScreen, (255, 0, 0), (self.x, self.y, self.width, self.height)) class gun(object): def __init__(self, startx, starty): self.startx = startx self.starty = starty self.endx = self.startx self.endy = self.starty self.up = False self.down = False self.left = False self.right = False def draw(self, gameScreen): pygame.draw.line(gameScreen, (0, 0, 255), (self.startx, self.starty), (self.endx, self.endy)) class bulletThing(object): def __init__(self, x, y, radius): self.x = x self.y = y self.radius = radius self.verticalVel = 12 * vertical self.horizontalVel = 12 * horizontal print(self.verticalVel, self.horizontalVel) def draw(self, gameScreen): pygame.draw.circle(gameScreen, (0, 255, 0), (self.x, self.y), self.radius) #updates screen def drawScreen(gameScreen): gameScreen.fill((0, 0, 0)) player.draw(gameScreen) gun.draw(gameScreen) for bullet in bullets: bullet.draw(gameScreen) pygame.display.update() #create player and gun and bullets list player = player(50, 50, 64, 64) gun = gun(player.x + (player.width / 2), player.y + (player.height / 2)) bullets = [] vertical = 0 horizontal = 1 shootLoop = 0 dimensions = gameScreen.get_size() #main loop running = True while running: clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False #shot delay if shootLoop > 0: shootLoop += 1 if shootLoop > 3: shootLoop = 0 #bullet movement for bullet in bullets: if bullet.x < dimensions[0] and bullet.x > 0: bullet.x += bullet.horizontalVel else: bullets.pop(bullets.index(bullet)) if bullet.y < dimensions[1] and bullet.y > 0: bullet.y += bullet.verticalVel else: bullets.pop(bullets.index(bullet)) keys = pygame.key.get_pressed() #move left if keys[pygame.K_a]: if player.x > 0: player.x -= player.vel if gun.startx > 0 + player.width / 2: gun.startx -= player.vel gun.endx -= player.vel #move right if keys[pygame.K_d]: if player.x < dimensions[0] - player.width: player.x += player.vel if gun.startx < dimensions[0] - player.width / 2: gun.startx += player.vel gun.endx += player.vel #move up if keys[pygame.K_w]: if player.y > 0 + player.height / 2: player.y -= player.vel if gun.starty > 0: gun.starty -= player.vel gun.endy -= player.vel #move down if keys[pygame.K_s]: if player.y < dimensions[1] - player.height: player.y += player.vel if gun.starty < dimensions[1] - player.height / 2: gun.starty += player.vel gun.endy += player.vel #top "gun"'s for visuals #aim up and left if keys[pygame.K_UP] and keys[pygame.K_LEFT]: gun.endy = gun.starty gun.endy -= 64 gun.endx = gun.startx gun.endx -= 64 gun.up = True gun.down = False gun.left = True gun.right = False #aim up and right elif keys[pygame.K_UP] and keys[pygame.K_RIGHT]: gun.endy = gun.starty gun.endy -= 64 gun.endx = gun.startx gun.endx += 64 gun.up = True gun.down = False gun.left = False gun.right = True #aim down and left elif keys[pygame.K_DOWN] and keys[pygame.K_LEFT]: gun.endy = gun.starty gun.endy += 64 gun.endx = gun.startx gun.endx -= 64 gun.up = False gun.down = True gun.left = True gun.right = False # aim down and right elif keys[pygame.K_DOWN] and keys[pygame.K_RIGHT]: gun.endy = gun.starty gun.endy += 64 gun.endx = gun.startx gun.endx += 64 gun.up = False gun.down = True gun.left = False gun.right = True #aim up elif keys[pygame.K_UP]: gun.endx = gun.startx gun.endy = gun.starty gun.endy -= 64 gun.up = True gun.down = False gun.left = False gun.right = False #aim down elif keys[pygame.K_DOWN]: gun.endx = gun.startx gun.endy = gun.starty gun.endy += 64 gun.up = False gun.down = True gun.left = False gun.right = False #aim left elif keys[pygame.K_LEFT]: gun.endy = gun.starty gun.endx = gun.startx gun.endx -= 64 gun.up = False gun.down = False gun.left = True gun.right = False #aim right elif keys[pygame.K_RIGHT]: gun.endy = gun.starty gun.endx = gun.startx gun.endx += 64 gun.up = False gun.down = False gun.left = False gun.right = True #bullet creation if keys[pygame.K_SPACE] and shootLoop == 0: bullets.append(bulletThing(round(player.x + player.width / 2), round(player.y + player.height / 2), 6)) #sets bullet movement to up, down, left, or right if gun.up: vertical = -1 else: vertical = 0 if gun.down: vertical = 1 else: vertical = 0 if gun.left: horizontal = -1 else: horizontal = 0 if gun.right: horizontal = 1 else: horizontal = 0 shootLoop = 1 drawScreen(gameScreen) pygame.quit()
问题原因
代码里有两个核心bug导致子弹无法向左、向上发射:
- 赋值顺序错误:创建
bulletThing实例的代码在设置vertical/horizontal方向值之前,子弹初始化时读取的是上一帧的方向参数,不是当前瞄准的方向。初始全局变量vertical=0、horizontal=1,默认就是向右的状态。 - 方向值被覆盖:四个方向判断都带了
else分支重置数值,比如判断gun.up为真把vertical设为-1后,下一个判断gun.down为假,会直接走else把vertical重置为0,向上的速度直接被清零;向左的horizontal值同理,会被后续判断gun.right的else分支重置为0,所以向左、向上的子弹永远没有对应方向的速度。 - 额外隐患:遍历子弹列表时直接在原列表调用
pop()删除元素,会导致列表索引错位,可能漏判子弹边界。
修复方案
- 调整射击逻辑的顺序:先计算当前瞄准方向的
vertical、horizontal值,再实例化子弹对象。 - 修正方向赋值逻辑:先把
vertical、horizontal初始化为0,再根据对应方向标记赋值,不要用连续的else重置数值,避免参数被覆盖。 - 遍历子弹时遍历列表副本,避免删除元素导致的索引错误。
修复后的核心逻辑代码参考:
#bullet creation if keys[pygame.K_SPACE] and shootLoop == 0: # 先计算方向值 vertical, horizontal = 0, 0 if gun.up: vertical = -1 if gun.down: vertical = 1 if gun.left: horizontal = -1 if gun.right: horizontal = 1 # 方向计算完成后再创建子弹 bullets.append(bulletThing(round(player.x + player.width / 2), round(player.y + player.height / 2), 6)) shootLoop = 1 # 子弹移动逻辑修正,遍历列表副本避免索引错误 for bullet in bullets[:]: bullet.x += bullet.horizontalVel bullet.y += bullet.verticalVel # 超出屏幕边界直接删除 if bullet.x < 0 or bullet.x > dimensions[0] or bullet.y <0 or bullet.y > dimensions[1]: bullets.remove(bullet)
内容的提问来源于stack exchange,提问作者randomperson2114
相关产品推荐
相关产品推荐

