def run_game():
    #Initialize pygame, settings and screen object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    #Make the play button
    play_button = Button(ai_settings, screen, "Play")

    #Create a GameStats instance to store game statistics
    stats = GameStats(ai_settings)

    #Make a ship, a group of bullets, and a group of aliens
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()

    #Create the fleet of aliens
    gf.create_fleet(ai_settings, screen, ship, aliens)
    

    #Start the main loop of the game
    while True:
        gf.check_events(ai_settings, screen, stats, play_button, ship, aliens, bullets)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)

        gf.update_screen(ai_settings, screen, stats, ship, aliens, bullets, play_button)
def run_game():
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")
    # make a ship
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()
    alien = Alien(ai_settings, screen)
    gf.create_fleet(ai_settings, screen, aliens)


    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)
        bullets.update()

        # Get rid of bullets that have disappeared.
        for bullet in bullets.copy():
            if bullet.rect.bottom <= 0:
                bullets.remove(bullet)
        print(len(bullets))
def run_game():
    #初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode( (ai_settings.screen_width, ai_settings.screen_height) )
    pygame.display.set_caption("Alien Invasion")

    #创建Play按钮
    play_button = Button(ai_settings,screen, "Play")

    #创建一个用于存储游戏统计信息的实例,并创建计分牌
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings,screen,stats)

    #创建一艘飞船
    ship = Ship(ai_settings, screen)
    #创建一个用于存储子弹的编组
    bullets = Group()
    #创建一个用于存储外星人的编组
    aliens = Group()
    #创建外星人群
    gf.create_fleet(ai_settings,screen,ship,aliens)


    #开始游戏的主循环
    while True:
        #监视键盘和鼠标事件
        gf.check_events(ai_settings,screen,stats,sb, play_button,ship,aliens,bullets)
        #根据移动标志调整飞船的位置
        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)
            gf.update_aliens(ai_settings,stats,screen,sb,ship,aliens,bullets)#更新子弹后再更新外星人位置,因为稍后要检查子弹是否撞到外星人
        #更新屏幕上的图像,并切换到新屏幕
        gf.update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button)
Example #4
0
def run_game():
    """运行游戏"""

    # 初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption(ai_settings.title)

    ship = Ship(screen)

    # 开始游戏的主循环
    while True:

        # 监视键盘和鼠标事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)

        screen.fill(ai_settings.bg_color)
        ship.blitme()

        # 让最近回执的屏幕可见
        pygame.display.flip()
Example #5
0
def run_game():
	# Initialize game and create a screen object.
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode(
	(ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	
	# Make the play button.
	play_button = Button(ai_settings,screen, "Play")
	
	# Create an instance to store game stats and create a scoreboard
	stats = GameStats(ai_settings)
	sb = Scoreboard(ai_settings,screen,stats)
	
	#Make a ship, a group of bullets, and a group of aliens.
	ship = Ship(ai_settings,screen)
	bullets = Group()
	aliens = Group()
	
	# Create a fleet of aliens
	gf.create_fleet(ai_settings,screen,ship,aliens)
	
	# Start the main loop for the game.
	while True:
		# Watch for keyboard and mouse events.
		gf.check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets)
		
		if stats.game_active:
			ship.update()
			gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)
			gf.update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets)	
		gf.update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button)
def run_game():

    # Initialize pygame, settings and screen object.
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Snoopvasion")

    # Create an instance to store game statistics.
    stats = GameStats(ai_settings)

    # Make a ship.
    ship = Ship(ai_settings, screen)
    # Make a group to store bullets in
    bullets = Group()
    aliens = Group()

    # Create the fleet of aliens.
    gf.create_fleet(ai_settings, screen, ship, aliens)

    # Start the main loop for the game.
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)

        gf.update_screen(ai_settings, screen, ship, aliens, bullets)
	def __init__(self, position=None, colour=None, 
				 projectile_pool=None, player_id=-1, name=""):
		Ship.__init__(self, position, colour, projectile_pool)
		self.id = player_id
		self.name = name
		self.destroyed = False
		self.respawn_in = -1
Example #8
0
	def populate_bg(self, bg):
		"""
		Populate a battleground with random ships.
		:param bg: the battleground to populate
		"""
		it = SHIP_LENS.__iter__()
		ship_len = it.next()
		while True:
		#for ship_len in SHIP_LENS:
			ship = Ship(ship_len)
			direction = random.randint(0, 1) # 0 = vertical, 1 = horizontal
			if direction == 0:
				start_x = random.randint(0, NUM_SQUARES - 1)
				start_y = random.randint(0, NUM_SQUARES - 1 - ship_len)
			elif direction == 1:
				start_x = random.randint(0, NUM_SQUARES - 1 - ship_len)
				start_y = random.randint(0, NUM_SQUARES - 1)

			squares = []
			for i in xrange(ship_len):
				if direction == 0:
					squares.append(Square(start_x, start_y + i, SquareState.intact))
				elif direction == 1:
					squares.append(Square(start_x + i, start_y, SquareState.intact))

			ship.squares = squares
			if bg.check_intersect(ship):
				continue
			bg.add_ship(ship)

			# Python's f****d up way to check if an iterator reached the end of a container
			try:
				ship_len = it.next()
			except:
				break
Example #9
0
def run_game():
    #Initialize pygame, settings, screen and screen object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")
    #make ship
    ship = Ship(ai_settings ,screen)
    #Make a group to store bullets in
    bullets = Group()
    #Make an alien group
    aliens = Group()
    #Make play button
    play_button = Button(ai_settings, screen, "Play")
    #Create fleet of aliens
    gf.create_fleet(ai_settings, screen, ship, aliens)
    #Create instance to store game statistics and create scoreboard
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings, screen, stats)

    
    #Start main loop for game
    while True:
        #Watch for keyboard/mouse events
        gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)
        
        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
            
        #Redraw the screen during each pass through the loop
        gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
Example #10
0
def run_game():
	# Initialize pygame, settings, and screen object
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode(
		(ai_settings.screen_width, ai_settings.screen_height))
	pygame.display.set_caption("Mutha F****n' Alien Invasion")

	# Set the background color.
	# bg_color = (230,230,230)

	# Make a ship, a group of bullets, and a group of aliens.
	ship = Ship(ai_settings, screen)
	bullets = Group()
	aliens = Group()

	# Create the fleet of aliens
	gf.create_fleet(ai_settings, screen, ship, aliens)

	# # A group to store super bullets in.
	# super_bullets = Group()

	# Start the main loop for the game.
	while True:

		gf.check_events(ai_settings, screen, ship, aliens, bullets)
		ship.update()
		gf.update_bullets(bullets)
		gf.update_screen(ai_settings, screen, ship, aliens, bullets)

		# Make the most recently drawn screen visible.
		pygame.display.flip()
Example #11
0
def run_game():
	# Initilize game and create a screen object
	pygame.init()
	ai_settings = Settings()

	# create a display window named screen
	screen = pygame.display.set_mode(
		(ai_settings.screen_width, ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")

	# set background color 
	bg_color = (230, 230, 230)

	# Make a ship
	ship = Ship(ai_settings, screen)

	# Make a group to store the bullets in.
	bullets = Group()

	# Start the main loop for the game
	while True:

		# Watch for keyboard and mouse events
		gf.check_events(ai_settings, screen, ship, bullets)
		ship.update()
		gf.update_bullets(bullets)
		gf.update_screen(ai_settings, screen, ship, bullets)
Example #12
0
def run_game():
	#Initializes the settings needed for pygame to run properly
	pygame.init()
	
	aiSettings = Settings()
	#Display mode called 'screen' is made, with 1200 x 800 dimensions
	#Screen is where the game elements are shown
	screen = pygame.display.set_mode(
		(aiSettings.screen_width,aiSettings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	#Sets background colour
	
	stats = GameStats(aiSettings)
	
	
	#Makes a ship on screen
	ship = Ship(aiSettings,screen)
	#Bullets! - make a group called bullets
	bullets = Group()
	#Aliens are made
	aliens = Group()
	
	#Calls on the createFleet function
	gf.createFleet(aiSettings, screen, ship, aliens)
	
	while True:
		gf.check_events(aiSettings,screen,ship,bullets)
		if stats.game_active:
			ship.update()
			gf.updateBullets(aiSettings, screen, ship, aliens, bullets)
			gf.updateAliens(aiSettings, stats, screen, ship, aliens, bullets)
	
		gf.update_screen(aiSettings, screen, ship, aliens, bullets)
def run_game():
    # Inicjalizacja pygame, ustawień i obiektu ekranu.
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Inwazja obcych")
    
    # Utworzenie egzemplarza przeznaczonego do przechowywania
    # danych statystycznych dotyczących gry.
    stats = GameStats(ai_settings)
    
    # Zdefiniowanie koloru tła.
    bg_color = (230, 230, 230)
    
    # Utworzenie statku, grupy pocisków oraz grupy obcych.
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()
    
    # Utworzenie floty obcych.
    gf.create_fleet(ai_settings, screen, ship, aliens)

    # Rozpoczęcie pętli głównej gry.
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        
        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
        
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)
Example #14
0
def run_game():

    # Initialising game, setting and screen objects
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("Space War")

    # Make a ship
    ship = Ship(ai_settings,screen)

    # Make Bullet (Group)
    bullets = Group()

    # Make Alien
    # alien = Alien(ai_settings,screen)
    aliens = Group()

    # Create an instance to store game statistics.
    stats = GameStats(ai_settings)

    # Fleet of aliens
    gf.create_fleet(ai_settings,screen,ship,aliens)

    # Game loop
    while True:

        # Check for events
        gf.check_events(ai_settings,screen,ship,bullets)
        if stats.game_active:
            # Updates
            ship.update()
            gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
        gf.update_screen(ai_settings,screen,ship,aliens,bullets)
Example #15
0
def run_game():
    """初始化pygame、设置和屏幕对象"""
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    # 创建button按钮
    play_button = Button(ai_settings, screen, "Play")

    # 创建存储游戏统计信息的实例,并创建记分牌
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings, screen, stats)

    # 创建一艘飞船、一个子弹编组和一个外星人编组
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()

    # 创建外星人群
    gf.create_fleet(ai_settings, screen, ship, aliens)

    # 开始游戏主循环
    while True:
        gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
            gf.update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets)

        gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
def run_game():
    # Initialise
    pygame.init()
    ai_settings=Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    # Make the Play button.
    play_button = Button(ai_settings, screen, "Play")

    # Create an instance to store game statistics and create a scoreboard.
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings, screen, stats)

    # Make a ship, a group of bullets and a group of aliens.
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()
    
    # Create the alien fleet
    gf.create_fleet(ai_settings, screen, ship, aliens)

    # main loop
    while True:
        gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)
        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
            gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)

        gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
def run_game():
    pygame.init()

    ai_settings = Settings()

    """ Screen settings and such"""
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))

    pygame.display.set_caption("Alien Invasion")
    stats = GameStats(ai_settings)

    bg_color = (230, 230, 230)
    """background screen color; grey"""

    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()
    gf.create_fleet(ai_settings, screen, ship, aliens)

    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
        gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

        for bullet in bullets.copy():
            if bullet.rect.bottom <= 0:
                bullets.remove(bullet)
        print(len(bullets))
def run_game():
    pygame.init() #make game
    ai_settings = Settings() #make settings object which has settings
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height)) #make window
    pygame.display.set_caption("Alien Invasion") #title for window
    ship = Ship(screen)
    
    while True: #forever loop for the window
        for event in pygame.event.get(): #wait for user to exit
            if event.type == pygame.QUIT:
                sys.exit()
                
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        pygame.display.flip() #redraw
Example #19
0
def run_game():
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))

    pygame.display.set_caption("Alien Invasion")

    play_button = Button(ai_settings, screen, "Play")

    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings, screen, stats)
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens =  Group()

    gf.create_fleet(ai_settings, screen, ship, aliens)

    while True:
        gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens,
                bullets)
            gf.update_aliens(ai_settings, screen, stats, sb, ship, aliens,
                bullets)

        gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
def run_game():
    # initialize game and create a screen object.
    # initialize pygame, settings, and screen object>
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("alien ivasion")

    # make a ship.
    ship = Ship(ai_settings, screen)

    # start the main loop for the game.
    while True:


        gf.check_events(ship)
        ship.update()
        gf.update_screen(ai_settings, screen, ship)


        # redraw the screen during each pass through  the loop.
        screen.fill(ai_settings.bg_color)
        ship.blitme()

        # make the most recently drawn screen visible.
        pygame.display.flip()
def run_game():
    # 初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    # 创建一艘飞船
    ship = Ship(ai_settings, screen)

    # 创建一个用于存储子弹的编组
    bullets = Group()

    # 创建一个外星人编组
    aliens = Group()

    # 创建外星人群
    gf.create_fleet(ai_settings, screen, aliens)

    # 开始游戏的主循环
    while True:

        # 监视键盘和鼠标事件
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)
Example #22
0
def run_game():
  #inits game and creates a screen object.
  pygame.init()
  ai_settings = Settings()
  screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
  pygame.display.set_caption("Alien Invasion")

  #Make the Play Button
  play_button = Button(ai_settings, screen, "Play")

  #Create an instance to store game stats and create a scoreboard 
  stats = GameStats(ai_settings)
  sb = Scoreboard(ai_settings, screen, stats)

  #make a ship
  ship = Ship(ai_settings, screen)
  #Make a group to store bullets in. 
  bullets = Group()
  #make an alien.
  aliens = Group()

  #Creating a fleet of aliens
  gf.create_fleet(ai_settings, screen, ship, aliens)


  #Start the main loop for the game.
  while True:
    gf.check_events(ai_settings, screen, stats, sb, play_button, ship, aliens, bullets)
    
    if stats.game_active:
      ship.update()
      gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets)
      gf.update_aliens(ai_settings, stats, screen, sb, ship, aliens, bullets)

    gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button)
def run_game():
    # Initialize pygame, settings, and screen object.
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    # Make a ship, a group of bullets, and a group of aliens.
    ship = Ship(ai_settings, screen)
    bullets = Group()
    aliens = Group()

    # Create the fleet of aliens.
    gf.create_fleet(ai_settings, screen, aliens)


    # Start the main loop for the game.
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

        # Redraw the screen during each pass through the loop.
        screen.fill(ai_settings.bg_color)
        ship.blitme()

        # Make the most recently drawn screen visible.
        pygame.display.flip()
Example #24
0
 def createShip(self):
     ship = Ship()
     ship.newSprite.connect(self.newSprite)
     ship.newMissile.connect(self.onNewMissile)
     ship.init()
     
     self.ship.add(ship)
     self.newSprite(self.ship)
Example #25
0
	def __init__(self, game):
		Ship.__init__(self, game, 0, twoStage=True)
		self.fixedPos = self.pos = (400, 300)
		self.accel = (0, 0)
		self.accelFactor = 0.4
		self.turning = 0
		self.shooting = False
		self.shootCounter = 0
Example #26
0
    def __init__(self, *args, **kargs):
        if not Destructor.img:
            Destructor.img = pygame.image.load("../media/destructor.png").convert_alpha()


        Ship.__init__(self, Destructor.img, *args, score = 200,
                      projectile = Missile, health = 200,
                      density = 0.85, **kargs)
Example #27
0
    def die(self):
        game = app.get_current_game()
        num = random()
        if num > 0.3:
            ent = HealModifierEntity(pos = self.pos)
            game.modifiers.add(ent)

        Ship.die(self)
Example #28
0
 def setUp(self):
     self.testPlayer = Player()
     self.ship1 = Ship('ship1', 3)
     self.ship2 = Ship('ship2', 4)
     self.ship3 = Ship('ship3', 2)
     self.testPlayer._setShips([self.ship1,
                                self.ship2,
                                self.ship3,
                                ])
Example #29
0
def generate_ships():
    """This generates ships non-strategically for testing purposes."""
    # Let's get some ships
    ships = []
    ships.append(Ship("M", 5, 5, "H"))
    ships.append(Ship.random_ship("D"))
    ships.append(Ship.random_ship("D"))
    ships.append(Ship.random_ship("P"))
    ships.append(Ship.random_ship("P"))
    return ships
 def setup_ship(self, name, length):
     while True :
         print("Add a " + name + " (length {0}):".format(length))
         start = input("Enter a start coordinate : ")
         end = input("Enter the end coordinate: ")
         ship = Ship(Coord(start), Coord(end))
         if ship.length() != length :
             print("That's not the right length ({0}). Try again.".format(ship.length()))
         else :
             break
     self._my_board.add_ship(ship)
