class InvasaoKlingon: """Class para lidar com os comportamentos do jogo""" def __init__(self): """Inicializa o jogo e cria os recursos""" pygame.init() self.configuracoes = Configuracoes() """Para habilitar modo Fullscreen, retire as anotações dos três códigos abaixo e adicione observação no 'self.screen'""" # self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # self.configuracoes.screen_width = self.screen.get_rect().width # self.configuracoes.screen_height = self.screen.get_rect().height self.screen = pygame.display.set_mode( (self.configuracoes.screen_width, self.configuracoes.screen_height)) pygame.display.set_caption("Invasão Klingon") # Cria uma instância para armazenar os dados do jogo self.stats = GameStats(self) self.placar = Placar(self) self.placar = Placar(self) # Músicas de fundo self.open_music = pygame.mixer.Sound( os.path.join("complemento/tng_open.mp3") ) # Abertura da série Star Trek: Next Generation self.battle_music = pygame.mixer.Sound( os.path.join( "complemento/first_contact.mp3")) # Assimilation battle sound # Sprites self.nave = Nave(self) self.tiros = pygame.sprite.Group() self.klingons = pygame.sprite.Group() self._criar_frota() # Botão de iniciar self.play_botao = Botao(self, "Iniciar") # Icon self.icon = pygame.transform.scale( pygame.image.load(os.path.join("complemento/klingon_icon.png")), (35, 35)) pygame.display.set_icon(self.icon) def run_game(self): """Inicia o loop principal do jogo""" while True: self._check_events() self.open_music.play(loops=-1) self.open_music.set_volume(0.1) if self.stats.game_active: self.nave.update() self.open_music.stop() if self.open_music.stop: self.battle_music.play(loops=-1) self._update_tiros() self._update_klingons() self._update_screen() def _check_events(self): """Notar o uso do teclado e do mouse""" 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 and self.stats.game_active is False: mouse_pos = pygame.mouse.get_pos() self._check_iniciar_botao(mouse_pos) pygame.mixer.Channel(2).play( pygame.mixer.Sound( os.path.join("complemento/computerbeep_10.mp3"))) def _check_iniciar_botao(self, mouse_pos): """Inicia um novo jogo quando o usuário clicar no botão""" click_botao = self.play_botao.rect.collidepoint(mouse_pos) if click_botao and not self.stats.game_active: # Reset as configs do jogo self.configuracoes.inicializar_dinamica_configs() # Reset os stats do jogo self.stats.reset_stats() self.stats.game_active = True self.placar.prep_placar() self.placar.prep_level() self.placar.prep_naves() # Retira os aliens e disparos da partida antiga self.klingons.empty() self.tiros.empty() # Cria uma nova frota e centraliza a nave self._criar_frota() self.nave.center_nave() # Esconder o cursor do mouse pygame.mouse.set_visible(False) def _check_keydown_events(self, event): """Responde as teclas""" if event.key == pygame.K_RIGHT: # Move a nave para a direita self.nave.moving_right = True elif event.key == pygame.K_LEFT: self.nave.moving_left = True elif event.key == pygame.K_q: sys.exit() elif event.key == pygame.K_p: self._iniciar_jogo() pygame.mixer.Channel(2).play( pygame.mixer.Sound("complemento/computerbeep_10.mp3")) elif event.key == pygame.K_SPACE and self.stats.game_active is True: self._dispara_tiro() def _iniciar_jogo(self): # Reset as configs do jogo self.configuracoes.inicializar_dinamica_configs() # Reset os stats do jogo self.stats.reset_stats() self.stats.game_active = True self.placar.prep_placar() def _check_keyup_events(self, event): """Responde a ausência de interação com o teclado""" if event.key == pygame.K_RIGHT: self.nave.moving_right = False elif event.key == pygame.K_LEFT: self.nave.moving_left = False def _dispara_tiro(self): """Cria um novo disparo e adiciona esse tiro em uma lista""" if len(self.tiros) < self.configuracoes.tiros_permitidos: novo_disparo = Tiro(self) self.tiros.add(novo_disparo) pygame.mixer.Channel(1).play( pygame.mixer.Sound(os.path.join("complemento/torp.mp3"))) pygame.mixer.Channel(1).set_volume(0.35) def _update_tiros(self): """Atualiza a posição dos disparos e se deleta os antigos""" # Atualiza a posição self.tiros.update() # Deleta os tiros após sairem da tela for tiro in self.tiros.copy(): if tiro.rect.bottom <= 0: self.tiros.remove(tiro) self._check_colisao_disparo() def _check_colisao_disparo(self): # Checar se algum disparo atingiu uma nave inimiga # Se sim, retirar a nave klingon da tela colisao = pygame.sprite.groupcollide(self.tiros, self.klingons, True, True) if colisao: for klingon in colisao.values(): self.stats.score += self.configuracoes.klingon_points * len( klingon) self.placar.prep_placar() self.placar.check_high_score() if not self.klingons: # Destroi os tiros existentes e cria uma nova tropa self.tiros.empty() self._criar_frota() self.configuracoes.aumentar_vel() # Aumenta o nível self.stats.level += 1 self.placar.prep_level() def _update_klingons(self): """Atualiza a posição de todas as naves Klingons""" self._check_fleet_edges() self.klingons.update() # Colisão de naves if pygame.sprite.spritecollideany(self.nave, self.klingons): self._nave_hit() # Verifica se a nave klingon atingiu o fundo da tela self._check_klingons_bottom() def _nave_hit(self): """Responde a nave caso seja atingida por uma nave klingon""" if self.stats.nave_left > 0: # Decrementa nave_left self.stats.nave_left -= 1 self.placar.prep_naves() # Se livra das naves restantes e disparos self.klingons.empty() self.tiros.empty() # Cria uma nova frota de naves e centraliza a nave self._criar_frota() self.nave.center_nave() # Pausa sleep(0.5) else: self.stats.game_active = False pygame.mouse.set_visible(True) def _criar_frota(self): """Cria as naves Bird of Prey""" # Cria os Klingons e amostra a quantidade de naves em uma fileira # O espaço entre cada nave é igual a largura de uma nave klingon = Klingon(self) klingon_width, klingon_height = klingon.rect.size espaco_disp_x = self.configuracoes.screen_width - (2 * klingon_width) numero_klingons_x = espaco_disp_x // (2 * klingon_width) # Determina a primeira frota completa de Klingons nave_height = self.nave.rect.height espaco_disp_y = (self.configuracoes.screen_height - (3 * klingon_height) - nave_height) num_fileiras = espaco_disp_y // (2 * klingon_height) # Cria a primeira fileira de naves for num_fileiras in range(num_fileiras): for quant_klingon in range(numero_klingons_x): self._criar_klingon(quant_klingon, num_fileiras) def _criar_klingon(self, quant_klingon, num_fileiras): """Cria uma nave e a posiciona em uma fileira""" klingon = Klingon(self) klingon_width, klingon_height = klingon.rect.size klingon.x = klingon_width + 2 * klingon_width * quant_klingon klingon.rect.x = klingon.x klingon.rect.y = klingon.rect.height + 2 * klingon.rect.height * num_fileiras self.klingons.add(klingon) def _check_fleet_edges(self): """Responde apropriadamente se qualquer nave klingon atingir a borda da tela""" for klingon in self.klingons.sprites(): if klingon.check_edges(): self._mudar_direcao_frota() break def _check_klingons_bottom(self): """Checa se alguma nave klingon atingiu o fundo da tela""" screen_rect = self.screen.get_rect() for klingon in self.klingons.sprites(): if klingon.rect.bottom >= screen_rect.bottom: # Trata da mesma forma como se a nave fosse atingida self._nave_hit() break def _mudar_direcao_frota(self): """Mudar a direção da frota inteira""" for klingon in self.klingons.sprites(): klingon.rect.y += self.configuracoes.fleet_drop_speed self.configuracoes.direcao_frota *= -1 def _update_screen(self): # Redesenha a tela durante cada passada do loop # self.screen.fill(self.configuracoes.bg_color) self.screen.blit(self.configuracoes.background, [0, 0]) self.nave.blitme() for tiros in self.tiros.sprites(): tiros.draw_tiro() self.klingons.draw(self.screen) self.placar.show_placar() # Desenha o botão de Íniciar se o jogo estiver inativo if not self.stats.game_active: self.screen.blit(self.configuracoes.background, [0, 0]) self.nave.blitme() self.play_botao.draw_botao() self.screen.blit(self.configuracoes.logo, [270, 35]) pygame.display.flip()
class Jogo(): def __init__(self, nome_player): pygame.mixer.init() pygame.mixer.music.load('./audios/menu.wav') self.nome_player = nome_player self.ranking_botao_clicado = False def resetar(self): pygame.init() self.sons = Sons() self.ai_settings = Settings() self.screen = pygame.display.set_mode( (self.ai_settings.screen_width, self.ai_settings.screen_height)) # ponteiro do mause disaparece pygame.mouse.set_visible(True) # Cria espaçonave self.painel_vacina = Painel_vacina(self.ai_settings, self.screen) self.mira = Mira(self.ai_settings, self.screen, self.painel_vacina) # Grupo de virus self.viroses = Group() self.miras = Group() self.mira_colisor = Mira_colisor(self.ai_settings, self.screen) self.miras.add(self.mira_colisor) pygame.display.set_caption('VAC') # Define background self.background = pygame.image.load(self.ai_settings.background_path) self.background = pygame.transform.scale( self.background, (self.ai_settings.screen_width + 500, self.ai_settings.screen_height)) self.background_init = pygame.image.load( self.ai_settings.background_path_init) self.background_init = pygame.transform.scale( self.background_init, (self.ai_settings.screen_width, self.ai_settings.screen_height)) """ Define o estado do jogo""" self.barra_tempo = Barra_tempo(self.ai_settings, self.screen) # Define um multiprocess self.atualiza_movimento = UpMovVirus(self.viroses) self.estado_jogo = EstadoJogo(self.ai_settings, self.viroses, self.screen, self.painel_vacina, self.barra_tempo, self.atualiza_movimento) self.barra_tempo.estado_jogo = self.estado_jogo if self.estado_jogo.fullscreen: self.screen = pygame.display.set_mode( (self.ai_settings.screen_width, self.ai_settings.screen_height), pygame.FULLSCREEN) self.pontuacao_placar = Pontuacao(self.ai_settings, self.screen, self.estado_jogo) self.pontuacao_placar.inicia_pontos() self.estado_jogo.pontuacao = self.pontuacao_placar grupos_viroses = gf.coloca_virus_tela(self.ai_settings, self.screen, self.viroses, self.estado_jogo) self.estado_jogo.set_grupo_viroses(grupos_viroses) """ Indica estado do jogo se está iniciado ou não""" # Define um multiprocess self.atualiza_barra_tempo = UpMovBarra(self.barra_tempo, grupos_viroses) self.ranking_bd = Ranking('bd_score', self.nome_player) self.play_botao = Botao(self.ai_settings, self.screen, './imagens/icones/iniciar.png', self.func_call_back_play) self.ranking_botao = Botao(self.ai_settings, self.screen, './imagens/icones/ranking.png', self.func_call_back_ranking) self.play_botao.rect.centerx = 350 self.play_botao.rect.bottomleft = ( self.screen.get_rect().bottomleft[0] + 50, self.screen.get_rect().bottomleft[1] - 50) self.ranking_botao.rect.bottomright = ( self.screen.get_rect().bottomright[0] - 50, self.screen.get_rect().bottomright[1] - 50) self.pause_botao = Botao(self.ai_settings, self.screen, './imagens/icones/pause-play.png', self.func_call_back_pause) self.pause_botao.altura = 50 self.pause_botao.largura = 50 self.pause_botao.make_rect() self.pause_botao.rect.centerx = self.ai_settings.screen_width - 30 self.pause_botao.rect.centery = 70 self.vetor_botoes = [] self.vetor_botoes.append(self.play_botao) self.vetor_botoes.append(self.ranking_botao) self.vetor_botoes.append(self.pause_botao) pygame.mixer.music.play(-1) """Inicia um novo jogo quando o jogador clicar em Play.""" def func_call_back_play(self): print('CARREGANDO JOGO ...') if not self.estado_jogo.jogo_estado: try: self.resetar() self.atualiza_movimento.start() self.atualiza_barra_tempo.start() except: self.atualiza_movimento = UpMovVirus(self.viroses) self.atualiza_barra_tempo = UpMovVirus(self.viroses) gf.reseta_jogo(self.barra_tempo, self.estado_jogo) self.estado_jogo.jogo_estado = True self.play_botao.ativo = False self.ranking_botao.ativo = False self.play_botao.is_visivel = False self.ranking_botao.is_visivel = False def func_call_back_pause(self): self.estado_jogo.pause = not self.estado_jogo.pause """Inicia um novo jogo quando o jogador clicar em Play.""" def func_call_back_ranking(self): self.ranking_botao.flag_click = True gf.ranking_tela(self.ranking_bd, self.screen, self.ai_settings, self.play_botao, self.ranking_botao) def funcao_desenha(self): gf.update_screen(self.ai_settings, self.screen, self.mira, self.painel_vacina, self.viroses, self.miras, self.background, self.pontuacao_placar, self.barra_tempo, self.play_botao, self.ranking_botao, self.ranking_bd, self.pause_botao) # Percorre os update atacado no modulo principal gf.update_logica(self.ai_settings, self.viroses, self.painel_vacina, self.barra_tempo, self.mira, self.estado_jogo, self.ranking_bd) # Desenha o botão Play se o jogo estiver inativo pygame.display.flip() def tela_inicial(self): if not self.estado_jogo.jogo_estado: self.screen.fill((200, 100, 100), self.screen.get_rect()) self.screen.blit(self.background_init, self.background_init.get_rect()) self.play_botao.draw_botao() self.ranking_botao.draw_botao() if not self.ranking_botao_clicado: pygame.display.flip() def run_game(self): print('Jogo iniciado ...') self.tela_inicial() # estado_jogo.jogo_estado = False while True: gf.check_events(self.ai_settings, self.screen, self.mira, self.mira_colisor, self.painel_vacina, self.miras, self.viroses, self.estado_jogo.grupo_viroses, self.estado_jogo, self.pontuacao_placar, self.barra_tempo, self.play_botao, self.atualiza_movimento, self.atualiza_barra_tempo, self.ranking_botao, self.ranking_bd, self.sons, self.vetor_botoes) if self.ranking_botao.flag_click: self.ranking_botao.flag_click = False # ranking_tela(ranking_bd,screen, ai_settings, play_botao, ranking_botao) gf.ranking_tela(self.ranking_bd, self.screen, self.ai_settings, self.play_botao, self.ranking_botao) self.ranking_botao_clicado = True if self.estado_jogo.jogo_estado: self.funcao_desenha() if not self.estado_jogo.jogo_estado: # Tela recente fica visivel pygame.mouse.set_visible(True) else: pygame.mouse.set_visible(False) self.tela_inicial() gf.is_fim_jogo(self.barra_tempo, self.estado_jogo, self.ranking_bd, self.screen, self.play_botao, self.ranking_botao)