Здравствуйте всем. Пишу игру вроде alien invasion с помощью pygame. Не могу реализировать так чтоб когда игрок нажал и держал кнопку Space нажатым пули стрелялись бесконечно... Пробовал циклами, там все пули разом выпускается как один(проверял с помощью print(len(), пули столько, сколько я установил). Проверял с помощью time.sleep(), так вообще корабль тоже остановился и вообще не получился задумка. Погуглил, но там другие ответы на другие вопросы. Рад буду за помощь
Основной модуль
import pygame
from pygame.sprite import Group
from settings import Settings
# module controlling ship,bullet,alien speed,
# amount of aliens, bullets etc.
import game_functions as gf
# module controlling changes coords of things in screen in every loop
from ship import Ship
# module of class Ship
def run_game():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
ship = Ship(screen, settings) # creating ship
bullets = Group() # creating tuple to store bullets
while True:
screen.fill(settings.bg_color) # changing background color
ship.blitme() # drawing ship onto screen
gf.check_events(ship, settings, screen, bullets) # keyboard events
ship.update() # changing position of ship when player presses definite key
gf.update_screen(bullets) # changing coords of bullet after it's been fired
pygame.display.flip() # loop
run_game() # starts game
game_functions.py
import sys
import time
import pygame
from bullet import Bullet # class of Bullet
def check_keydown_events(event, ship, settings, screen, bullets, fire):
if event.key == pygame.K_LEFT:
# left arrow keydown events
ship.move_left = True # moves ship left when key's keeping pressed
if event.key == pygame.K_RIGHT:
# right arrow keydown events
ship.move_right = True # moves ship right when key's keeping pressed
if event.key == pygame.K_DOWN:
# down arrow keydown events
ship.move_down = True # moves ship down when key's keeping pressed
if event.key == pygame.K_UP:
# up arrow keydown events
ship.move_up = True # moves ship up when key's keeping pressed
if event.key == pygame.K_SPACE:
fire = True
# fires bullets
if fire and len(bullets) < settings.bullets_allowed:
# continues firing until amount of bullets reaches limit
new_bullet = Bullet(settings, ship, screen) # creating new bullet
bullets.add(new_bullet) # adding created bullet to Group
def check_keyup_events(event, ship, fire):
# works with keydown events
if event.key == pygame.K_LEFT:
ship.move_left = False # stops moving of ship to left
if event.key == pygame.K_RIGHT:
ship.move_right = False # stops moving of ship to right
if event.key == pygame.K_UP:
ship.move_up = False # stops moving of ship to up
if event.key == pygame.K_DOWN:
ship.move_down = False # stops moving of ship to down
if event.key == pygame.K_SPACE:
fire = False # stops firing bullets
def check_events(ship, settings, screen, bullets):
"""main event checker function"""
fire = False # it'll be true when player press space
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
# working on keydown events
check_keydown_events(event, ship, settings, screen, bullets, fire)
# function that checks keydown event type and works according event type
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship, fire)
# function that checks keyup event type and works according event type
print(len(bullets)) # to check amount of bullets on screen
def update_screen(bullets):
"""works with bullet Group"""
for bullet in bullets.sprites():
bullet.update_bullet() # changes position of bullet in every loop
bullet.draw_bullet() # draws bullets with new coords
if bullet.rect.bottom < 0:
bullets.remove(bullet) # removes bullets reached outline of screen
settings.py
import pygame
class Settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 700
self.bg_color = (15, 38, 128)
self.ship_speed_factor = 1.5
self.bullet_width = 5
self.bullet_height = 15
self.bullet_color = 245, 15, 15
self.bullets_allowed = 5
self.bullet_speed_factor = 1
bullets.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
def __init__(self, settings, ship, screen):
super(Bullet, self).__init__()
self.settings = settings
self.ship_rect = ship.rect # rect of image of ship
self.screen = screen
self.width = settings.bullet_width
self.height = settings.bullet_height
self.color = settings.bullet_color
self.rect = pygame.Rect(0, 0, self.width, self.height) # left bullet
self.rect1 = pygame.Rect(0, 0, self.width, self.height) # right bullet
# variables below makes bullets being fired from ship wings
self.rect.x = self.ship_rect.centerx - 21
self.rect1.x = self.ship_rect.centerx + 21
self.rect.y = self.ship_rect.centery - 15
self.rect1.y = self.ship_rect.centery - 15
# variables below makes coords much more correct
self.x = float(self.rect.x)
self.y = float(self.rect.y)
self.x1 = float(self.rect1.x)
self.y1 = float(self.rect1.y)
def draw_bullet(self):
# draws bullets when being called
pygame.draw.rect(self.screen, self.color, self.rect)
pygame.draw.rect(self.screen, self.color, self.rect1)
def update_bullet(self):
# changes bullets coords in every loop
# rect can't get float number, so we use variables below and return it's integer type back at the end
self.y -= self.settings.bullet_speed_factor
self.y1 -= self.settings.bullet_speed_factor
self.rect.y = self.y
self.rect1.y = self.y1
ship.py
import pygame
class Ship():
def __init__(self, screen, ai_settings):
self.screen = screen
self.settings = ai_settings
self.image = pygame.image.load("images/ship.xcf") # ship image
self.rect = self.image.get_rect() # ship rect
self.screen_rect = self.screen.get_rect()
self.rect.centerx = self.screen_rect.centerx # moving ship to center
self.rect.centery = self.screen_rect.centery # vertical center aligning
self.centerx = float(self.rect.centerx) # we'll use float to be more correct
self.centery = float(self.rect.centery)
# variables below will be "True" or "False" according keydown events in game_functions.py
self.move_right = False
self.move_left = False
self.move_up = False
self.move_down = False
def update(self):
# changes ship position according keydown events in game_function.py
if self.move_right and self.rect.right < self.screen_rect.right:
self.centerx += self.settings.ship_speed_factor
if self.move_left and self.rect.left > self.screen_rect.left:
self.centerx -= self.settings.ship_speed_factor
if self.move_up and self.rect.top > self.screen_rect.top:
self.centery -= self.settings.ship_speed_factor
if self.move_down and self.rect.bottom < self.screen_rect.bottom:
self.centery += self.settings.ship_speed_factor
self.rect.centerx = self.centerx
self.rect.centery = self.centery
def blitme(self):
# draws ship onto screen
self.screen.blit(self.image, self.rect)