Example #31
0
class AlienInvasion:
    """Class to manage game assets"""
    def __init__(self):
        """initializing the class"""
        pygame.init()

        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        print(self.settings.screen_width)
        self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Alien Invasion")

        self.stats = GameStats(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

    def _create_fleet(self):
        """Create fleet of aliens"""
        #Make an alien
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        ship_height = self.ship.rect.height

        available_space = self.settings.screen_width - (2 * alien_width)
        available_space_y = self.settings.screen_height - (
            3 * alien_height) - ship_height
        number_aliens_x = available_space // (2 * alien_width)
        number_rows = available_space_y // (2 * alien_height)

        #create first row of aliens
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, alien_width, alien_height,
                                   row_number)

    def _create_alien(self, alien_number, alien_width, alien_height,
                      row_number):

        alien = Alien(self)
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien_height + 2 * alien_height * row_number
        self.aliens.add(alien)

    def _fire_bullet(self):
        """Create a bullet and add it to the group"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def run_game(self):
        """Start the main loop of the game"""
        while True:
            self._check_event()
            self.ship.update()
            self._update_bullets()
            self._update_aliens()
            self._update_screen()

    def _update_bullets(self):
        self.bullets.update()

        #Get rid of bullets

        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collision()

    def _check_bullet_alien_collision(self):
        """ Check for any bullets that hit aliens
		 if so get rid of bullet and alien """
        collision = pygame.sprite.groupcollide(self.bullets, self.aliens, True,
                                               True)

        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()

        print(len(self.bullets))

    def _check_event(self):
        #watch for quit
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                self._check_keydown_event(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_event(event)

    def _check_keydown_event(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True

        if event.key == pygame.K_LEFT:
            self.ship.moving_left = True

        elif event.key == pygame.K_q:
            sys.exit()

        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_event(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False

        if event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _update_aliens(self):
        """Check if fleet is at the edge the update positions of all aliens in the fleet"""
        self._check_fleet_edges()
        self.aliens.update()

        #check if ship collides with aliens

        pygame.sprite.spritecollideany(self.ship, self.aliens)

        self._ship_hit()

    def _ship_hit(self):
        """Respond to the ship hot by alien"""

        self.stats.ship_left -= 1
        """get rid of remaining bullets and ships"""
        self.aliens.empty()
        self.bullets.empty()

        #Create a new fleet

        self._create_fleet()
        self.ship.center_ship()

        #pause
        sleep(0.5)

    def _check_fleet_edges(self):
        """Respond appropriately if any aliens have reached the edge"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change fleet's direction"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        for bullet in self.bullets.sprites():

            bullet.draw_bullet()

        self.aliens.draw(self.screen)

        # Refresh the screen
        pygame.display.flip()
Example #32
0
class AlienInvasion():
    """ A class to manage game assets and behavior """
    def __init__(self):
        """ Init game, and create game resources """
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption(f"Alien Invasion")

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

    def run_game(self):
        """ Start the main loop for the game """
        while True:
            self._check_events()
            self._update_screen()
            self.bullets.update()
            self.ship.update()
            self._update_bullets()

    def _check_events(self):
        # Watch for keyboard and mouse events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.rect.x += 1
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.rect.x -= 1

    def _check_keydown_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_screen(self):
        # Redraw the screen during each pass through the loop.
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

    def _update_bullets(self):
        self.bullets.update()

        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

    def _fire_bullet(self):
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _update_bullets(self):
        # Remove bullets that have disappeared from screen

        self.bullets.update()
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

    def _update_screen(self):
        # Redraw the screen during each pass through the loop.
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        for bullet in self.bullets:
            bullet.draw_bullet()

        self.aliens.draw(self.screen)

        # Draw most current screen
        pygame.display.flip()

    def _create_fleet(self):
        """ Create fleet of aliens """
        alien = Alien(self)
        alien_width = alien.rect.width
        available_space = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space // (2 * alien_width)

        # Create the first row of aliens
        for alien_number in range(number_aliens_x):
            self._create_alien(alien_number)

    def _create_alien(self, alien_number):
        alien = Alien(self)
        alien_width = alien.rect.width
        alien.x = (alien_number * alien_width * 2) + alien_width
        alien.rect.x = alien.x
        self.aliens.add(alien)
def run_game():
    #  Initialize game, screen settings and screen project.
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Space Invasion")

    pygame.mixer_music.load('Sounds/background_music.mp3')
    pygame.mixer_music.play(-1, 0)

    #  Make the buttons.
    play_button = Button(ai_settings, screen, "Play")
    high_score_button = Button(ai_settings, screen, "High Scores")
    quit_button = Button(ai_settings, screen, "Quit")
    back_button = Button(ai_settings, screen, "Back")
    start_button = Button(ai_settings, screen, "Start!")
    play_button.rect.centery -= 150
    play_button.msg_image_rect.centery = play_button.rect.centery
    high_score_button.rect.bottom = play_button.rect.bottom + 100
    high_score_button.msg_image_rect.center = high_score_button.rect.center
    quit_button.rect.bottom = screen.get_rect().bottom
    quit_button.rect.right = screen.get_rect().right
    quit_button.msg_image_rect.center = quit_button.rect.center
    back_button.rect.center = quit_button.rect.center
    back_button.msg_image_rect.center = back_button.rect.center
    start_button.rect.bottom = screen.get_rect().bottom
    start_button.rect.right = screen.get_rect().right
    start_button.msg_image_rect.center = start_button.rect.center

    #  Create an instance to store game statistics and create a scoreboard
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings, screen, stats)

    #  Make a ship.
    ship = Ship(ai_settings, screen)
    #  Make a group to store bullets in.
    bullets = Group()
    aliens = Group()
    alien_bullets = Group()
    bunkers = Group()

    #  Create a fleet of aliens
    gf.create_fleet(ai_settings, screen, ship, aliens, bunkers)

    #  Start the main loop for the game
    while True:
        #  Watch for keyboard and mouse events.
        gf.check_events(ai_settings, screen, stats, sb, play_button,
                        high_score_button, quit_button, back_button, ship,
                        aliens, bullets, bunkers)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens,
                              bullets, alien_bullets, bunkers)
            gf.update_aliens(ai_settings, stats, screen, sb, ship, aliens,
                             bullets, alien_bullets, bunkers)
        gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets,
                         play_button, high_score_button, quit_button,
                         back_button, alien_bullets, bunkers)
Example #34
0
class AlienInvision:
    """Класс для управления ресурсами и поведением игры."""
    def __init__(self):
        """Инициализирует игру и создает игровые ресурсы."""

        pygame.init()
        self.settings = Settings()
        # запуск на весь экран
        # self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height

        # не на весь єкран, потому что на весь не работает
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

    def run_game(self):
        """Запуск основных циклoв игры."""
        while True:
            # Отслеживание событий клавиатуры и мыши.
            self._check_events()
            self.ship.update()
            self._update_bullets()
            self._update_aliens()
            self._update_screen()

    def _check_events(self):
        """Обрабатывает нажатие клавиш и события мыши"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        # нажатие клавиш
        if event.key == pygame.K_RIGHT:
            # переместить корабль вправо
            self.ship.moving_right = True
            # перемещает влево
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        # Реагирует на отпускание клавиш.
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        '''Создание снаряда и включение его в группу bullets.'''
        if len(self.bullets) < self.settings.bullet_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Обновляет позиции снарядов и уничтожает старые снаряды."""
        # Обновление снаряда.
        self.bullets.update()

        # Удаление снарядов, вышедших за край экрана.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        '''Обработка коллизий снарядов с пришельцами.'''
        # Удаление снарядов и пришельцев, участвующих  в колизиях.
        collisions = pygame.sprite.groupcollide(
            self.bullets, self.aliens, True,
            True)  # 1 True - уничтожения снаряда

        if not self.aliens:
            # Уничтожение существующих снарядов и создание нового флота.
            self.bullets.empty()
            self._create_fleet()

    def _update_aliens(self):
        '''Обновляет позиции всех пришельцев во флоте.'''
        # Проверяет достиг ли флот края экрана, с последующим обновлением позиций всех пришельцев во флоте.
        self._check_fleet_edges()
        self.aliens.update()

    def _create_fleet(self):
        '''Создание флота вторжения.'''
        # Создание пришельца и вычисление количества пришельцев в ряду.
        # Интервал между соседними пришельцами равен ширине пришельца.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        avalible_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = avalible_space_x // (2 * alien_width)
        '''Определяет количество рядов, помещающихся на экране.'''
        ship_height = self.ship.rect.height
        avalible_space_y = (self.settings.screen_height - (3 * alien_height) -
                            ship_height)
        number_rows = avalible_space_y // (2 * alien_height)

        # Создание флота вторжения.
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                # Создание пришельца и размищение его в ряду.
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        '''Создание пришельца и размищение его в ряду.'''
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        '''Реагирует на достижение пришельца края экрана.'''
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        '''Опускает весь флот и меняет направление флота.'''
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """Обновляет изображения на экране и отображает новый экран."""
        # При каждом проходе цикла перерисовывается экран.
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)
        # Отображение последнего прорисованного зкрана.
        pygame.display.flip()
Example #35
0
import sys
import pygame
from ship import Ship
from pygame.sprite import Group
from bullet import Bullet

screen = pygame.display.set_mode((800,600))


ship = Ship(screen)
bullets = Group()

while True:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                ship.moving_right = True
            elif event.key == pygame.K_LEFT:
                ship.moving_left = True
            elif event.key == pygame.K_UP:
                ship.moving_up = True
            elif event.key == pygame.K_DOWN:
                ship.moving_down = True
            elif event.key == pygame.K_SPACE:
                new_bullet = Bullet(ship,screen)
                bullets.add(new_bullet)
        elif event.type == pygame.KEYUP:
            ship.moving_left = False
class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源"""
        pygame.init()
        # 导入游戏设置
        self.settings = Settings()
        # 设置游戏名称
        pygame.display.set_caption(self.settings.name)
        # 创建用于存储游戏信息实例
        self.stats = GameStates(self)
        # 设置窗口屏幕大小
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        # 背景颜色调整
        self.bg_color = self.settings.screen_color
        # 导入飞船
        self.ship = Ship(self)
        # 子弹存储
        self.bullets = pygame.sprite.Group()
        # 外星人存储
        self.aliens = pygame.sprite.Group()
        self._create_fleet()
        # 设置计分
        self.sb = Scoreboard(self)
        # 创建play按钮
        self.play_button = Button(self, "play")

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            self._check_events()
            if self.stats.game_active:
                self.ship.update_position()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _check_events(self):
        """监视键盘和鼠标事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """玩家单机play时运行游戏"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # 重置游戏设置
            self.settings.initialize_dynamic_settings()
            # 重置游戏信息
            self.stats.reset_stats()
            self.stats.game_active = True
            # 清空子弹丶外星人
            self.aliens.empty()
            self.bullets.empty()
            # 创建一群新的外星人并让飞船居中
            self._create_fleet()
            self.ship.center_ship()
            pygame.mouse.set_visible(False)

    def _check_keyup_events(self, event):
        """松开按键"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False
        elif event.key == pygame.K_UP:
            self.ship.moving_up = False
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = False

    def _check_keydown_events(self, event):
        """按下按键"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_UP:
            self.ship.moving_up = True
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = True
        elif event.key == pygame.K_SPACE:
            self._create_bullet()

    def _create_bullet(self):
        """创建一颗子弹,并将其加入编组bullets中"""
        if len(self.bullets) < self.settings.bullet_maxNum:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """更新子弹位置并删除消失的子弹"""
        self.bullets.update()
        # 删除消失的子弹
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        # 检查是否有子弹击中外星人
        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """响应子弹与外星人碰撞"""
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)
        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

    def _draw_bullets(self):
        # 在屏幕上绘制打出的子弹
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

    def _create_fleet(self):
        """创建外星人舰队"""
        # 创建一个外星人,并且计算一行可以容纳多少外星人
        # 外星人间距为外星人宽度
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)
        # 计算屏幕能容纳多少行外星人
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - 3 * alien_height -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)
        # 创建外星人群
        for row_number in range(number_rows):
            # 创建一行外星人
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """创建一个外星人把它加入当前行的指定位置"""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.set_alien_rect_X(alien_width + 2 * alien_width * alien_number)
        alien.set_alien_rect_Y(alien.rect.height +
                               2 * alien.rect.height * row_number)
        self.aliens.add(alien)

    def _update_aliens(self):
        """更新外星人群中所有外星人位置"""
        self._check_fleet_edges()
        self.aliens.update()
        # 检测外星人与飞船是否碰撞
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()
        self._check_aliens_bottom()

    def _check_fleet_edges(self):
        """外星人到达屏幕边缘时采取相应措施"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """整群外星人下移并且改变放向"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """更新屏幕图像,并切换到新屏幕"""
        self.screen.fill(self.bg_color)
        self.ship.blitMe()
        self._draw_bullets()
        self.aliens.draw(self.screen)
        # 显示得分
        self.sb.show_score()
        # 若游戏处于非活动状态,绘制play按钮
        if not self.stats.game_active:
            self.play_button.draw_button()
        # 让最近绘制的屏幕可见
        pygame.display.flip()

    def _ship_hit(self):
        """响应飞船与外星人碰撞"""
        # 飞船数量-1
        if self.stats.ships_left > 0:
            self.stats.ships_left -= 1
            # 清空子弹,外星人
            self.aliens.empty()
            self.bullets.empty()
            # 建立一群新的外星人,并将飞船放在屏幕低端中央
            self._create_fleet()
            self.ship.center_ship()
            # 暂停
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        """检查是否有外星人到达底端"""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                self._ship_hit()
                break
def run_game():
		# Initialize pygame, settings, and screen object.
		pygame.init()
		ai_settings = Settings()
		screen =  pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
		pygame.display.set_caption("Alien Invasion")

		# Make a ship.
		ship = Ship(ai_settings, screen)

		#Make a group to store bullets in.
		bullets = Group()

		# Make an alien
		aliens = Group()

		# Create the fleet of aliens.
		gf.create_fleet(ai_settings, screen, aliens, ship)

		stats = GameStats(ai_settings)

		# Set the background color.
		bg_color = (230, 230, 230)

		ship_counter = 0

		game_active = True

		play_button = Button(ai_settings, screen, "Play")

		gf.update_screen(ai_settings, screen, ship, bullets, aliens)

		play_button.draw_button()

		pygame.display.flip()

		game_starting = True

		while game_starting:

			mouse_x, mouse_y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if play_button.rect.collidepoint(mouse_x, mouse_y) and event.type == pygame.MOUSEBUTTONDOWN:
					game_starting = False
					del play_button



		# Start the main loop for the game.
		while game_active:

				pygame.mouse.set_visible(False)

				# Watch for keyboard and mouse events.
				gf.check_events(ai_settings,screen,ship,bullets)

				gf.update_bullets(ai_settings, screen, ship, aliens, bullets)

				if pygame.sprite.spritecollideany(ship,aliens) or gf.alien_landed(screen, aliens):
					print("Life lost!")
					stats.lose_life()

					if  stats.check_game_over():
						print("Game over")
						game_active = False
					else:
						gf.update_aliens(ai_settings, screen, aliens, ship, bullets)


				# Redraw the screen during each pass through the loop.
				gf.update_screen(ai_settings, screen, ship, bullets, aliens)

				# Make the most recently drawn screen visible.
				pygame.display.flip()


		pygame.mouse.set_visible(True)
		
		end_button = Button(ai_settings, screen, "Quit")

		end_button.draw_button()

		pygame.display.flip()

		while True:

			mouse_x, mouse_y = pygame.mouse.get_pos()

			for event in pygame.event.get():

				if event.type == pygame.MOUSEBUTTONDOWN and end_button.rect.collidepoint(mouse_x, mouse_y):
					sys.exit()
class AlienInvasion:
    """Overall class to manage game assets and behavior."""
    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((1200, 800))
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height

        # creates a screen
        pygame.display.set_caption("Alien Invasion")
        self.bg_color = (230, 230, 230)

        # Create an instance to store game statistics,
        # and create a scoreboard.
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # Make the Play button.
        self.play_button = Button(self, "Play")

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
                self._update_screen()
            else:
                self._update_screen()

    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # quiting the game
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks Play."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # Reset the game settings
            self.settings.initialize_dynamic_settings()
            # Reset the game statistics.
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            # Get rid of any remaining aliens and bullets.
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship.
            self._create_fleet()
            self.ship.center_ship()

            # Hide the mouse button.
            pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_RIGHT:
            # Move the ship to the right.
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        # if you want ot limit num of bullets:
        if len(self.bullets) < self.settings.bullets_allowed:
            #
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        self.bullets.update()

        # Get rid of bullets that have disappeSared.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions."""
        # Remove any bullets and aliens that have collided.
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            # Destroy existing bullets and create new fleet.
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            # Increase level.
            self.stats.level += 1
            self.sb.prep_level()

    def _update_aliens(self):
        """
        Check if the fleet is at an edge,
        then update the positions of all aliens in the fleet.
        """
        self._check_fleet_edges()
        self.aliens.update()

        # Look for alien-ship collisions.
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Look for aliens hitting the bottom of the screen.
        self._check_aliens_bottom()

    def _ship_hit(self):
        """Respond to the ship being hit by an alien."""
        if self.stats.ships_left > 0:
            # Decrement ships_left and update scoreboard
            self.stats.ships_left -= 1
            self.sb.prep_ships()
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)
        # Get rid of any remaining aliens and bullets.
        self.aliens.empty()
        self.bullets.empty()

        # Create a new fleet and center the ship.
        self._create_fleet()
        self.ship.center_ship()
        # Pause
        sleep(0.5)

    def _check_aliens_bottom(self):
        """Check if any aliens have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()

                break

    def _create_fleet(self):
        """Create the fleet of aliens."""
        # Create an alien and find the number of aliens in a row.
        # Spacing between each alien is equal to one alien width.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that fit on the screen.
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create the full fleet of aliens.
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _check_fleet_edges(self):
        """Respond appropriately if any aliens have reached an edge."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
            break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _create_alien(self, alien_number, row_number):
        # Create an alien and place it in the row.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x

        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        # Redraw the screen during each pass through the loop.
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.aliens.draw(self.screen)

        # Draw the score information.
        self.sb.show_score()

        # Draw the play button if the game is inactive.
        if not self.stats.game_active:
            self.play_button.draw_button()

        # Make the most recently drawn screen visible.
        pygame.display.flip()
