defshoot(self): x = p.x y = p.y self.shooting = True while self.shooting: d.fill((98, 98, 98)) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit()
b = bullet() p = player(600, 500, 50, 30) whileTrue: d.fill((98, 98, 98)) p.draw() for event in pygame.event.get(): pass
if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: b.shoot() if event.key == pygame.K_LEFT: p.move_left() if event.key == pygame.K_RIGHT: p.move_right()
win.update()
Это то, что я смог придумать после нескольких проб и ошибок, но это действительно неэффективно. Во-первых, проигрыватель исчезает, когда я нажимаю пробел. Я думаю, это очевидно, поскольку у меня есть разные циклы для стрельбы и проигрывателя, но я не знаю, как обойти это и реализовать и стрельбу, и проигрыватель в одном цикле.
Вторая проблема, с которой я сталкиваюсь, - это разрыв while self.shooting: цикла. Я попытался прервать его, когда y достигнет определенной точки, выполнив это:
if y <= 0: self.shooting = False
Но это не прерывается. Вместо этого цикл перезапускается заново.
Еще одна странная проблема, с которой я сталкиваюсь, заключается в том, что каждый раз, когда я перемещаю мышь (немного быстро) или нажимаю кучу кнопок одновременно, это прерывает while self.shooting цикл.
Переведено автоматически
Ответ 1
Общий подход к стрельбе пулями заключается в сохранении позиций пуль в списке (bullet_list). Когда пуля выпущена, добавьте начальную позицию пули ([start_x, start_y]) в список. Начальная позиция - это позиция объекта (игрока или врага), который запускает пулю. Используйте for-цикл для перебора всех маркеров в списке. Переместите положение каждого отдельного маркера в цикле. Удалите маркер из списка, который покидает экран (bullet_list.remove(bullet_pos)). По этой причине необходимо выполнить копию списка (bullet_list[:]) (см. Как удалять элементы из списка во время итерации?). Используйте другой for-цикл для blit оставшихся маркеров на экране:
bullet_list = []
while run == True: # [...]
for event in pygame.event.get(): if event.type == pygame.QUIT: run = False
if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: bullet_list.append([start_x, start_y])
for bullet_pos in bullet_list[:]: bullet_pos[0] += move_bullet_x bullet_pos[1] += move_bullet_y ifnot screen.get_rect().colliderect(bullet_image.get_rect(center = bullet_pos)) bullet_list.remove(bullet_pos)
# [...]
for bullet_pos in bullet_list[:] screen.blit(bullet_image, bullet_image.get_rect(center = bullet_pos))
Пожалуйста, обратите внимание, что в именах классов обычно следует использовать соглашение о заглавных словах. (См. Руководство по стилю для имен классов кода Python) Это означает, что это должно быть Player и Bullet, а не player и bullet
You have an application loop, so use it. All the objects are continuously updated and drawn in the main application loop, in each frame.
The class Bullet do not need any loop. The constructor has to have parameters for the position (x, y). Further it needs on method which changes the position and one which draws the bullet:
classBullet: def__init__(self, x, y): self.radius = 10 self.speed = 10 self.x = x self.y = y
Use a list of bullets. Create a new bullet when space is pressed. Move the bullets (update) in every frame an remove a bullet if it is out of the window. Draw the remaining bullets in every frame:
bullets = []
# [...] while run:
for event in pygame.event.get(): # [...] if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: bullets.append(Bullet(p.x+p.width//2, p.y))
# [...] for b in bullets: b.update() if b.y < 0: bullets.remove(b)
# [...] for b in bullets: b.draw()
Furthermore use pygame.key.get_pressed() use to get the state of the keys in every frame and to update the position of the player:
while run:
# [...]
keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: p.move_left() if keys[pygame.K_RIGHT]: p.move_right()
# handel events for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: bullets.append(Bullet(p.x+p.width//2, p.y))
# update objects keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: p.move_left() if keys[pygame.K_RIGHT]: p.move_right() for b in bullets: b.update() if b.y < 0: bullets.remove(b)