class AlienInvasion:
    """Overall class to manage game assets and behavior."""
    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        pygame.display.set_caption("Alien Invasion")

        # Create an instance to store game statistics,
        #   and create a scoreboard.
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.text = Text(self)
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # Make buttons.
        self.play_button = Button(self, "Play", -0.6)
        self.goon_button = Button(self, "Continue", -0.6)
        self.score_button = Button(self, "Score", 0.2)
        self.help_button = Button(self, "Help", 1)
        self.exit_button = Button(self, "Exit", 1.8)
        self.back_button = Button(self, "Back to Menu", 3.7, 36, 190, 40)
        self.record_file = './scores.json'
        with open(self.record_file, 'r') as f:
            self.record = json.load(f)

    #   back 上一点         主menu往下一点

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()

            if self.stats.game_state == c.RUN:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                if self.stats.game_state == c.MENU:
                    self._check_play_button(mouse_pos)
                    self._check_score_button(mouse_pos)
                    # self._check_continue_button(mouse_pos)
                    self._check_exit_button(mouse_pos)
                    self._check_help_button(mouse_pos)
                if self.stats.game_state == c.HELP or self.stats.game_state == c.SCORE or self.stats.game_state == c.FINAL:
                    self._check_back_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks Play."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and self.stats.game_state == c.MENU and not c.PAUSE:
            # Reset the game settings.
            self.settings.initialize_dynamic_settings()

            # Reset the game statistics.
            self.stats.reset_stats()
            self.stats.game_state = c.RUN
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            # Get rid of any remaining aliens and bullets.
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship.
            self._create_fleet()
            self.ship.center_ship()

            # Hide the mouse cursor.
            pygame.mouse.set_visible(False)

        if button_clicked and self.stats.game_state == c.MENU and c.PAUSE:
            self.stats.game_state = c.RUN
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()
            c.PAUSE = False
            # Hide the mouse cursor.
            pygame.mouse.set_visible(False)

    def _check_score_button(self, mouse_pos):
        """Show information about scores when the player clicks Score."""
        button_clicked = self.score_button.rect.collidepoint(mouse_pos)
        # implement score_button here
        if button_clicked:
            self.stats.game_state = c.SCORE

    def _check_back_button(self, mouse_pos):
        """Show information about scores when the player clicks Score."""
        button_clicked = self.back_button.rect.collidepoint(mouse_pos)
        if button_clicked and self.stats.game_state == c.FINAL:
            # Reset the game statistics.
            self.stats.reset_stats()
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            # Get rid of any remaining aliens and bullets.
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship.
            self._create_fleet()
            self.ship.center_ship()
            self.stats.game_state = c.MENU
        elif button_clicked and self.stats.game_state != c.FINAL:
            self.stats.game_state = c.MENU

    def _check_help_button(self, mouse_pos):
        """Show information about scores when the player clicks Score."""
        button_clicked = self.help_button.rect.collidepoint(mouse_pos)
        if button_clicked:
            self.stats.game_state = c.HELP

    def _check_exit_button(self, mouse_pos):
        """Show information about scores when the player clicks Score."""
        button_clicked = self.exit_button.rect.collidepoint(mouse_pos)
        if button_clicked:
            sys.exit()

    # def _check_continue_button(self, mouse_pos):
    #     """Continue the game when the player clicks Score."""
    #     button_clicked = self.continue_button.rect.collidepoint(mouse_pos)
    #     if button_clicked and not self.stats.game_state:
    #         self.stats.game_state = True
    #
    #         # Hide the mouse cursor.
    #         pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_ESCAPE:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            if self.stats.game_state == c.RUN:
                self._fire_bullet()
        elif event.key == pygame.K_z:
            if self.stats.game_state == c.RUN and self.stats.level > 3:
                self._fire_bullet_plus_left()
        elif event.key == pygame.K_c:
            if self.stats.game_state == c.RUN and self.stats.level > 3:
                self._fire_bullet_plus_right()
        elif event.key == pygame.K_r:
            if self.stats.game_state == c.DEAD:
                # Get rid of any remaining aliens and bullets.
                self.aliens.empty()
                self.bullets.empty()

                # Create a new fleet and center the ship.
                self._create_fleet()
                self.ship.center_ship()
                self.stats.game_state = c.RUN
            elif self.stats.game_state == c.PASS:
                self.bullets.empty()
                self._create_fleet()
                self.settings.increase_speed()

                # Increase level.
                self.stats.level += 1
                self.sb.prep_level()

                self.stats.game_state = c.RUN
            elif self.stats.game_state == c.MENU and c.PAUSE:
                self.stats.game_state = c.RUN
                # Hide the mouse cursor.
                c.PAUSE = False
                pygame.mouse.set_visible(False)
        elif event.key == pygame.K_p:
            if self.stats.game_state == c.RUN:
                self.stats.game_state = c.MENU
                c.PAUSE = True
                pygame.mouse.set_visible(True)

    def _check_keyup_events(self, event):
        """Respond to key releases."""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)
            se.bullet_sound.play()

    def _fire_bullet_plus_left(self):
        """Create a new bullet towards left and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed - 2:
            new_bullet = Bullet_plus_left(self)
            self.bullets.add(new_bullet)
            se.bullet_sound.play()

    def _fire_bullet_plus_right(self):
        """Create a new bullet towards left and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed - 2:
            new_bullet = Bullet_plus_right(self)
            self.bullets.add(new_bullet)
            se.bullet_sound.play()

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        # Update bullet positions.
        self.bullets.update()

        # Get rid of bullets that have disappeared.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions."""
        # Remove any bullets and aliens that have collided.
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
                self.sb.prep_score()
            se.alien_sound.play()

        if not self.aliens:
            # Destroy existing bullets and create new fleet.
            self.stats.game_state = c.PASS

    def _update_aliens(self):
        """
        Check if the fleet is at an edge,
          then update the positions of all aliens in the fleet.
        """
        self._check_fleet_edges()
        self.aliens.update()

        # Look for alien-ship collisions.
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Look for aliens hitting the bottom of the screen.
        self._check_aliens_bottom()

    def _check_aliens_bottom(self):
        """Check if any aliens have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()
                break

    def _ship_hit(self):
        """Respond to the ship being hit by an alien."""
        if self.stats.ships_left > 1:
            # Decrement ships_left, and update scoreboard.
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            # Pause.
            sleep(0.1)
            self.stats.game_state = c.DEAD
            # pygame.mouse.set_visible(True)
        else:
            sleep(0.1)
            self.stats.game_state = c.FINAL
            pygame.mouse.set_visible(True)

    def _create_fleet(self):
        """Create the fleet of aliens."""
        # Create an alien and find the number of aliens in a row.
        # Spacing between each alien is equal to one alien width.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that fit on the screen.
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create the full fleet of aliens.
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """Create an alien and place it in the row."""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """Respond appropriately if any aliens have reached an edge."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.aliens.draw(self.screen)
        self.ship.blitme()
        # Draw the score information.
        self.sb.show_score()
        cover = pygame.Surface(
            (pygame.display.Info().current_w, pygame.display.Info().current_h),
            pygame.SRCALPHA)
        cover.fill(c.COVER)

        # Draw the play button if the game is inactive.
        if self.stats.game_state == c.MENU and c.PAUSE:
            self.screen.blit(cover, (0, 0))
            self.text.title()
            self.play_button.draw_button()
            self.goon_button.draw_button()
            self.score_button.draw_button()
            self.help_button.draw_button()
            self.exit_button.draw_button()
            self.text.goon()
        elif self.stats.game_state == c.MENU and not c.PAUSE:
            self.screen.blit(cover, (0, 0))
            self.text.title()
            self.play_button.draw_button()
            self.score_button.draw_button()
            self.help_button.draw_button()
            self.exit_button.draw_button()
        elif self.stats.game_state == c.DEAD:
            # when the game stops and you still have some chances
            self.screen.blit(cover, (0, 0))
            self.text.diaplay(
                "You dead, " + str(self.stats.ships_left) +
                " ships left." if self.stats.ships_left > 1 else "You dead, " +
                str(self.stats.ships_left) + " ship left.")
            self.text.goon()
        elif self.stats.game_state == c.PASS:
            # when the game stops and you still have some chances
            self.screen.blit(cover, (0, 0))
            self.text.diaplay("Cong! " + "Next Level: " +
                              str(self.stats.level + 1))
            if self.stats.level == 3:
                self.text.diaplay(
                    "You can press z/c to fire anterolaterally now.", 1, 25,
                    "Consolas")
            self.text.goon()
        elif self.stats.game_state == c.FINAL:
            # when the game stops and you just don't have any chances
            # update scores.json

            self.stats.score = round(self.stats.score, -1)
            if int(self.record['3']) < self.stats.score < int(
                    self.record['2']):
                self.record['3'] = str(self.stats.score)
                self.stats.rank = 3
            elif int(self.record['2']) < self.stats.score < int(
                    self.record['1']):
                self.record['3'] = self.record['2']
                self.record['2'] = str(self.stats.score)
                self.stats.rank = 2
            elif self.stats.score > int(self.record['1']):
                self.record['3'] = self.record['2']
                self.record['2'] = self.record['1']
                self.record['1'] = str(self.stats.score)
                self.stats.rank = 1
            elif self.stats.score == int(self.record['1']):
                self.stats.rank = 1
            elif self.stats.score == int(self.record['2']):
                self.stats.rank = 2
            elif self.stats.score == int(self.record['3']):
                self.stats.rank = 3

            with open(self.record_file, 'w') as f:
                json.dump(self.record, f)

            self.screen.blit(cover, (0, 0))

            self.text.finial(str(self.stats.score), self.stats.rank)

            self.back_button.draw_button()

        elif self.stats.game_state == c.SCORE:
            self.screen.blit(cover, (0, 0))
            self.text.record(self.record['1'], self.record['2'],
                             self.record['3'])
            self.back_button.draw_button()

        elif self.stats.game_state == c.HELP:
            self.screen.blit(cover, (0, 0))
            self.text.help()
            self.back_button.draw_button()
        pygame.display.flip()
Example #40
0
class AlienInvasion:
    """Overall class to manage game assets and behavior"""
    def __init__(self):
        """Init the game, and create game resources"""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Alien Invasion")

        #Create an isntance to store game stats and create scoreboard
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        #Make the Play button
        self.play_button = Button(self, "Play")

    def run_game(self):
        """Start the main loop for the game"""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

    def _check_events(self):
        """Respond to key press and mouse events"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Start new game when player clicks play"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            #Reset the game settings
            self.settings.initialize_dynamic_settings()

            #Reset game stats
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            #Get rid of any bullets and aliens
            self.aliens.empty()
            self.bullets.empty()

            #Create new fleet and center ship
            self._create_fleet()
            self.ship.center_ship()
            pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        """Respond to key presses"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """Respond to key releases"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """Create new bullet and add to bullets group"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update bullet position and remove old bullets"""
        self.bullets.update()

        #Get rid of old bullets
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        #print(len(self.bullets))

        self._check_bullet_alien_collision()

    def _check_bullet_alien_collision(self):
        #Check for any bullets that have hit aliens
        #If so, get rid of bullet and alien
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            #Destroy existing bullets and create new fleet
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            #Increase level
            self.stats.level += 1
            self.sb.prep_level()

    def _update_aliens(self):
        """Check if fleet is on edge, Update the pos of all aliens"""
        self._check_fleet_edges()
        self.aliens.update()

        #Check for alien-ship collision
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        #Look for aliens reaching the bottom
        self._check_aliens_bottom()

    def _check_aliens_bottom(self):
        """Check if any aliens reach the bottom"""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                #Treat same as ship hit
                self._ship_hit()
                break

    def _create_fleet(self):
        """Create a whole fleet of aliens"""
        #Make alien and find number of aliens in a row
        #Spacing between each alien is equal to one alien width
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        #Determine the number of rows of aliens that fit
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        #Create the fill fleet of aliens
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        #Create alien and place in row
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """Respond appropriately if aliens reach edge"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop entire fleet down, move other direction"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _ship_hit(self):
        """Respond to the ship being hit by alien"""

        if self.stats.ships_left > 0:
            #Decrement ships_left and update display
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            #Get rid of all remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            #Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            #Pause.
            sleep(.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _update_screen(self):
        '''Update images on the screen and flip to the new screen'''
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        #Draw scoreboard
        self.sb.show_score()

        #Draw the play button if game inactive
        if not self.stats.game_active:
            self.play_button.draw_button()

        #Make the most recently drawn screen visible
        pygame.display.flip()
Example #41
0
class AlienInvasion:
    """Overall class to manage game assets and behavior."""
    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        # Create an instance to store game statistics.
        self.stats = GameStats(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # Make the Play button.
        self.play_button = Button(self, "Play")

        # Make difficulty level buttons.
        self._make_difficulty_buttons()

    def _make_difficulty_buttons(self):
        """Make buttons that allow player to select difficulty level."""
        self.easy_button = Button(self, "Easy")
        self.medium_button = Button(self, "Medium")
        self.difficult_button = Button(self, "Difficult")

        # Position buttons so they don't all overlap.
        self.easy_button.rect.top = (self.play_button.rect.top +
                                     1.5 * self.play_button.rect.height)
        self.easy_button._update_msg_position()

        self.medium_button.rect.top = (self.easy_button.rect.top +
                                       1.5 * self.easy_button.rect.height)
        self.medium_button._update_msg_position()

        self.difficult_button.rect.top = (self.medium_button.rect.top +
                                          1.5 * self.medium_button.rect.height)
        self.difficult_button._update_msg_position()

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)
                self._check_difficulty_buttons(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks Play."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            self._start_game()

    def _check_difficulty_buttons(self, mouse_pos):
        """Set the appropriate difficulty level."""
        easy_button_clicked = self.easy_button.rect.collidepoint(mouse_pos)
        medium_button_clicked = self.medium_button.rect.collidepoint(mouse_pos)
        diff_button_clicked = self.difficult_button.rect.collidepoint(
            mouse_pos)
        if easy_button_clicked:
            self.settings.difficulty_level = 'easy'
        elif medium_button_clicked:
            self.settings.difficulty_level = 'medium'
        elif diff_button_clicked:
            self.settings.difficulty_level = 'difficult'

    def _start_game(self):
        """Start a new game."""
        # Reset the game settings.
        self.settings.initialize_dynamic_settings()

        # Reset the game statistics.
        self.stats.reset_stats()
        self.stats.game_active = True

        # Get rid of any remaining aliens and bullets.
        self.aliens.empty()
        self.bullets.empty()

        # Create a new fleet and center the ship.
        self._create_fleet()
        self.ship.center_ship()

        # Hide the mouse cursor.
        pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_p and not self.stats.game_active:
            self._start_game()

    def _check_keyup_events(self, event):
        """Respond to key releases."""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        # Update bullet positions.
        self.bullets.update()

        # Get rid of bullets that have disappeared.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions."""
        # Remove any bullets and aliens that have collided.
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if not self.aliens:
            # Destroy existing bullets and create new fleet.
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

    def _update_aliens(self):
        """
        Check if the fleet is at an edge,
          then update the positions of all aliens in the fleet.
        """
        self._check_fleet_edges()
        self.aliens.update()

        # Look for alien-ship collisions.
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Look for aliens hitting the bottom of the screen.
        self._check_aliens_bottom()

    def _check_aliens_bottom(self):
        """Check if any aliens have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()
                break

    def _ship_hit(self):
        """Respond to the ship being hit by an alien."""
        if self.stats.ships_left > 0:
            # Decrement ships_left.
            self.stats.ships_left -= 1

            # Get rid of any remaining aliens and bullets.
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship.
            self._create_fleet()
            self.ship.center_ship()

            # Pause.
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _create_fleet(self):
        """Create the fleet of aliens."""
        # Create an alien and find the number of aliens in a row.
        # Spacing between each alien is equal to one alien width.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that fit on the screen.
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create the full fleet of aliens.
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """Create an alien and place it in the row."""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """Respond appropriately if any aliens have reached an edge."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        # Draw the play button if the game is inactive.
        if not self.stats.game_active:
            self.play_button.draw_button()
            self.easy_button.draw_button()
            self.medium_button.draw_button()
            self.difficult_button.draw_button()

        pygame.display.flip()
Example #42
0
class AlienInvasion:
    """Overall class to manage game assets and behavior."""

    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Alien Invasion")

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()


    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()
            self.ship.update()
            self._update_bullets()
            self._update_screen()


    def _create_fleet(self):
        """create fleet of aliens"""
        #create first row of aliens
        for alien_number in range(number_aliens_x):
            #create alien put in row
            alien = Alien(self)
            alien.x = alien_width + 2 * alien_width * alien_number
            alien.rect.x = alien.x
            self.aliens.add(alien)


    def _create_alien(self, alien_number):
        """create alien place it in row"""
        #make alien
        alien = Alien(self)
        self.aliens.add(alien)
        alien_width = alien.rect.width
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)



    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_d:
            self.ship.moving_right = True
        elif event.key == pygame.K_a:
            self.ship.moving_left = True
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_q:
            sys.exit()

    def _check_keyup_events(self, event):
        """Respond to key releases."""
        if event.key == pygame.K_d:
            self.ship.moving_right = False
        elif event.key == pygame.K_a:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """create new bullet add to bullets group"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """update position of bullets and get rid of old bullets."""
        #update bullet position
        self.bullets.update()

        #get rid of bullets that have exited screen
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        #print(len(self.bullets))

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        pygame.display.flip()
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# Initialize pygame, settings, and screen object.
pygame.init()
settings = Settings()
screen = pygame.display.set_mode(
    (settings.screen_width, settings.screen_height))

sb = Scoreboard(settings, screen)

player = Ship(
    screen, settings
)  # Create the player; Player is a ship; Draw the ship on the screen

# Make a group to store bullets in.
bullets = Group()

# Make a group to store enemies in.
enemies = Group()

# Make a group to store enemy bullets in
enemy_bullets = Group()

# Make an enemy.
gf.spawn_enemies(settings, screen, enemies, enemy_bullets)

pygame.display.set_caption("My Game")
Example #44
0
class SideScroller:
    """Overall class to manage the game assets and behavior"""

    def __init__(self):
        """initialize the game"""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        #grab the screen width and height for later calculations
        self.screen_width, self.screen_height = pygame.display.get_surface().get_size()

        pygame.display.set_caption("Side Scroller")

        #create instance to store game stats
        self.stats = GameStats(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        # counter for time based stuff TODO: see if there is a better way to do this
        self.counter = 0

        #Background color
        self.bg_color = self.settings.bg_color

        #Make play button
        self.play_button = Button(self, "Play")

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullet()
                self._update_aliens()
            
            self._update_screen()

    #event handlers

    def _check_events(self):
        #Watch for keyboard events in game
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    self._check_keydown_events(event)
                elif event.type == pygame.KEYUP:
                    self._check_keyup_events(event)
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    mouse_pos = pygame.mouse.get_pos()
                    self._check_play_button(mouse_pos)

    def _check_keydown_events(self, event):
        #check which button the player pressed
        if event.key == pygame.K_q:
            #press q to quit
            sys.exit()
        elif event.key == pygame.K_UP:
            #move ship up
            self.ship.moving_up = True
        elif event.key == pygame.K_DOWN:
            #move ship down
            self.ship.moving_down = True
        elif event.key == pygame.K_SPACE:
            #shoot a bullet if not recently fired
            if len(self.bullets) < self.settings.bullet_limit:
                self._fire_bullet()

    def _check_keyup_events(self, event):
        #Check when the player releases a key
        if event.key == pygame.K_UP:
            #move ship up
            self.ship.moving_up = False
        elif event.key == pygame.K_DOWN:
            #move ship down
            self.ship.moving_down = False

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks play."""

        # If the player clicks the play button AND the game isn't going
        if self.play_button.rect.collidepoint(mouse_pos) and not self.stats.game_active:

            # reset the game stats
            self.stats.reset_stats()
            self.stats.game_active = True

            # get rid of any remaining aliens and bullets.
            self.aliens.empty()
            self.bullets.empty()

            # recenter player
            self.ship.center_ship()

            # hide the mouse cursor
            pygame.mouse.set_visible(False)

    #misc helper functions

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group"""
        new_bullet = Bullet(self)
        self.bullets.add(new_bullet)

    def _spawn_enemy(self):
        """Spawns enemies randomly from the right side of the screen"""
        alien = Alien(self)
        alien_width = alien.rect.width
        alien.x = self.screen_width
        self.aliens.add(alien)

    def _ship_hit(self):
        """respond to ship being hit by alien"""

        if self.stats.ships_left > 0:
            #Decrement ships
            self.stats.ships_left -= 1

            #Get rid of remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # Recenter the ship
            self.ship.center_ship

            # pause
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    # update functions

    def _update_bullet(self):
        """Update position of bullets and get rid of old bullets"""

        # update position of old bullets
        self.bullets.update()

        # Get rid of bullets that are off screen
        for bullet in self.bullets.copy():
            if bullet.rect.left >= self.screen_width:
                self.bullets.remove(bullet)

        # see if it hit an alien
        # get rid of both if so
        collisions = pygame.sprite.groupcollide(
            self.bullets, self.aliens, True, True
        )

    def _update_aliens(self):
        """make the aliens move slowly to the left"""

        #update position of aliens
        self.aliens.update()

        #increase counter
        self.counter += 1

        #delete offscreen aliens
        for alien in self.aliens.copy():
            if alien.rect.right < 0:
                self.aliens.remove(alien)

        #spawn new enemies if counter is 10
        if self.counter == 500:
            self._spawn_enemy()
            self.counter = 0

        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()


    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        # Redraw the screen during each pass of the loop
        self.screen.fill(self.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)
        if not self.stats.game_active:
            self.play_button.draw_button()

        # Make the most recently drawn screen visible
        pygame.display.flip()
Example #45
0
class alieninvasion:
    def __init__(self):
        pygame.init()
        self.settings = Settings()
        if self.settings.Full_screen == 0:
            self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
            pygame.display.set_caption('FISHDOM QUEST')
        elif self.settings.Full_screen != 0:
            self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
            self.settings.screen_width = self.screen.get_rect().width
            self.settings.screen_height = self.screen.get_rect().height
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

    def _create_fleet(self):
        alien = Alien(self)
        alien_height = alien.rect.height - 59
        # print(alien_height)
        availible_space_y = self.settings.screen_height - (alien_height)//2
        # print(availible_space_y)
        number_aliens_y = availible_space_y // (2 * (alien_height))
        # print(number_aliens_y)
        for alien_number in range(number_aliens_y):
            alien = Alien(self)
            alien.y = alien_height + 2 * alien_height * alien_number
            alien.rect.y = alien.y
            self.aliens.add(alien)

    def run_game(self):
        while True:
            self._check_events()
            self.ship.update()
            self.bullets.update()
# wywalić pętle for z run_game!!! Run game ma byc czyste. Można zdefiniować nową metode np. self._update_bullets()
# i zdefnionować funkcję jako def _update_bullets(self), w którym damy poniższą petle. 
            for bullet in self.bullets.copy():
                if self.settings.Full_screen == 0:
                    if bullet.rect.right > 1200:
                        self.bullets.remove(bullet)
                elif self.settings.Full_screen == 1:
                    if bullet.rect.right > 2000:
                        self.bullets.remove(bullet)
            #print(len(self.bullets))
# zmienić obie wartości z hard coded, wtedy będzie można zrezygonwać z jednego ifa/elifa
            self._update_screen()

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        pygame.display.flip()

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self,event):
        if event.key == pygame.K_UP:
            self.ship.moving_up = True
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = True
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_ESCAPE:
            sys.exit()

    def _fire_bullet(self):
    #  new_bullet = Bullet(self)
    # self.bullets.add(new_bullet)
    # powyżej są nieograniczone poziski

        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _check_keyup_events(self, event):
        if event.key == pygame.K_UP:
            self.ship.moving_up = False
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = False
class AlienInvasion(object):
    """Overall class to manage game assets and behavior."""
    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))

        # Fullscreen mode
        # self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Alien Invasion")

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            # Watch for keyboard and mouse events.
            self._check_event()
            self.ship.update()
            self._update_bullets()
            self._update_screen()

    def _update_bullets(self):
        self.bullets.update()

        # Get rid of bullets that have disappeared.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        # print(len(self.bullets))

    def _check_event(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _check_keydown_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        # Make the most recently drawn screen visible.
        pygame.display.flip()
Example #47
0
class AlienInvasion():
	def __init__(self):
		pygame.init()
		self.setts=Settings()
		self.screen=pygame.display.set_mode(
			(0,0))#,pygame.FULLSCREEN)
		self.setts.screen_width=self.screen.get_rect().width
		self.setts.screen_height=self.screen.get_rect().height
		pygame.display.set_caption("Alien Invasion")
		self.play_button=Button(self,"Play")
		pygame.mixer.music.load('music/background_XX_intro.mp3')
		pygame.mixer.music.play(-1)
		self.sound_ship_attack=pygame.mixer.Sound('music/ship_attack.mp3')
		self.sound_ship_attack.set_volume(0.2)
		self.sound_level_success=pygame.mixer.Sound('music/new_level.mp3')
		self.sound_level_failure=pygame.mixer.Sound('music/failure_level.mp3')
		self.sound_level_failure.set_volume(0.6)
		self.sound_alien_ship=pygame.mixer.Sound('music/alien_ship_collision.mp3')
		self.sound_alien_ship.set_volume(0.3)
		self.stats=GameStats(self)
		self.sb=Scoreboard(self)
		self.ship=Ship(self)
		self.bull=pygame.sprite.Group()
		self.aliens=pygame.sprite.Group()
		self._create_fleet()
	def run_game(self):
		while True:
			self._check_events()
			if self.stats.game_active:
				self.ship.update()
				self._update_bullets()
				self._update_aliens()
			self._update_screen()
	def _check_events(self):
		"""Managing user mouse and keyboard"""
		for event in pygame.event.get():
			if event.type==pygame.QUIT:
				sys.exit()
			elif event.type==pygame.KEYDOWN:
				self._check_keydown_events(event)
			elif event.type==pygame.KEYUP:
				self._check_keyup_events(event)
			elif event.type==pygame.MOUSEBUTTONDOWN:
				mouse_pos=pygame.mouse.get_pos()
				self._check_play_button(mouse_pos)
	def _check_play_button(self,mouse_pos):
		if self.play_button.rect.collidepoint(mouse_pos) and not self.stats.game_active:
			self.stats.reset_stats()
			self.stats.game_active=True
			self.aliens.empty()
			self.bull.empty()
			self._create_fleet()
			self.ship.center_ship()
			pygame.mouse.set_visible(False)
			self.sb.prep_level()
			self.sb.prep_ships()

	def _check_keydown_events(self,event):
		if event.key==pygame.K_RIGHT:
			self.ship.moving_r=True
		if event.key==pygame.K_LEFT:
			self.ship.moving_l=True
		if event.key==pygame.K_q:
			self._write_record(self.stats.high_score)
			sys.exit()
		if event.key==pygame.K_SPACE and self.stats.game_active:
			self.sound_ship_attack.play()
			self._fire_bullet()
		if event.key==pygame.K_1:
			pygame.mixer.music.pause()
		if event.key==pygame.K_2:
			pygame.mixer.music.set_volume(pygame.mixer.music.get_volume()*0.5)
		if event.key==pygame.K_3:
			pygame.mixer.music.unpause()
			pygame.mixer.music.set_volume(1)
		if event.key==pygame.K_s:
			if self.stats.game_active:
				if self.stats.ships_left>0:
					self.stats.ships_left-=1
					self.sb.prep_ships()
			if self.stats.ships_left==0:
				self.stats.game_active=False
				self.sound_level_failure.play()
				self.stats.reset_stats()
				self.sb.prep_score()
				pygame.mouse.set_visible(True)
	def _check_keyup_events(self,event):
		if event.key==pygame.K_RIGHT:
			self.ship.moving_r=False
		if event.key==pygame.K_LEFT:
			self.ship.moving_l=False
	def _check_fleet_edges(self):
		for alien in self.aliens.sprites():
			if alien.check_edges():
				self._change_fleet_direction()
				break
	def _check_aliens_bottom(self):
		screen_rect=self.screen.get_rect()
		for alien in self.aliens.sprites():
			if alien.rect.bottom>=screen_rect.bottom:
				self._ship_hit()
				break
	def _change_fleet_direction(self):
		for alien in self.aliens.sprites():
			alien.rect.y+=self.setts.fleet_drop_speed
		self.setts.fleet_direction*=-1
	def _fire_bullet(self):
		"""Creating new bullet and including it into bullets' group"""
		if len(self.bull)<self.setts.bullets_allowed:
			new_bullet=Bullet(self)
			self.bull.add(new_bullet)
	def _update_bullets(self):
		"""Update position and remove irrelevant bullets"""
		self.bull.update()
		for b in self.bull.copy():
			if b.rect.bottom <=0:
				self.bull.remove(b)
		self._check_bullet_alien_collisions()
		#print(len(self.bull)) -debug
	def _check_bullet_alien_collisions(self):
		collisions=pygame.sprite.groupcollide(
			self.bull,self.aliens,True,True)
		if collisions:
			for al in collisions.values():
				self.stats.score+=self.setts.alien_points*len(al)
			self.sb.prep_score()
			self.sb.check_high_score()
		if not self.aliens:
			self.bull.empty()
			self.setts.increase_speed()
			self.sound_level_success.play()
			self.stats.level+=1
			self.sb.prep_level()
			self._create_fleet()
	def _update_aliens(self):
		self._check_fleet_edges()
		self.aliens.update()
		"""check alien-ship collision"""
		if pygame.sprite.spritecollideany(self.ship,self.aliens):
			self._ship_hit()
		self._check_aliens_bottom()
	def _ship_hit(self):
		if self.stats.ships_left > 0:
			self.stats.ships_left-=1
			self.sound_alien_ship.play()
			self.sb.prep_ships()
			self.aliens.empty()
			self.bull.empty()
			self._create_fleet()
			self.ship.center_ship()
			sleep(1)
		if self.stats.ships_left==0:
			self.stats.game_active=False
			self.sound_level_failure.play()
			self.stats.reset_stats()
			self.sb.prep_score()
			pygame.mouse.set_visible(True)
	def _create_fleet(self):
		new_alien=Alien(self)
		alien_width=new_alien.rect.width
		alien_height=new_alien.rect.height
		ship_height=self.ship.rect.height
		available_space_x=(self.setts.screen_width-
			(2*alien_width))
		available_space_y=(self.setts.screen_height-
			(3*alien_height)-ship_height)
		number_aliens_x=available_space_x//(2*alien_width)
		number_rows=available_space_y//(2*alien_height)
		for row in range(number_rows):
			for al in range(number_aliens_x):
				self._create_alian(al,row)
			
	def _create_alian(self,al_number,row_number):
		new_alien=Alien(self)
		alien_width=new_alien.rect.width
		new_alien.x=alien_width+alien_width*2*al_number
		new_alien.rect.x=new_alien.x
		new_alien.rect.y=(new_alien.rect.height+
			2*new_alien.rect.height*row_number)
		self.aliens.add(new_alien)
	def _write_record(self,record):
		filename=self.setts.record_filename
		f=open(filename,'w')
		json.dump(record,f)
		f.close()
	def _update_screen(self):	
		self.screen.fill(self.setts.bg_color)
		self.ship.blitme()
		for b in self.bull.sprites():
			b.draw_bullet()
		self.aliens.draw(self.screen)
		self.sb.show_score()
		if not self.stats.game_active:
			self.play_button.draw_button()
		pygame.display.flip()
Example #48
0
class AlienInvasion:
    """Overall class to manage games assets and behavior"""
    
    def __init__(self):
        """Intitalize the game, create game window, and create game resources"""
        pygame.init()
        self.settings = Settings()

        # Full screen instructions pg 245
        #self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) #If don't like full screen, delete
        #self.settings.screen_width = self.screen.get_rect().width   # If don't like full screen, delete
        #self.settings.screen_height = self.screen.get_rect().height # If don't like full screen, delete
        
        
        self.screen = pygame.display.set_mode(
                (self.settings.screen_width, self.settings.screen_height))           #Re enable if don't like full screen
        pygame.display.set_caption("Alien Invasion")

        # Instantiate game statistics and scoreboard
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        # Creates a ship, a bullet which is added to a bullets group, an alien,
            # which is added to an aliens group
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # Create Play button to activate game
        self.play_button = Button (self, "Play")

    def run_game(self):
        """Start the main loop for the game"""
        while True:
            self._check_events()

            # Run updates when game is active
            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
                
            self._update_screen()

    def _check_events(self):
        """Event Listener"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False        
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Start a game when player clicks Play button"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # Reset game settings
            self.settings.initialize_dynamic_settings()

            # Reset game stats
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            # Remove all remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            # Hide cursor while game is active
            pygame.mouse.set_visible(False)
            
    def _check_keydown_events(self, event):
        """Respond to key presses"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """Respond to key releases"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update the position of bullets and remove old bullets"""
        # Update bullet positions
        self.bullets.update()

        # Remove bullets that have disappeared
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions"""
        # Remove any bullets and aliens that have collided
        collisions = pygame.sprite.groupcollide(
                self.bullets, self.aliens, True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        # If current fleet empty, destroy current bullets and create new fleet
            # to continue play after all aliens shot
        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            # Increase level
            self.stats.level += 1
            self.sb.prep_level()

    def _update_aliens(self):
        """Check if alien is at edge, update all alien positions"""
        self._check_fleet_edges()
        self.aliens.update()

        # Check for alien-ship collisions
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Check for aliens reaching the bottom of the screen
        self._check_aliens_bottom()

    def _ship_hit(self):
        """Respond to ship being hit by an alien"""
        if self.stats.ships_left > 0:
        
            # Decrement ships_left and update scoreboard
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            # Remove all remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            # Pause following collision
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        """Check if any aliens reach bottom of screen"""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Respond same as ship getting hit by an alien
                self._ship_hit()
                break

    def _create_fleet(self):
        """Create a fleet of aliens"""
        # Make an alien and find the number of aliens that will fit in a row
        # Spacing between aliens is equal to one alien width
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine number of rows of aliens that fit on the screen
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - 
            (3 * alien_height) - ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create a full fleet of aliens (multiple rows)
        for row_number in range(number_rows):
            # Crete a row of aliens
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """Helper method to create an alien and place it in the row"""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """Moves fleet if window edges are met"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drops fleet and changes fleet direction"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """Update images on the screen and flip to a new screen"""
        # Redraw the screen during each pass through the loop
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        # Draw the score information
        self.sb.show_score()

        # Draw the play button if the game is inactive
        if not self.stats.game_active:
            self.play_button.draw_button()   

        # Make the most recently drawn screen visible
        pygame.display.flip()
Example #49
0
class AlienInvasion(object):
    """
    Класс для управления ресурсами и поведением игры.
    """
    def __init__(self):
        """Инициализирует игру и создает игровые ресурсы."""
        pygame.init()
        pygame.display.set_caption('Alien Invasion')

        self.settings = Settings()

        self.background_color = self.settings.background_color

        if self.settings.fullscreen:
            self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)

        else:
            self.screen = pygame.display.set_mode(
                (self.settings.screen_width, self.settings.screen_height))

        self.stats = GameStats(self)
        self.score = ScoreBoard(self)
        self.play_button = PlayButton(self, 'Play')

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.mega_bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

    def _check_events(self):
        """Обрабатывает нажатия клавиш и события мыши."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

            elif event.type == pygame.MOUSEBUTTONDOWN:
                self._check_play_button(pygame.mouse.get_pos())

    def _check_keydown_events(self, event):

        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True

        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True

        elif event.key == pygame.K_q or event.key == pygame.K_ESCAPE:
            sys.exit()

        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

        elif event.key == pygame.K_z:
            self._fire_mega_bullet()

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _check_play_button(self, position):
        """Запускает новую игру при нажатии кнопки Play."""
        if self.play_button.rect.collidepoint(
                position) and not self.stats.game_active:
            self.stats.reset_stats()
            self.settings.init_dynamic_settings()
            self.stats.game_active = True

            self.score.prep_score()
            self.score.prep_level()
            self.score.prep_ships()

            self.aliens.empty()
            self.bullets.empty()

            self._create_fleet()
            self.ship.center_ship()

            pygame.mouse.set_visible(False)

    def _check_bullet_alien_collisions(self):

        # Проверка попаданий в пришельцев.
        collisions = pygame.sprite.groupcollide(
            self.bullets,
            self.aliens,
            True,
            True,
        )

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.score.prep_score()
            self.score.check_high_score()

        self._using_mega_bullets()

        if not self.aliens:
            self.bullets.empty()
            self.mega_bullets.empty()
            self._create_fleet()

            self.settings.increase_speed()
            self.stats.level += 1
            self.score.prep_level()

    def _check_fleet_edges(self):
        """Реагирует на достижение пришельцем края экрана."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _check_aliens_bottom(self):
        """Проверяет, добрались ли пришельцы до нижнего края экрана."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                self._ship_hit()
                break

    def _update_bullets(self):
        """Обновляет позиции снарядов."""
        self.bullets.update()

        # Удаление снарядов, вышедших за край экрана.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _update_aliens(self):
        """Обновляет позиции всех пришельцев во флоте."""
        self._check_fleet_edges()
        self.aliens.update()

        # Проверка коллизий "пришелец — корабль".
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        self._check_aliens_bottom()

    def _update_screen(self):
        """Обновляет изображения на экране и отображает новый экран."""
        self.screen.fill(self.background_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        for mega_bullet in self.mega_bullets.sprites():
            mega_bullet.draw_bullet()
        self.aliens.draw(self.screen)

        # Вывод информации о счете.
        self.score.show_score()

        if not self.stats.game_active:
            self.play_button.draw_button()

        pygame.display.flip()

    def _fire_bullet(self):
        """Создание нового снаряда и включение его в группу bullets."""
        if len(self.bullets) < self.settings.max_bullets:
            self.bullets.add(Bullet(self))

    def _fire_mega_bullet(self):
        self.mega_bullets.add(MegaBullet(self))

    def _create_alien(self, alien_number, row_number):
        """Создание пришельца и размещение его в ряду."""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _create_fleet(self):
        """Создание флота вторжения."""
        # Создание одного пришельца, не включенного во флот,
        # для расчета максимального количествыа пришельцев в ряду
        # TODO: оптипизировать
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_of_aliens_x = available_space_x // (2 * alien_width)
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             self.ship.rect.height)
        number_of_rows_y = available_space_y // (2 * alien_height)

        # Создание флота пришельцев.
        for row_number in range(number_of_rows_y):
            for alien_number in range(number_of_aliens_x):
                self._create_alien(alien_number, row_number)

    def _change_fleet_direction(self):
        """Опускает весь флот и меняет направление флота."""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_speed
        self.settings.fleet_direction *= -1

    def _using_mega_bullets(self):
        # Обработка читерских пуль
        self.mega_bullets.update()

        for mega_bullet in self.mega_bullets.copy():
            if mega_bullet.rect.bottom <= 0:
                self.mega_bullets.remove(mega_bullet)

        pygame.sprite.groupcollide(
            self.mega_bullets,
            self.aliens,
            False,
            True,
        )

    def _ship_hit(self):
        """Обрабатывает столкновение корабля с пришельцем."""
        self.stats.ships_left -= 1
        self.score.prep_ships()
        if self.stats.ships_left > 0:

            self.aliens.empty()
            self.bullets.empty()

            self._create_fleet()
            self.ship.center_ship()

            time.sleep(2)

        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def run_game(self):
        """Запуск основного цикла игры."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()
Example #50
0
def update_screen(ai_settings: Settings, screen, ship: Ship):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()
    def __init__(self):
        """Initialization of game, and game resources."""

        pygame.init(
        )  # Background settings needed for Pygame to work properly.
        self.settings = Settings(
        )  # Settings instance. Initialization of Settings' arguments in AlienInvasion class.

        # self.song_file = "YOUR_CHOICE.wav"    # Addition of background music.
        # pygame.mixer.music.load(self.song_file)
        # pygame.mixer.music.play(-1)

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height
             ))  # Create display window (surface), to display game elements.
        pygame.display.set_caption(
            "Emoji Invasion")  # Surface is updated after each loop.

        self.stats = GameStats(self)  # GameStats instance.
        self.sb = ScoreBoard(self)  # ScoreBoard instance.

        # Prepare welcoming page with user input. ---> pygame_functions.py
        screenSize(self.settings.screen_width,
                   self.settings.screen_height)  # Create welcoming page.
        newcloud = make_cloud(
            self.settings.cloud, self.settings.screen_width,
            self.settings.screen_height,
            self.settings.clouds_total)  # Create clouds on welcoming page.

        today = date.today()  # Prepate current date for welcoming page.
        year = today.year
        month = today.month
        day = today.day
        self.full_date = f"{day}/{month}/{year}"
        local_time = makeLabel(self.full_date, 30, 50, 20, "black",
                               "comicsans")
        showLabel(local_time)

        welcome_label = makeLabel("Welcome to Emoji Invasion!", 70,
                                  (self.settings.screen_width / 2),
                                  (self.settings.screen_height / 4), "black",
                                  "comicsans")
        showLabel(welcome_label)  # Show welcoming message.

        instruction_label = makeLabel("Please, enter your name:", 40,
                                      (self.settings.screen_width / 2),
                                      (self.settings.screen_height / 2) - 20,
                                      "black", "comicsans")
        showLabel(instruction_label)  # Show instructions.

        word_box = makeTextBox(self.settings.screen_width / 2,
                               self.settings.screen_height / 2 + 20, 200, 0,
                               "...", 0, 30)
        showTextBox(word_box)  # Ask user for username.
        self.entry = textBoxInput(word_box)  # Save user input.

        self.buttons = Button(self)  # Button instance.
        self.buttons.prep_menu_msgs("Select game difficulty:",
                                    f"Good luck, {self.entry}! :)")
        self.buttons.prep_difficulty_level_msgs("Easy", "Normal", "Hard")
        # self.buttons.prep_ib_msg("Info")

        self.ship = Ship(
            self
        )  # Ship instance. Self gives access Ship to AlienInvasion's resources.
        self.po = Powers(self)  # Power instance.
        self.clouds = pygame.sprite.Group(
        )  # Sprite for clouds. Draws clouds on screen.
        self.bullets = pygame.sprite.Group(
        )  # Sprite for bullets. Draws and uupdates at each pass through of main loop.
        self.enemy_bullets = pygame.sprite.Group(
        )  # Sprite for 2nd line of aliens.
        self.aliens = pygame.sprite.Group()  # Spire for 1st line of aliens.

        self._create_fleet_of_enemy_bullet(
        )  # Helper method to create a fleet of 2nd line aliens.
        self._create_fleet(
        )  # Helper method to create a fleet of 1st line aliens.
        self._create_cloud()  # Helper method to create a group of clouds.
class AlienInvasion:
    def __init__(self):
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
        self.settings.screen_height = self.screen.get_rect().height
        self.settings.screen_width = self.screen.get_rect().width
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()
        self._create_fleet()

    def _create_fleet(self):
        alien = Alien(self)
        alien_width = alien.rect.width
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)
        for alien_number in range(number_aliens_x):
            alien = Alien(self)
            alien.x = alien_width + 2 * alien_width * alien_number
            alien.rect.x = alien.x
            self.aliens.add(alien)

    def run_game(self):
        while True:
            self._check_events()
            self.ship.update()
            self._update_bullets()
            self._update_screen()

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self,event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        if event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self,event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        if event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        self.bullets.update()
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)
        pygame.display.flip()
class AlienInvasion:
    """Main class controlling game assets"""
    def __init__(self):
        """Initialization of game, and game resources."""

        pygame.init(
        )  # Background settings needed for Pygame to work properly.
        self.settings = Settings(
        )  # Settings instance. Initialization of Settings' arguments in AlienInvasion class.

        # self.song_file = "YOUR_CHOICE.wav"    # Addition of background music.
        # pygame.mixer.music.load(self.song_file)
        # pygame.mixer.music.play(-1)

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height
             ))  # Create display window (surface), to display game elements.
        pygame.display.set_caption(
            "Emoji Invasion")  # Surface is updated after each loop.

        self.stats = GameStats(self)  # GameStats instance.
        self.sb = ScoreBoard(self)  # ScoreBoard instance.

        # Prepare welcoming page with user input. ---> pygame_functions.py
        screenSize(self.settings.screen_width,
                   self.settings.screen_height)  # Create welcoming page.
        newcloud = make_cloud(
            self.settings.cloud, self.settings.screen_width,
            self.settings.screen_height,
            self.settings.clouds_total)  # Create clouds on welcoming page.

        today = date.today()  # Prepate current date for welcoming page.
        year = today.year
        month = today.month
        day = today.day
        self.full_date = f"{day}/{month}/{year}"
        local_time = makeLabel(self.full_date, 30, 50, 20, "black",
                               "comicsans")
        showLabel(local_time)

        welcome_label = makeLabel("Welcome to Emoji Invasion!", 70,
                                  (self.settings.screen_width / 2),
                                  (self.settings.screen_height / 4), "black",
                                  "comicsans")
        showLabel(welcome_label)  # Show welcoming message.

        instruction_label = makeLabel("Please, enter your name:", 40,
                                      (self.settings.screen_width / 2),
                                      (self.settings.screen_height / 2) - 20,
                                      "black", "comicsans")
        showLabel(instruction_label)  # Show instructions.

        word_box = makeTextBox(self.settings.screen_width / 2,
                               self.settings.screen_height / 2 + 20, 200, 0,
                               "...", 0, 30)
        showTextBox(word_box)  # Ask user for username.
        self.entry = textBoxInput(word_box)  # Save user input.

        self.buttons = Button(self)  # Button instance.
        self.buttons.prep_menu_msgs("Select game difficulty:",
                                    f"Good luck, {self.entry}! :)")
        self.buttons.prep_difficulty_level_msgs("Easy", "Normal", "Hard")
        # self.buttons.prep_ib_msg("Info")

        self.ship = Ship(
            self
        )  # Ship instance. Self gives access Ship to AlienInvasion's resources.
        self.po = Powers(self)  # Power instance.
        self.clouds = pygame.sprite.Group(
        )  # Sprite for clouds. Draws clouds on screen.
        self.bullets = pygame.sprite.Group(
        )  # Sprite for bullets. Draws and uupdates at each pass through of main loop.
        self.enemy_bullets = pygame.sprite.Group(
        )  # Sprite for 2nd line of aliens.
        self.aliens = pygame.sprite.Group()  # Spire for 1st line of aliens.

        self._create_fleet_of_enemy_bullet(
        )  # Helper method to create a fleet of 2nd line aliens.
        self._create_fleet(
        )  # Helper method to create a fleet of 1st line aliens.
        self._create_cloud()  # Helper method to create a group of clouds.

    def run_game(self):
        """Game's main loop. It controls the game."""

        FPS = 60  # Frame Per Second (FPS).
        clock = pygame.time.Clock(
        )  # Check events, then update main loop FPS times per second.

        while True:  # Main loop. Screen, event management and update.

            clock.tick(FPS)  # Consistancy of main loop.

            self._check_events(
            )  # Check events. Always, even if game is inactive.

            if self.stats.game_active:  # Flag controlling game activity (on/off).

                self.ship.update()  # Update ship.
                self._update_bullets()  # Update bullets.
                self._update_aliens()  # Update aliens (1st and 2nd line).

                if self.po.status:  # If power-up status is active, update power-ups.
                    self._update_po()

            self._update_screens(
            )  # Whether game is active or not, update screen.
            self._save_high_score(
            )  # Save to external file current highscore values.

    def _check_events(self):
        """Method responding to keypresses and mouse events."""

        for event in pygame.event.get(
        ):  # Check keyboard and mouse events to detect movements (list).

            if event.type == pygame.QUIT:  # End game by clicking game window's
                sys.exit()  # close button.

            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos(
                )  # Return cursor's x-, y-coordinates when mouse clicked.
                self._check_buttons(
                    mouse_pos
                )  # Send mouse position to _check_buttons helper method.
                if self.sb.power_type == 4:  # If powe type is 4, check what power type user selected.
                    self._check_power_up_buttons(mouse_pos)

            elif event.type == pygame.KEYDOWN:  # Keys are down.
                self._check_keydown_events(event)  # Check executed movement.

            elif event.type == pygame.KEYUP:  # Keys are up.
                self._check_keyup_events(event)  # Check released key.

    def _check_buttons(self, mouse_pos):
        """Start new game when player selects one of the difficulty levels."""

        elpb_button_clicked = self.buttons.elpb_rect.collidepoint(mouse_pos)
        if elpb_button_clicked and not self.stats.game_active:  # If easy level and game inactive.
            self.settings.initialize_easy_level_settings(
            )  # Initialize starting parameters.
            self._start_game()  # Start game.

        nlpb_button_clicked = self.buttons.nlpb_rect.collidepoint(mouse_pos)
        if nlpb_button_clicked and not self.stats.game_active:
            self.settings.initialize_normal_level_settings()
            self._start_game()

        hlpb_button_clicked = self.buttons.hlpb_rect.collidepoint(mouse_pos)
        if hlpb_button_clicked and not self.stats.game_active:
            self.settings.initialize_hard_level_settings()
            self._start_game()

    def _check_keydown_events(self, event):
        """Respond to keypresses."""

        if event.key == pygame.K_RIGHT:  # Right arrow.
            self.ship.moving_right = True  # Flag activating movmebet to the rigth.

        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True

        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = True

        elif event.key == pygame.K_UP:
            self.ship.moving_up = True

        elif event.key == pygame.K_q:  # Key Q.
            sys.exit()  # Exit game.

        elif event.key == pygame.K_SPACE:  # Key space.
            self.ship.firing = True  # Fire bullet.

        elif event.key == pygame.K_p:  # Key P.
            self.pause = True  # Pause flag acitvated.
            pygame.mouse.set_visible(True)
            if self.stats.game_active:  # Only if game is active.
                self._paused()  # Execute helper method, that pauses game.

        elif event.key == pygame.K_c:  # Key C.
            if self.stats.game_active:
                self.pause = False  # Pause flag inactive. Game continues.
                pygame.mouse.set_visible(False)  # Set mouse cursor invisible.

        elif event.key == pygame.K_m:  # Key M.
            if self.stats.game_active:
                self.pause = False  # Pause flag inactive. Game continues.
                self._return_menu()  # Return to game menu.

    def _paused(self):
        """A simple way to pause the game."""

        while self.pause:  # While paused, check events (Continue/return Menu/Quit).
            self._check_events(
            )  # Check events. Especially kepress events (C/M/Q).

            self.screen.fill(
                self.settings.bg_color)  # Fill screen with default background.
            self.clouds.draw(self.screen)  # Fill screen with clouds.

            self.buttons.prep_pause_menu_msgs(
                "Pause", "Press C to continue.", "Press M to menu.",
                "Press Q to quit.")  # Prepare pause menu messages.
            self.buttons.draw_pause_msgs()  # Draw pause messages.

            pygame.display.flip()  # Display latest screen settings.

    def _check_keyup_events(self, event):
        """Respond to kreypresses."""

        if event.key == pygame.K_RIGHT:  # If right key released.
            self.ship.moving_right = False  # Set it to False.

        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = False

        elif event.key == pygame.K_UP:
            self.ship.moving_up = False

        elif event.key == pygame.K_SPACE:  # If space key released.
            self.ship.firing = False  # Stop firing.

    def _start_game(self):
        """A simple method to start/restart a game."""

        if not self.stats.game_active:  # If game is incative.

            if self.settings.dif_level == "Easy":  # Reset game statiistics, scores, and level.
                self.stats.reset_el_stats()
                self.stats.game_active = True  # Activate game (main while loop).
                self.sb.prep_el_score()
                self.sb.prep_el_level()

            if self.settings.dif_level == "Normal":
                self.stats.reset_nl_stats()
                self.stats.game_active = True
                self.sb.prep_nl_score()
                self.sb.prep_nl_level()

            if self.settings.dif_level == "Hard":
                self.stats.reset_hl_stats()
                self.stats.game_active = True
                self.sb.prep_hl_score()
                self.sb.prep_hl_level()

            self.sb.prep_ships()  # After selecting level prepare life.
            self._reset_screen(
            )  # Reset screen settings (aliens, player, clouds, etc.).

            pygame.mouse.set_visible(False)  # Hide mouse cursor.

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""

        self._cooldown_ship()  # Method controlling frequency of bullets.

        if len(
                self.bullets
        ) < self.settings.bullets_allowed and self.ship.firing:  # If limitation is respected and space key is hit.

            if self.ship.cooldown_counter == 0:  # If cooldown is 0.
                new_bullet = Bullet(self, None)  # Create Bullet instance.
                self.bullets.add(
                    new_bullet)  # Add new bullet to the sprite group.

                if self.sb.power_type == 1:  # If collision with power up is 1, then:
                    new_bullet_r = Bullet(
                        self,
                        1)  # Create new bullet on the rigth side of player.
                    self.bullets.add(new_bullet_r)
                    new_bullet_l = Bullet(
                        self,
                        -1)  # Create new bullet on the left side of player.
                    self.bullets.add(new_bullet_l)

            self.ship.cooldown_counter += 1  # Increment cooldown counter.
            # print(self.ship.cooldown_counter) # To check if ouur trick works.

    def _cooldown_ship(self):
        """A simple method to regulate shooting frequency."""
        if self.ship.cooldown_counter >= self.settings.COOLDOWN_SHIP:  # If couunter is bigger than contstant.
            self.ship.cooldown_counter = 0  # Reset counter to be 0 and start creating new bullets.

    def _cooldown_power(self):
        """A simple method to regulate power-up frequency."""
        if self.po.cooldown_counter >= self.settings.COOLDOWN_POWER:  # Same as for _cooldown_ship().
            self.po.cooldown_counter = 0

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""

        self._fire_bullet()  # Check if bullets were fired.
        self.bullets.update()  # Update bullet sprite.

        for bullet in self.bullets.copy(
        ):  # Get rid of bullets when they hit screen edges.
            if bullet.rect.top <= 0:  # We can't remove items from a list or group within
                self.bullets.remove(
                    bullet)  # a for loop ---> must make a copy.
            elif bullet.rect.bottom >= self.settings.screen_height:
                self.bullets.remove(bullet)
            elif bullet.rect.left <= 0:
                self.bullets.remove(bullet)
            elif bullet.rect.right >= self.settings.screen_width:
                self.bullets.remove(bullet)
        # print(len(self.bullets))      # To check if bullets were removed.

        self._check_bullet_alien_collisions(
        )  # Check bullet-alien (1st and 2nd line) collisions.

    def _check_bullet_alien_collisions(self):
        """Respond to bullet-alien collisions."""

        if self.settings.dif_level == "Easy":  # Easy level.
            self._check_bullet_alien_collisions_easy_level()

        if self.settings.dif_level == "Normal":  # Normal level.
            self._check_bullet_alien_collisions_normal_level()

        if self.settings.dif_level == "Hard":  # Hard level.
            self._check_bullet_alien_collisions_hard_level()

        if not self.aliens and not self.enemy_bullets:  # If no more enemies left,
            self._start_new_level()  # start new level.

    def _check_bullet_alien_collisions_easy_level(self):
        """If easy level selected, check collisions between bullets and aliens."""

        collision_b_a = pygame.sprite.groupcollide(
            self.bullets, self.aliens, True,
            True)  # Pygame returns a collision dictionary.
        collision_b_eb = pygame.sprite.groupcollide(self.bullets,
                                                    self.enemy_bullets, True,
                                                    True)

        if collision_b_a:  # Check if collision dictionary exists.
            for aliens in collision_b_a.values(
            ):  # Add scoring point for each collided alien.
                self.stats.score += self.settings.a_point * \
                    len(aliens)
            self.sb.prep_el_score(
            )  # Create new image with updated score value.
            self.sb.check_el_high_score(
            )  # Comprare current score with registered highscore.

        if collision_b_eb:
            for enemy_bullets in collision_b_eb.values():
                self.stats.score += self.settings.eb_point * \
                    len(enemy_bullets)
                for enemy_bullet in self.enemy_bullets.sprites(
                ):  # For aliens in 2nd line, create a power-
                    if enemy_bullet.bonus and self.po.cooldown_counter == 0:  # up if conditions are met.
                        pos = enemy_bullet.rect  # Assign position of power-up to random alien (sprites are not in order).
                        self.po.status = True  # Activate power-up status.
                        self.po.generate_rand_pow(pos)  # Generate power-up.
            self.po.cooldown_counter += 1  # Increment cooldown-counter.
            self._cooldown_power()  # Check cooldown counter.
            self.sb.prep_el_score()
            self.sb.check_el_high_score()

    def _check_bullet_alien_collisions_normal_level(self):
        """If normal level selected, check collisions between bullets and aliens."""

        collision_b_a = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                   True, True)

        collision_b_eb = pygame.sprite.groupcollide(self.bullets,
                                                    self.enemy_bullets, True,
                                                    True)

        if collision_b_a:
            for aliens in collision_b_a.values():
                self.stats.score += self.settings.a_point * \
                    len(aliens)
            self.sb.prep_nl_score()
            self.sb.check_nl_high_score()

        if collision_b_eb:
            for enemy_bullets in collision_b_eb.values():
                self.stats.score += self.settings.eb_point * \
                    len(enemy_bullets)
                for enemy_bullet in self.enemy_bullets.sprites():
                    if enemy_bullet.bonus and self.po.cooldown_counter == 0:
                        pos = enemy_bullet.rect
                        self.po.status = True
                        self.po.generate_rand_pow(pos)
            self.po.cooldown_counter += 1
            self._cooldown_power()
            self.sb.prep_nl_score()
            self.sb.check_nl_high_score()

    def _check_bullet_alien_collisions_hard_level(self):
        """If hard level selected, check collisions between bullets and aliens."""

        collision_b_a = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                   True, True)
        collision_b_eb = pygame.sprite.groupcollide(self.bullets,
                                                    self.enemy_bullets, True,
                                                    True)

        if collision_b_a:
            for aliens in collision_b_a.values():
                self.stats.score += self.settings.a_point * \
                    len(aliens)
            self.sb.prep_hl_score()
            self.sb.check_hl_high_score()

        if collision_b_eb:
            for enemy_bullets in collision_b_eb.values():
                self.stats.score += self.settings.eb_point * \
                    len(enemy_bullets)
                for enemy_bullet in self.enemy_bullets.sprites():
                    if enemy_bullet.bonus and self.po.cooldown_counter == 0:
                        pos = enemy_bullet.rect
                        self.po.status = True
                        self.po.generate_rand_pow(pos)
            self.po.cooldown_counter += 1
            # print(self.po.cooldown_counter)   # To check power-up generation cooldown counter.
            self._cooldown_power()
            self.sb.prep_hl_score()
            self.sb.check_hl_high_score()

    def _update_po(self):
        """A simple method to uupdate power-ups."""

        self._check_po_ship_collision()  # Check poper-up - ship collision.
        self.po.update()  # Update vertical position of falling power-up.

    def _check_po_ship_collision(self):
        """A simple method to check collision between power-ups adn ship."""

        if pygame.Rect.colliderect(self.po.rect,
                                   self.ship.rect):  # Chcek collission.
            self.sb.power_type = self.po.pow  # Recognize power-up type.

            if self.sb.power_type == 1:  # If 1, fire triple bullets.
                self._fire_bullet()

            if self.sb.power_type == 2:
                self.settings.count_pause = 0  # Reset to zero if 2 consecutive freeze.
                self._update_aliens()

            if self.sb.power_type == 3:  # If 3, increase ship's life.
                self.stats.ships_left += 1
                self.sb.prep_ships()

            if self.sb.power_type == 4:  # If 4, get lucky box.
                self.lucky_box = True
                self._lucky_box()

            self.po.status = False  # Stop creation of powerups.

    def _lucky_box(self):
        """A simple method for choosing a power-up."""

        while self.lucky_box:
            self._check_events()
            self.screen.fill(self.settings.bg_color)
            self.clouds.draw(self.screen)

            self.buttons.prep_lucky_box(
                "Select a power-up:")  # Prepare contents of lucky box.
            self.buttons.draw_lucky_box()  # Draw power-ups.

            pygame.display.flip()
            pygame.mouse.set_visible(True)
        pygame.mouse.set_visible(False)

    def _check_power_up_buttons(self, mouse_pos):
        """A simple method to select power-ups in lucky box."""

        ac_button_clicked = self.buttons.acpb_rect.collidepoint(
            mouse_pos)  # Select alarm clock.
        if ac_button_clicked:  # If clicked on alarm clock.
            self.sb.power_type = 1  # Power type is 1.
            self.lucky_box = False  # Exit lucky box.

        hv_button_clicked = self.buttons.hvpb_rect.collidepoint(mouse_pos)
        if hv_button_clicked:
            self.sb.power_type = 2
            self.settings.count_pause = 0
            self.lucky_box = False

        exl_button_clicked = self.buttons.exlpb_rect.collidepoint(mouse_pos)
        if exl_button_clicked:
            self.sb.power_type = 3
            self.stats.ships_left += 1
            self.sb.prep_ships()
            self.lucky_box = False

    def _start_new_level(self):
        """Start new level alien fleets are destroyed."""

        self._reset_screen()  # Reset screen settings.
        self.settings.increase_speed()  # Increase game speed.

        if self.settings.dif_level == "Easy":  # Initialize easy level.
            self.stats.level += 1  # Increase level statistics.
            self.sb.prep_el_level()  # Draw new level statisctics.

        if self.settings.dif_level == "Normal":
            self.stats.level += 1
            self.sb.prep_nl_level()

        if self.settings.dif_level == "Hard":
            self.stats.level += 1
            self.sb.prep_hl_level()

        sleep(1.0)  # Pause game for a second.

    def _create_fleet(self):
        """Create alien fleet (1st row)."""

        alien = Alien(self)  # Alien instamce.
        alien_width, alien_height = alien.rect.size  # Get rect size.

        space_x = alien.rect.x / self.settings.alien_adjustment  # Indent of 1st alien.
        available_space_x = self.settings.screen_width - \
            (2 * space_x + alien_width)     # Available space in x-direction.
        number_aliens_x = int(
            available_space_x //
            (2 * space_x +
             alien_width))  # Number of aliens that fits along x-direction.

        ship_height = self.ship.rect.height  # Get ship's image height.
        space_y = alien.rect.y / self.settings.alien_adjustment  # Indent from y-direction.
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)  # Available space along y-direction.
        number_rows = int(
            available_space_y //
            (space_y +
             alien_height))  # Number of aliens tthat fits along y-direction.

        for row_number in range(number_rows):  # Create alien fleet (1st line).
            for alien_number in range(
                    number_aliens_x):  # Loop through x-direction.
                self._create_alien(
                    alien_number,
                    row_number)  # Loop through along y-direction.
        # print(f"How many aliens? {len(self.aliens)}")     # Check how many aliens been created.

    def _create_alien(self, alien_number, row_number):
        """Create an alien and place it in the row."""

        alien = Alien(self)
        alien_width, alien_height = alien.rect.size

        space_x = alien.rect.x / self.settings.alien_adjustment
        alien.x = (space_x + (1.5 * space_x + alien_width) * alien_number)
        alien.rect.x = alien.x

        space_y = alien.rect.y / self.settings.alien_adjustment
        alien.y = 4 * space_y + (space_y + alien_height) * row_number
        alien.rect.y = alien.y
        self.aliens.add(alien)  # Add created alien to aliens sprite.

    def _create_fleet_of_enemy_bullet(self):
        """Create alien fleet (2nd line). Same method as befor"""

        enemy_bullet = EnemyBullet(self)
        enemy_bullet_width, enemy_bullet_height = enemy_bullet.rect.size

        space_x = enemy_bullet.rect.x / self.settings.alien_adjustment
        available_space_x = self.settings.screen_width - \
            (2 * space_x + enemy_bullet_width)
        number_enemy_bullet_x = int(available_space_x //
                                    (2 * space_x + enemy_bullet_width))

        ship_height = self.ship.rect.height
        space_y = enemy_bullet.rect.y / self.settings.alien_adjustment
        available_space_y = (self.settings.screen_height -
                             (3 * enemy_bullet_height) - ship_height)
        number_rows = int(available_space_y // (space_y + enemy_bullet_height))

        num1 = random.randint(0, number_rows -
                              1)  # Generate random number for power up.
        num2 = random.randint(0, number_enemy_bullet_x -
                              1)  # Generate random number for power up.

        for row_number in range(number_rows):
            for number_enemy_bullet in range(number_enemy_bullet_x):
                self._create_enemy_bullet(number_enemy_bullet, row_number,
                                          num1, num2)

    def _create_enemy_bullet(self, number_enemy_bullet, row_number, num1,
                             num2):
        """Create an enemy bullet and place it in the row."""

        enemy_bullet = EnemyBullet(self)
        enemy_bullet_width, enemy_bullet_height = enemy_bullet.rect.size
        if row_number == num1 and number_enemy_bullet == num2:  # If randomly generated numbers match, create power-up.
            enemy_bullet.bonus = True
            # print(f"Selected power up position (row:column): {num1}:{num2}")  # Check position of power-up.

        space_x = enemy_bullet.rect.x / self.settings.alien_adjustment
        enemy_bullet.x = (
            space_x +
            (1.5 * space_x + enemy_bullet_width) * number_enemy_bullet)
        enemy_bullet.rect.x = enemy_bullet.x

        space_y = enemy_bullet.rect.y / self.settings.alien_adjustment
        enemy_bullet.y = 4 * space_y + \
            (space_y + enemy_bullet_height) * row_number
        enemy_bullet.rect.y = enemy_bullet.y
        self.enemy_bullets.add(enemy_bullet)

    def _check_fleet_edges(self):
        """Respond appropriately if 1st line alien hits an edge."""

        for alien in self.aliens.sprites(
        ):  # Check all alien in the aliens sprite.
            if alien.check_edges(
            ):  # If hits edge change direction (1st and 2nd line).
                self._change_fleet_direction()
                self._change_enemy_bullets_fleet_direction()
                break  # Break out from loop.
            elif not alien.check_edges(
            ):  # If 1st line does not hit edge, but not empty, check 2nd line.
                self._check_enemy_bullets_edges()
                break

        if not self.aliens:  # If 1st line aliens empty, check only 2nd line.
            self._check_enemy_bullets_edges()

    def _check_enemy_bullets_edges(self):
        """Respond appropriately 2nd line alien hits an edge."""

        for enemy_bullet in self.enemy_bullets.sprites():
            if enemy_bullet.check_edges():
                self._change_enemy_bullets_fleet_direction()
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""

        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _change_enemy_bullets_fleet_direction(self):

        for enemy_bullet in self.enemy_bullets.sprites():
            enemy_bullet.rect.y += self.settings.fleet_drop_speed
        self.settings.enemy_bullet_direction *= -1

    def _update_aliens(self):
        """A simple method containing all movement for aliens."""

        if self.sb.power_type == 2 and self.settings.count_pause <= 160:  # Freeze aliens.
            self.settings.count_pause += 1
            # print(f"Time until freeze stops: {self.settings.count_pause}")    # For verification.

        else:
            self._check_fleet_edges(
            )  # Chech collision between aliens and edges.
            self.aliens.update()  # Update each alien in aliens sprite.
            self.enemy_bullets.update(
            )  # Update each alien in enemy_bullets sprite.
            self._check_aliens_bottom()  # Collision 1st line aliens - bottom.
            self._check_enemy_bullets_bottom(
            )  # Collision 2nd line aliens - bottom.

            if pygame.sprite.spritecollideany(
                    self.ship, self.aliens
            ):  # Check alien-ship collision. Returns None, if no collision
                self._ship_hit()  # Arguments: sprite & group (all members).
            if pygame.sprite.spritecollideany(self.ship, self.enemy_bullets):
                self._ship_hit()

    def _check_enemy_bullets_bottom(self):
        screen_rect = self.screen.get_rect()
        for enemy_bullet in self.enemy_bullets.sprites():
            if enemy_bullet.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()
                break

    def _check_aliens_bottom(self):
        """Check if an alien have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()
                break

    def _ship_hit(self):
        """Respond to the ship being hit by an alien."""

        if self.stats.ships_left > 1:  # If life not empty.
            self.stats.ships_left -= 1  # Decrement ships left.
            self.sb.prep_ships()  # Update scoreboard.
            self._reset_screen()  # Reset screen contents.
            sleep(1.0)
        else:
            self._return_menu()  # If no more ship left, open menu.

    def _return_menu(self):
        """If more life left, reinitialize the screen."""

        self.stats.game_active = False  # Set game incactive.
        self.sb.ships.empty()  # Get rid of ships.
        self._reset_screen()
        pygame.mouse.set_visible(True)

    def _reset_screen(self):
        """When game ends, reset screen."""

        self.clouds.empty()  # Get rid of clouds.
        self.aliens.empty()  # Get rid of 1st line aliens
        self.enemy_bullets.empty()  # Get rid of 2nd line aliens
        self.bullets.empty()  # Get rid of bullets.

        self.po.status = False  # Reset power-up status (off).
        self.sb.power_type = 0  # Reset power type (off).
        self.settings.count_pause = 0  # Reset count_pause.

        self._create_cloud()  # Generate new sprite group of clouds.
        self._create_fleet_of_enemy_bullet()  # Generate new 2nd line aliens.
        self._create_fleet()  # Generate new 1st line aliens
        self.settings.enemy_bullet_direction = abs(
            self.settings.enemy_bullet_direction
        )  # Make sure  2nd line aliens go to the rigth.
        self.settings.fleet_direction = abs(
            self.settings.fleet_direction
        )  # Make sure  1st line aliens go to the rigth.
        self.ship.center_ship()  # Re-center ship's position.

    def _create_cloud(self):
        """Create clouds in random position (x, y)."""

        number_clouds = int(
            self.settings.clouds_total)  # Make sure it's an integer.
        for number in range(number_clouds):  # Generate clouds.
            cloud = Cloud(self)  # Create Cloud instance
            self.clouds.add(cloud)  # Add cloud to clouds sprote.

    def _update_screens(self):
        """Update images on the screen, and flip to the new screen."""

        self.screen.fill(
            self.settings.bg_color)  # Fill screen with background color.
        self.clouds.draw(self.screen)  # Draw clouds.

        if self.stats.game_active:  # If game mode is active, draw ship.
            self.ship.blitme()

        if self.stats.game_active:  # If game is active, draw bullets.
            for bullet in self.bullets.sprites():
                bullet.blitme()

        if self.stats.game_active:  # If game is active draw 2nd line aliens.
            self.enemy_bullets.draw(self.screen)

        if self.stats.game_active:
            self.aliens.draw(
                self.screen)  # If game is active draw 1st line aliens.

        if self.settings.dif_level == "Easy" and self.stats.game_active:  # If easy level and active game:
            self.sb.show_el_score()  # draw the score information.

        if self.settings.dif_level == "Normal" and self.stats.game_active:
            self.sb.show_nl_score()

        if self.settings.dif_level == "Hard" and self.stats.game_active:
            self.sb.show_hl_score()

        if not self.stats.game_active:  # Draw menu buttons if game is inactive.
            self.buttons.draw_button()

        if self.po.status:  # Drae power-ups.
            self.po.blitme()

        pygame.display.flip()  # COntinuous update of recent screen settings.

    def _save_high_score(self):
        """Save highscore data, when quitting game."""

        date = self.full_date  # Get date (dd/mm/yy).
        player_name = self.entry  # Get player's name.

        highscores = [
            self.stats.el_high_score, self.stats.nl_high_score,
            self.stats.hl_high_score
        ]  # Get high scores.
        myFiles = [
            'el_high_scores.txt', 'nl_high_scores.txt', 'hl_high_scores.txt'
        ]  # Read old high scores from files.
        cwd = os.getcwd()  # Get current working directory (cwd).

        for file_name, highscore in zip(myFiles,
                                        highscores):  # Read old highscores.
            with open(os.path.join(cwd, file_name), encoding='utf-8') as f:
                contents = f.read()  # Read file contents.
            words = contents.split()  # Split content to list of entries.
            old_high_score = words[-1]  # Get last entry.

            if int(highscore) > int(
                    old_high_score):  # If new hiighscore, save it.
                with open(os.path.join(os.getcwd(), file_name), 'w') as f:
                    f.write(f"{date} {player_name} {highscore}"
                            )  # Save info to file.
class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源"""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))

        # 全屏模式
        # self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Alien Invasion")

        # 创建一个用户存储游戏统计信息的实例。
        self.stats = GameStats(self)

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()
        self._create_fleet()

        # 创建Play按钮。
        self.play_button = Button(self, "Play")

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self.bullets.update()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _check_events(self):
        """响应按键和鼠标事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_keydown_events(self, event):
        """响应按键。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """响应松开。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _check_play_button(self, mouse_pos):
        """在玩家单击Play按钮时开始新游戏。"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # 重置游戏统计信息。
            self.stats.reset_stats()
            self.stats.game_active = True

            # 清空余下的外星人和子弹。
            self.aliens.empty()
            self.bullets.empty()

            # 创建一群新的外星人并让飞船居中。
            self._create_fleet()
            self.ship.center_ship()

            # 隐藏鼠标光标。
            pygame.mouse.set_visible(False)

    def _fire_bullet(self):
        """创建一颗子弹,并将其加入编组bullets中。"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """更新子弹的位置并删除消失的子弹。"""
        # 更新子弹的位置。
        self.bullets.update()
        # 删除消失的子弹
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """响应子弹和外星人碰撞。"""
        # 删除发送碰撞的子弹和外星人。
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if not self.aliens:
            # 删除现有的所有子弹,并创建一群新的外星人。
            self.bullets.empty()
            self._create_fleet()

    def _update_aliens(self):
        """
        检查是否有外星人位于屏幕边缘,
        并更新整群外星人的位置。
        """
        self._check_fleet_edges()
        self.aliens.update()

        # 检测外星人与飞船之间的碰撞。
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # 检查是否有外星人到达屏幕底端。
        self._check_aliens_bottom()

    def _ship_hit(self):
        """响应飞船被外星人撞到。"""
        if self.stats.ship_left > 0:
            # 将ships_left减1。
            self.stats.ship_left -= 1

            # 清空余下的外星人和子弹。
            self.aliens.empty()
            self.bullets.empty()

            # 创建一群新的外星人,并将飞船放到屏幕底端的中央。
            self._create_fleet()
            self.ship.center_ship()

            # 暂停。
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        """检查是否有外星人到达了屏幕底端。"""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                # 像飞船被撞到一样处理。
                self._ship_hit()
                break

    def _check_fleet_edges(self):
        """有外星人到达边缘时采取相应的措施。"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """将整群外星人下移,并改变它们的方向。"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _create_fleet(self):
        """创建外星人群。"""
        # 创建一个外星人。
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # 计算屏幕可容纳多少行外星人。
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # 创建外星人群。
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """创建一个外星人并将其放在当前行。"""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _update_screen(self):
        """更新屏幕上的图像,并切换到新屏幕。"""
        self.screen.fill(self.settings.bg_color)
        # 将飞船绘制到屏幕。
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        # 如果游戏处于非活动状态,就绘制Play按钮。
        if not self.stats.game_active:
            self.play_button.draw_button()

        # 让最近绘制的屏幕可见。
        pygame.display.flip()
class AlianInvasion:
    """ Top Level class to maintain the game."""
    def __init__(self):
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_height = self.screen.get_rect().height
        self.settings.screen_width = self.screen.get_rect().width
        pygame.display.set_caption("Alien Invasion")
        self.stats = GameStats(self)
        self.ship = Ship(self)
        self.aliens = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.scoreboard = Scoreboard(self)
        self._create_fleet()
        # Make the button
        self.play_button = Button(self, "Play")

    def run_game(self):
        while True:
            self._check_events()
            if self.stats.game_active:
                self.ship.update_position()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _create_fleet(self):
        """ Create the fleet of aliens. """

        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_of_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that can fit on the screen
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (9 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)
        for row_number in range(number_rows):
            for alien_number in range(number_of_aliens_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien_height + 2 * alien_height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """ Check whether any of the aliens have touched the edges. """
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """ Move the fleet down and change direction. """
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_aliens(self):
        """ Update the position of the aliens."""
        self._check_fleet_edges()
        self.aliens.update()
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()
        self._check_aliens_bottom()

    def _check_aliens_bottom(self):
        """ Check whether the aliens have reached the bottom. """
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                self._ship_hit()
                break

    def _ship_hit(self):
        """ Respond to the ship hit by an alien. """
        if self.stats.ships_left > 0:
            # Redude the number of ships
            self.stats.ships_left -= 1
            self.scoreboard.prep_ships()

            # clear the aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # recreate the fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            sleep(1)
        else:
            pygame.mouse.set_visible(True)
            self.stats.game_active = False

    def _update_bullets(self):
        """ Updates the position of the bullet"""
        self.bullets.update()
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        """ check collisions and recreate fleet if done. """
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)
        if collisions:
            for collision in collisions.values():
                self.stats.score += self.settings.alien_points
            self.scoreboard.prep_score()
            self.scoreboard.check_high_score()

        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()
            self.stats.level += 1
            self.scoreboard.prep_level()

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        # using the sprite draw function
        self.aliens.draw(self.screen)
        if not self.stats.game_active:
            self.play_button.draw_button()
        self.scoreboard.show_score()
        pygame.display.flip()

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_event(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_event(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """Check whether the mouse button was clicked. """
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            self.stats.reset_stats()
            self.scoreboard.prep_score()
            self.scoreboard.prep_level()
            self.scoreboard.prep_ships()
            self.settings.initialize_dynamic_settings()
            # remove any remaining aliens
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet
            self._create_fleet()
            self.ship.center_ship()
            self.stats.game_active = True
            pygame.mouse.set_visible(False)

    def _check_keydown_event(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_q:
            sys.exit()

    def _check_keyup_event(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        if len(self.bullets) < self.settings.max_bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def get_image_path(self, image_name):
        return os.path.join(os.path.join(os.path.dirname(__file__), "images"),
                            image_name)
Example #56
0
class AlienInvasion:
    """
    Класс для управления ресурсами и поведением игры
    """
    def __init__(self):
        # Инициальзация pygame
        pygame.init()

        # Создание объекта класса Настройки, чтобы подтягивать их или изменения из отдельного файла а не в самом коде
        self.settings = Settings()

        # Назначение размера окна и имени
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption('Alien Invasion')

        # Создание экземпляра для хранения игровой статистики
        self.stats = GameStats(self)

        # Создание экземпляра Scoreboard
        self.scoreboard = Scoreboard(self)

        # Создание экземпляра корабля
        self.ship = Ship(self)

        # Группа для хранения всех летящих снарядов
        self.bullets = pygame.sprite.Group()

        # Группа для хранения всех пришельцев
        self.aliens = pygame.sprite.Group()
        self._create_fleet()

        # Создание кнопки Play
        self.play_button = Button(self, 'Play')

    def run_game(self):
        """
        Запуск основного цикла игры
        """
        while True:
            self._check_events()

            # Отделим части игры, которые должны выподлняться только при активной игре (game_active = True)
            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()

            self._update_screen()

    def _check_events(self):
        """
        Обрабатывает нажатия клавиш и события мыши
        """
        # Отслеживание дествий клвариатуры и мыши (итерация по всем значениям в списке действий в pygame.event.get)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            # Блок отвечающий за действие при нажатии клавиши (начать движение корабля)
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            # Блок отвечающий за действие при отжатии клавиши (прекратить движение корабля)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        """
        Запускает новую игру при нажатии кнопки Play
        """
        # Проверяет находится ли точка щелчка в пределах прямоугольника
        # и отмена реакции клика по квадрату, если игра активна
        mouse_on_play = self.play_button.rect.collidepoint(mouse_pos)
        if mouse_on_play and not self.stats.game_active:
            # Сброс игровой статистики
            self.settings.initialize_dynamic_settings(
            )  # Увеличение скорости игры
            self.stats.reset_stats()
            self.stats.game_active = True
            self.scoreboard.prep_score()
            self.scoreboard.prep_high_score()
            self.scoreboard.prep_level()
            self.scoreboard.prep_ships()

            # Очистка списков пришельцев и снарядов
            self.aliens.empty()
            self.bullets.empty()

            # Создание нового флота и размещение корабля в центре
            self._create_fleet()
            self.ship.center_ship()

            # Спрятать указаьель мыши во время игры
            pygame.mouse.set_visible(False)

    def _check_keydown_events(self, event):
        """
        Реагирует на нажатие клавиш.
        """
        # Действия при нажатии клавиш перемещения -> <-
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        # Добпавление действия при нажатии кнопки пробела
        elif event.key == pygame.K_SPACE:
            self.fire_bullet()

    def _check_keyup_events(self, event):
        """
        Реагирует на отпускание клавиш.
        """
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def fire_bullet(self):
        """
        Создание нового снаряда и включение его в группу bullets
        """
        # Сначала проверим, что количество уже летящих на экране снарядов не болшье разрешенного значения (3)
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """
        Обновляет позиции срарядов и удаляет старые снаряды
        """
        # Вызываем bullet.update() для каждого снаряда в группе self.bullets
        self.bullets.update()

        # Удаление снарядов, вышедших за край экрана. Иначе они существуют за его пределами и потребляют память
        # Сам список bullets в цикле изменять нельзя, пожтому изменять будет его копию .copy()
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collision()

    def _check_bullet_alien_collision(self):
        """
        Обработка коллизий снарядов с пришельцами
        """
        # Проверка попадений в пришельцев (коллизий) с помощью sprite.groupcollide()
        # True, True обозначает, что нужно удалять каждый объект после столкновения
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                False, True)

        # Проверка есть ли попадение в прищельца и добавление очков за него
        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.scoreboard.prep_score()
            self.scoreboard.check_high_score()

        # Удаление существующих снарядов после поражения последнего пришельца и создание нового флота
        # Метод empty() удаляет все спрайты(объекты группы) из группы
        if not self.aliens:
            self.bullets.empty()
            self._create_fleet()
            # Ускорение игры в 1.1 раз
            self.settings.increase_speed()

            # Увеличение номера уровня
            self.stats.level += 1
            self.scoreboard.prep_level()

    def _create_fleet(self):
        """
        Создание флота вторжения
        """
        # Создание пришельца и вычисление допустимого количества пришельцев в ряду
        # Интервал между пришельцами равен ширине пришельца
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        ship_height = self.ship.rect.height

        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        available_space_y = self.settings.screen_height - (
            2 * alien_height) - ship_height * 4
        number_rows = available_space_y // (2 * alien_height)

        # Создание первого ряда пришельцев
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x - 1):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """
        Создание пришельца и размещение его в ряду, добавление его в группу Sprite
        """
        alien = Alien(self)
        # Атрибут size содержит коржтеж из значений ширины и высоты rect
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _check_fleet_edges(self):
        """
        Реагирует на достижение пришельцем края экрана
        """
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """
        Опускает весь флот и меняет его направление движения
        """
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_aliens(self):
        """
        Проверяет достиг ли флот края экрана и обновляет позиции всех пришельцев во флоте
        """
        self._check_fleet_edges()
        # Вызываем aliens.update() для каждого снаряда в группе self.aliens
        self.aliens.update()

        # Проверка коллизий корабль - пришелец
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # Проверяет добрались ли пришельцы до нижнего края экрана
        self._check_aliens_bottom()

    def _ship_hit(self):
        """
        Обрабатывает столкнокение корабля с пришельцем
        """
        if self.stats.ships_left > 0:
            # Уменьшение количества жизней корабля на 1
            self.stats.ships_left -= 1
            self.scoreboard.prep_ships()

            # Очистка кораблей и снарядов
            self.bullets.empty()
            self.aliens.empty()

            # Создание нового флота и размещение корабля в центре
            self._create_fleet()
            self.ship.center_ship()

            # Пауза
            sleep(0.5)
        else:
            self.stats.game_active = False

    def _check_aliens_bottom(self):
        """
        Проверяет добрались ли пришельцы до нижнего края экрана
        """
        if self.stats.ships_left > 0:
            screen_rect = self.screen.get_rect()
            for alien in self.aliens.sprites():
                if alien.rect.bottom >= screen_rect.bottom:
                    # Происхоит тоже, что при столкновении с кораблем
                    self._ship_hit()
                    break
        else:
            self.stats.game_active = False

    def _update_screen(self):
        # Заполенение экрана нужным цветом
        self.screen.fill(self.settings.background_color)

        # Выводит изображение корабля на экран в позиции, заданной self.rect
        self.ship.blitme()

        # Перебор всех bullet в спрайте(группы) bullets и прорисовка каждой
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        # Специальный метод pygame для вывода всей группы на поверхность(получаемый аргумент)
        self.aliens.draw(self.screen)

        # Вывод инфолрмации о счете
        self.scoreboard.show_score()

        # Кнопка Play отображается только когда игра не активна
        if not self.stats.game_active:
            self.play_button.draw_button()

        # Отображение последнего прорисованного экрана
        pygame.display.flip()
Example #57
0
class AlienInvaders:
    #Manage game asssets and game behaviours

    def __init__(self):
        #Initialize the game and create game resources
        pygame.init()
        pygame.display.set_caption("Alien Invaders")
        self.settings = Settings()
        self.screen = pygame.display.set_mode((1600, 900), pygame.FULLSCREEN)
        self.stats = GameStats(self)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        self.ship = Ship(self)
        self.bullet = Bullet(self)
        self.bullets = pygame.sprite.Group()
        self.aliens1 = pygame.sprite.Group()
        self.aliens2 = pygame.sprite.Group()
        self.scores = []
        self.ammo = Ammo(self)
        self.cur_ammo = self.settings.bullet_limit
        self.spawn_alien2_count = 4
        self.a1_kill_amount = 0
        self.sb = Scoreboard(self)
        self.play_button = Button(self)

    def run_game(self):
        #Start the game
        while True:
            #Detect keyboard and mouse events
            self._check_events()
            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _check_events(self):
        #Respond to events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if event.type == pygame.KEYDOWN:
                self._check_keydown(event)
            if event.type == pygame.KEYUP:
                self._check_keyup(event)
            if event.type == pygame.MOUSEBUTTONDOWN:
                if not self.stats.game_active:
                    mouse_pos = pygame.mouse.get_pos()
                    self._check_play(mouse_pos)
                elif event.button == 1:
                    self._fire_bullet()

    def _check_keydown(self, event):
        if event.key == pygame.K_r or event.key == pygame.K_SPACE:
            self.cur_ammo = self.settings.bullet_limit
        if event.key == pygame.K_d:
            self.ship.moving_right = True
        elif event.key == pygame.K_a:
            self.ship.moving_left = True
        elif event.key == pygame.K_w:
            self.ship.moving_up = True
        elif event.key == pygame.K_s:
            self.ship.moving_down = True

    def _check_keyup(self, event):
        if event.key == pygame.K_ESCAPE:
            sys.exit()
        elif event.key == pygame.K_d:
            self.ship.moving_right = False
        elif event.key == pygame.K_a:
            self.ship.moving_left = False
        elif event.key == pygame.K_w:
            self.ship.moving_up = False
        elif event.key == pygame.K_s:
            self.ship.moving_down = False

    def _fire_bullet(self):
        #Create a new bullet
        if self.cur_ammo > 0:
            self.cur_ammo -= 1
            new_bullet = Bullet(self)
            new_bullet.bullet_angle()
            self.bullets.add(new_bullet)

    def _update_aliens(self):
        #Update alien positions
        if len(self.aliens1) + len(self.aliens2) == 0:
            self._create_aliens()
        for alien in self.aliens1.copy():
            alien.update()
        for alien in self.aliens2.copy():
            alien.update()
        if pygame.sprite.spritecollideany(
                self.ship, self.aliens1) or pygame.sprite.spritecollideany(
                    self.ship, self.aliens2):
            self._ship_hit()

    def _update_bullets(self):
        #Update bullet positions and delete old bullets
        for bullet in self.bullets.copy():
            bullet.update()
            if bullet.rect.bottom <= 0 or bullet.rect.bottom >= self.settings.screen_height or bullet.rect.x <= 0 or bullet.rect.x >= self.settings.screen_width:
                self.bullets.remove(bullet)
        self._check_bullet_alien_collisions()

    def _check_bullet_alien_collisions(self):
        aliens1 = len(self.aliens1.copy())
        aliens2 = len(self.aliens2.copy())
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens1,
                                                True, True)
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens2,
                                                True, True)

        if aliens2 > len(self.aliens2):
            for i in range(aliens2 - len(self.aliens2)):
                self.stats.score += self.settings.alien2_points
                self._create_aliens()
                self._create_aliens()

        if aliens1 > len(self.aliens1):
            for i in range(aliens1 - len(self.aliens1)):
                self.a1_kill_amount += 1
                self.stats.score += self.settings.alien1_points
                self._create_aliens()

    def _create_aliens(self):
        if self.a1_kill_amount > self.spawn_alien2_count:
            self.spawn_alien2_count += 1
            self.a1_kill_amount = 0
            self._spawn_alien2()
        else:
            self._spawn_alien1()

    def _spawn_alien1(self):
        alien1 = Alien(self)
        alien1.type = 1
        alien1.rect = alien1.rect1
        self.aliens1.add(alien1)

    def _spawn_alien2(self):
        alien2 = Alien(self)
        alien2.type = 2
        alien2.rect = alien2.rect2
        self.aliens2.add(alien2)

    def _inti_scores(self):
        for i in range(1, 11):
            score = Scoreboard(self)
            score.place = i
            self.scores.append(score)

    def _update_screen(self):
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        self.sb.show_score()
        for score in self.scores.copy():
            score._check_score()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        for alien in self.aliens1.sprites():
            alien.draw_alien()
        for alien in self.aliens2.sprites():
            alien.draw_alien()
        if not self.stats.game_active:
            self.play_button.draw_button()

        pygame.display.flip()

    def _ship_hit(self):
        #Respond if ship is hit by alien
        if self.stats.ships_left - 1 != 0:
            self.stats.ships_left -= 1
            self.spawn_alien2_count = 4
            self.a1_kill_amount = 0
            self.aliens1.empty()
            self.aliens2.empty()
            self.bullets.empty()
            self._spawn_alien1()
            self.cur_ammo = 3
            self.ship.center_ship()
            sleep(.5)
        else:
            self.stats.game_active = False
            sleep(1)
            pygame.mouse.set_visible(True)

    def _check_play(self, mouse_pos):
        if self.play_button.rect.collidepoint(mouse_pos):
            self.stats.game_active = True
            self.stats.reset_stats()
            self.spawn_alien2_count = 4
            self.a1_kill_amount = 0
            self.aliens1.empty()
            self.aliens2.empty()
            self.bullets.empty()
            self.scores.clear()
            self._spawn_alien1()
            self._inti_scores()
            self.cur_ammo = 3
            self.ship.center_ship()
            pygame.mouse.set_visible(False)
Example #58
0
SCREENHEIGHT = 900

XCOORD = 0
YCOORD = 0
previousXCOORD = 0
previousYCOORD = 0

size = (SCREENWIDTH, SCREENHEIGHT)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("Star Trek")

# This will be a list that will contain all the sprites we intend to use in our game.
all_sprites_list = pygame.sprite.Group()

player1 = Ship('enterprise', 'federationHC')
player1.rect.x = 500
player1.rect.y = 500
player2 = Ship('koplah', 'defiant')

playerCar = Car(RED, 60, 80, 70)
playerCar.rect.x = 160
playerCar.rect.y = SCREENHEIGHT - 100

car1 = Car(PURPLE, 60, 80, random.randint(50, 100))
car1.rect.x = 60
car1.rect.y = -100

car2 = Car(YELLOW, 60, 80, random.randint(50, 100))
car2.rect.x = 160
car2.rect.y = -600
class AlienInvasion:
	"""Overall class to manage game assets and behavior."""

	def __init__(self):
		"""Initialize the game, and create game resources."""
		pygame.init()
		self.settings = Settings()
		
		self.screen = pygame.display.set_mode(
			(self.settings.screen_width, self.settings.screen_height))
		#self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
		self.settings.screen_width = self.screen.get_rect().width
		self.settings.screen_height = self.screen.get_rect().height
		pygame.display.set_caption("Alien Invasion")

		# Create an instance to store game statistics.
		self.stats = GameStats(self)

		self.ship = Ship(self)
		self.bullets = pygame.sprite.Group()
		self.aliens = pygame.sprite.Group()

		self._create_fleet()										

	def _check_keydown_events(self, event):
		"""Respond to keypresses."""
		#print(event.key)
		if event.key == pygame.K_RIGHT:
			self.ship.moving_right = True
		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = True
		elif event.key == pygame.K_UP:
			self.ship.moving_top = True
		elif event.key == pygame.K_DOWN:
			self.ship.moving_bottom = True
		elif event.key == pygame.K_SPACE:
			self._fire_bullet()
		elif event.key == pygame.K_q:
			sys.exit()
		
	def _check_keyup_events(self, event):
		"""Respond to key releases."""
		if event.key == pygame.K_RIGHT:
			self.ship.moving_right = False
		elif event.key == pygame.K_LEFT:
			self.ship.moving_left = False
		elif event.key == pygame.K_UP:
			self.ship.moving_top = False
		elif event.key == pygame.K_DOWN:
			self.ship.moving_bottom = False

	def _fire_bullet(self):
		"""Create a new bullet and add it to the bullets group."""
		if len(self.bullets) < self.settings.bullets_allowed:
			new_bullet = Bullet(self)
			self.bullets.add(new_bullet)

	def _check_events(self):
		"""Respond to keypresses and mouse events."""
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				sys.exit()
			elif event.type == pygame.KEYDOWN:
				self._check_keydown_events(event)
			elif event.type == pygame.KEYUP:
				self._check_keyup_events(event)

	def _update_bullets(self):
		"""Update position of bullets and get rid of old bullets."""
		# Update bullet positions.
		self.bullets.update()

		# Get rid of bullets that have disappeared.
		for bullet in self.bullets.copy():
			if bullet.rect.right >= self.settings.screen_width:
				self.bullets.remove(bullet)
		
		self._check_bullet_alien_collisions()
	
	def _check_bullet_alien_collisions(self):
		"""Respond to bullet-alien collisions."""
		# Remove any bullets and aliens that have collided.
		collisions = pygame.sprite.groupcollide(
				self.bullets, self.aliens, True, True)

		if collisions:
			self.stats.hit_aliens_left = len(self.aliens.sprites())
			if not self.stats.hit_aliens_left:
				self.stats.game_active = False
		
		# Destroy existing bullets and create new fleet.
		if not self.aliens:
			self.bullets.empty()
			if self.stats.game_active:
				self._create_fleet()
	
	def _update_aliens(self):
		"""
		Check if the fleet is at an edge,
		then update the positions of all aliens in the fleet.
		"""
		self._check_fleet_edges()
		self.aliens.update()

		# Look for alien-ship collisions.
		if pygame.sprite.spritecollideany(self.ship, self.aliens):
			self._ship_hit()

		# Look for aliens hitting the left of the screen.
		self._check_aliens_left()

	def _ship_hit(self):
		"""Respond to the ship being hit by an alien."""
		# Decrement ships_left.
		self.stats.ships_left -= 1
		if self.stats.ships_left > 0:
			# Get rid of any remaining aliens and bullets.
			self.aliens.empty()
			self.bullets.empty()
			
			# Create a new fleet and center the ship.
			self._create_fleet()
			self.ship.center_ship()
				
			# Pause.
			sleep(0.5)
		else:
			self.stats.game_active = False

	def _create_fleet(self):
		"""Create the fleet of aliens."""
		# Create an alien and find the number of aliens in a row.
		# Spacing between each alien is equal to one alien width.
		alien = Alien(self)
		alien_width, alien_height = alien.rect.size
		ship_height = self.ship.rect.height

		available_space_y = self.settings.screen_height - 2 * alien_height
		number_rows = available_space_y // (2 * alien_width)
		
		available_space_x = (self.settings.screen_width - (alien_width)
							- ship_height)
		number_aliens_y = available_space_x // (2 * alien_width)

		self.stats.hit_aliens_left = number_rows * number_aliens_y

		# Create the full fleet of aliens.
		for row_number in range(number_rows):
			for alien_number in range(number_aliens_y):
				self._create_alien(alien_number, row_number)
	
	def _create_alien(self, alien_number, row_number):
		"""Create an alien and place it in the row."""
		alien = Alien(self)
		alien_width, alien_height = alien.rect.size

		alien.x = 3 * alien_width + 2 * alien_width * alien_number
		alien.rect.x = alien.x
		
		alien.y = alien.rect.height + 2 * alien.rect.height * row_number
		alien.rect.y = alien.y
		self.aliens.add(alien)

	def _check_fleet_edges(self):
		"""Respond appropriately if any aliens have reached an edge."""
		for alien in self.aliens.sprites():
			if alien.check_edges():
				self._change_fleet_direction()
				break

	def _check_aliens_left(self):
		"""Check if any aliens have reached the bottom of the screen."""
		screen_rect = self.screen.get_rect()
		for alien in self.aliens.sprites():
			if alien.rect.left <= 0:
				# Treat this the same as if the ship got hit.
				self._ship_hit()
				break
	
	def _change_fleet_direction(self):
		"""Drop the entire fleet and change the fleet's direction."""
		for alien in self.aliens.sprites():
			alien.rect.x -= self.settings.fleet_drop_speed
		self.settings.fleet_direction *= -1

	def _update_screen(self):
		"""Update images on the screen, and flip to the new screen."""
		self.screen.fill(self.settings.bg_color)
		self.ship.blitme()
		for bullet in self.bullets.sprites():
			bullet.draw_bullet()
		self.aliens.draw(self.screen)

		# Make the most recently drawn screen visible.
		pygame.display.flip()

	def run_game(self):
		"""Start the main loop for the game."""
		while True:
			self._check_events()

			if self.stats.game_active:
				self.ship.update()
				self._update_bullets()
				self._update_aliens()
			
			self._update_screen()
Example #60
0
def play():
    pygame.init()
    settings = Settings()
    screen = pygame.display.set_mode((settings.scr_width, settings.scr_height))
    pygame.display.set_caption('Alien Invasion')
    main_clock = pygame.time.Clock()

    stats = GameStats(settings, screen)
    sb = Scoreboard(settings, screen, stats)
    sscreen = StartScreen(settings, screen)

    # Make a ship
    ship = Ship(settings, screen)

    # Make bunkers
    bunkers = [Bunker(screen, 400, 480)]

    # Make bullets and aliens group
    bullets = Group()
    aliens = Group()
    enemy_bullets = Group()
    # gf.create_fleet(settings, screen, ship, aliens)

    # Make buttons
    play_button = Button(screen, 'PLAY', screen.get_rect().centerx, 400)
    score_button = Button(screen, 'HIGH SCORE', screen.get_rect().centerx, 480)
    buttons = [play_button, score_button]

    # Set up music
    bg_music1 = pygame.mixer.Sound('audio/background_1.wav')
    bg_music2 = pygame.mixer.Sound('audio/background_2.wav')
    is_playing_music = False
    is_playing_music2 = False
    game_over_sound = pygame.mixer.Sound('audio/gameover.wav')

    # Boss timer
    boss_respawn_time = randint(10, 18) * 1000  # 10-18s at level 1
    boss_timer = boss_respawn_time
    delta_time = 0

    # Enemy fire timer
    enemy_fire_time = randint(2, 6) * 1000  # 2-6s at level 1
    fire_timer = enemy_fire_time

    # Main game loop
    game_over = False
    while not game_over:
        gf.check_events(settings, screen, stats, sb, buttons, ship, aliens, bullets, enemy_bullets, bunkers)
        if stats.game_status == 2:
            # update bg music
            if not is_playing_music:
                bg_music1.play(-1)
                is_playing_music = True
                is_playing_music2 = False
            if len(aliens) - settings.boss_number <= 10 and not is_playing_music2:
                bg_music1.stop()
                bg_music2.play(-1)
                is_playing_music2 = True
            if is_playing_music2 and len(aliens) - settings.boss_number > 10:
                bg_music2.stop()
                bg_music1.play(-1)
                is_playing_music = True
                is_playing_music2 = False
            if ship.dead and ship.die_anim.finished and stats.ships_left > 0:
                pygame.mixer.stop()
                is_playing_music, is_playing_music2 = False, False
                # reset boss and fire timer when ship explodes
                boss_respawn_time = randint(10, 18) * 1000
                boss_timer = int(boss_respawn_time / settings.enemy_timer_scale)
                enemy_fire_time = randint(2, 6) * 1000
                fire_timer = int(enemy_fire_time / settings.enemy_timer_scale)

            for b in bunkers:
                b.update(bullets, enemy_bullets)
            ship.update()
            gf.update_ship(settings, screen, stats, sb, ship, aliens, bullets, enemy_bullets)
            gf.update_bullets(settings, screen, stats, sb, aliens, bullets, enemy_bullets)

            # Spawn boss
            if settings.boss_number < settings.boss_number_limit:
                if boss_timer <= 0:
                    gf.create_boss(settings, screen, aliens)
                    boss_respawn_time = randint(10, 18) * 1000
                    boss_timer = int(boss_respawn_time / settings.enemy_timer_scale)
                else:
                    boss_timer -= delta_time

            gf.update_aliens(settings, screen, ship, aliens)

            # Enemy fire
            if fire_timer <= 0 and len(enemy_bullets) < settings.bullets_allowed:
                new_bullet = EnemyBullet(settings, screen, aliens)
                enemy_bullets.add(new_bullet)
                enemy_fire_time = randint(2, 6) * 1000
                fire_timer = int(enemy_fire_time / settings.enemy_timer_scale)
            elif fire_timer > 0:
                fire_timer -= delta_time
            gf.update_enemy_bullets(settings, ship, bullets, enemy_bullets)

        else:
            # update music
            if is_playing_music or is_playing_music2:
                pygame.mixer.stop()
                is_playing_music, is_playing_music2 = False, False
                if stats.ships_left == 0:
                    game_over_sound.play()
                    # reset boss and fire timer to level 1
                    boss_respawn_time = randint(10, 18) * 1000
                    boss_timer = boss_respawn_time
                    enemy_fire_time = randint(2, 6) * 1000
                    fire_timer = enemy_fire_time

        gf.update_screen(settings, screen, stats, sb, ship, aliens, bullets, enemy_bullets, bunkers, buttons, sscreen)
        delta_time = main_clock.tick(FPS)