Código fonte para invasores

#!/usr/bin/python
# Invasores
# Escrito por: Nilo Menezes (nilo at nilo dot pro dot br)
# Data: 21 de Setembro de 2003
# Versão 0.5 - 22/09/2003
#               Funcionamento básico
# Versão 0.6 - 23/09/2003
#               Ajuste e comentários
#               Adição de som
#               Melhoria das rotinas de impresão
#               Bugs de fechamento corrigidos
#               Tratamento de eventos melhorados
# Versão 0.7 - 24/09/2003
#               Melhoria nos gráficos
#               Acentuação do texto: contribuição de Luís Braga (SciTE)
#               Imagem de título e fim feitas no GIMP
#               Novos gráficos
#               Recarga de Mísseis
#               Recarga de Resistência
#               Nivel de dificuldade progressivo (mais inimigos a cada segundo a cada 10 segundos) :-)
#               Redutor de tiro (só se dispara uma vez a cada 3 frames ou 1/10 s
# Versão 0.8 -  12/04/2004
#               Suporte à Joystick (aceleracao fixa)
#               Suporte à Mouse (aceleracao variavel - max 15)
#               ESC sai
#               M misses (+1000)
#               R resistencia (+1000)
# Versão 0.9 - 05/03/2005
#               # Fazendo # Limpeza no código
#               # Fazendo # Isolamento da SDL em classes especificas
#               Divisão das classes em vários arquivos
#               # Fazendo # Classe de recursos (som e imagem)
#               Correção do bug de Joystick [1157541]
#               Correção do bug de Som (para micros sem som) [1157542]
#               Correção de erro de path no Linux [1157558]
#               * - Alterna FullScreen
#               + - Próximo modo de vídeo
#               - - Modo de vídeo anterior
#               Estrelas cintilantes
# Versão 0.9.1 - 12/11/2006
#              Controlador de jogo implementado
#              Resolvido bug de controle com mouse
#              Melhor jogabilidade
#              Resolvido bug ao iniciar nova partida
#              Primeiros testes com traducao
#              Implemenaçao basica de fases
# Versão 0.9.2 - 17/11/2006
#              Adicionado espanhol e francês a lista de traduçao
# Versão 0.9.3 - 04/2007
# Versão 0.9.4 - 24/11/2007
#              Modificada posição inicial das naves
# Versão 0.9.9 - 01/04/2017
#              Migração para Python 3.6 e GitHub

# TODO: limpar o código
# TODO: reprojetar a engine de controle
# TODO: introduzir variabilidade de movimentos nos aliens
# TODO: criar telas de configuração
# TODO: níveis de dificuldade (fases)
# TODO: high score
# TODO: campo de força
# TODO: novas armas
# TODO: novos inimigos - boss

#   This file is part of Invasores.
#
#   Invasores is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   Invasores is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with Invasores; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Módulos do PyGame

import pygame
import pygame.joystick
from pygame.locals import *

# Módulos do Python


# Módulos do jogo
import traducao
import video
import naleatorios

from universo import *
from objetodojogo import *
from nave import *
from objetosbonus import *
from laser import *
from alienigena import *
from score import *


[documentos]class Invasores: """ Esta classe é responsavel pelo jogo em si. Toda customização deve ser feita aqui """ def __init__(self, tela): self.tamanho = tela self.eventos = {} self.comandos = {} self.universo = Universo(tela) self.video = self.universo.video self.carregue_imagens() self.sair = None self.jogador = Nave("Nave", [400, 400], self.iJogador) self.placar = ScoreComFPS("Placar", [0, 0]) self.placar.jogador = self.jogador self.universo.quadros = 30 self.universo.calcule_pontos = self.calcula_pontos self.video.titulo("Invasores") self.video.icone(video.carregue("ICONE", "nave2.bmp")) self.fases = (self.fase1, self.fase2) self.nova_partida() try: pygame.joystick.init() self.joystick = pygame.joystick.Joystick(0) self.joystick.init() except: pass self.sensibilidade_mouse = 5 self.inicializa_eventos() self.inicializa_comandos()
[documentos] def carregue_imagens(self): self.iJogador = video.carregue("NAVE", "img/nave.png") self.iMissil = video.carregue("TIRO", "img/laser.png") self.iInimigo = video.carregue("INIMIGO", "img/inimigo.png") self.iCaixaDeMisseis = video.carregue("CMISSIL", "img/caixademisseis.png") self.iCaixaDeResistencia = video.carregue("CRESITENCIA", "img/caixaderesistencia.png") self.logo = video.Imagem("LOGO", "img/Invasoreslogo.png") self.logo.ponto_croma(0, 0) self.fim_de_jogo = video.Imagem("FIMDEJOGO", "img/fimdejogo.png") self.fim_de_jogo.ponto_croma(0, 0)
[documentos] def mostra_texto(self, ttexto): texto = Texto("Texto", [-1, -1], ttexto, 80, 90, self.universo, (255, 0, 0)) texto.respire() self.universo.adicione(texto)
[documentos] def fase1(self): self.script = [ [0, self.mostra_texto, "fase1"], [30, self.cria_alienigena, 100, 50, 4, 3, [(3, 0, 120), (-3, 1, 120), (3, 0, 120), (-3, 2, 120)]], [31, self.cria_alienigena, 400, 50, 4, 3, [(5, 1, 120), (-5, 0, 120), (8, -1, 120), (-5, 2, 120)]], [250, self.cria_municao], [295, self.para_tempo_script, 1], [300, self.cria_alienigena, 100, 50, 10, 2, [(3, 0, 120), (-3, 1, 120), (3, 0, 120), (-3, 2, 120)]], [450, self.cria_municao], [495, self.para_tempo_script, 1], [500, self.cria_alienigena, 100, 50, 10, 4, [(4, 0, 120), (-4, 1, 120), (4, 0, 120), (-4, 2, 120)]], [700, self.cria_resistencia], [720, self.cria_municao], [895, self.para_tempo_script, 1], [800, self.cria_alienigena, 100, 50, 12, 4, [(5, 0, 120), (-5, 1, 120), (5, 0, 120), (-5, 2, 120)]], [810, self.cria_municao], [850, self.cria_municao], [895, self.para_tempo_script, 1], [900, None]]
[documentos] def fase2(self): self.script = [ [0, self.mostra_texto, "fase2"], [100, self.cria_alienigena, 100, 100, 6, 4, [(5, 3, 120), (-3, 1, 120), (3, -1, 120), (-5, -2, 120)]], [250, self.cria_municao], [295, self.para_tempo_script, 1], [300, self.cria_alienigena, 100, 100, 8, 6, [(5, 0, 120), (-3, 1, 120), (3, 0, 120), (-5, 2, 120)]], [450, self.cria_municao], [590, self.para_tempo_script, 1], [600, self.cria_alienigena, 100, 100, 8, 6, [(4, 0, 120), (-4, 1, 120), (4, 0, 120), (-4, 2, 120)]], [700, self.cria_resistencia], [895, self.para_tempo_script, 1], [900, self.cria_alienigena, 100, 100, 10, 6, [(6, 0, 120), (-6, 1, 120), (6, 0, 120), (-6, 2, 120)]], [1199, self.para_tempo_script, 1], [1200, self.mostra_texto, "venceu"], [1500, self.saida]]
[documentos] def faseT(self): self.script = [[0, self.mostra_texto, "fase1"], [5, self.faseTCriaalienigena], [200, self.faseTCriaalienigena], [400, self.faseTCriaalienigena], [1400, self.saida]]
[documentos] def cria_alienigena(self, xi, yi, c, l, script, xl=60, yl=60): for y in range(l): for x in range(c): a = Alienigena("Inimigo", [xi + x * xl, yi + y * yl], self.iInimigo) a.set_script(script) self.universo.adicione(a)
[documentos] def para_tempo_script(self, motivo): self.estado_tempo_script = motivo
[documentos] def incrementa_tempo_script(self): if self.estado_tempo_script == 0: self.tempo_script += 1 elif self.estado_tempo_script == 1: if Alienigena.alienigenas_vivos == 0: self.estado_tempo_script = 0
[documentos] def nova_partida(self): self.jogador.resistencia = 300 self.jogador.misseis = 300 self.jogador.pos = [400, 400] self.jogador.ix = 0 self.jogador.iy = 0 self.universo.score = 0 self.universo.objetos = [] self.universo.colisoes = {} self.universo.adicione(self.jogador) self.universo.adicione(self.placar) self.placar.respire() self.fase = 0 self.frame = 0 self.tempo_script = 0 Alienigena.alienigenas_vivos = 0
[documentos] def calcula_pontos(universo, a, b): if a.nome != b.nome: a.colida(b) b.colida(a) return a.valor + b.valor else: return 0
[documentos] def atira(self, evento=None): if self.jogador.misseis > 0 and self.frame - self.ultimo_tiro >= 5: self.universo.adicione(Laser("tiro", [self.jogador.pos[0] + 5, self.jogador.pos[1] - 30], self.iMissil)) self.universo.adicione(Laser("tiro", [self.jogador.pos[0] + self.jogador.lx - 15, self.jogador.pos[1] - 30], self.iMissil)) self.jogador.misseis -= 2 self.ultimo_tiro = self.frame
[documentos] def cria_municao(self, carga=100): caixa_m = ObjetosBonus("CaixaDeMisseis", [naleatorios.faixa(self.tamanho[0]), 10], self.iCaixaDeMisseis) caixa_m.carga = carga self.universo.adicione(caixa_m)
[documentos] def cria_resistencia(self, carga=100): caixa_r = ObjetosBonus("CaixaDeResistencia", [naleatorios.faixa(self.tamanho[0]), 10], self.iCaixaDeResistencia) caixa_r.carga = carga self.universo.adicione(caixa_r)
[documentos] def tela_inicial(self): self.universo.desenhe_fundo() self.universo.desenhe([-1, -1], self.logo.imagem) self.universo.escreva([-1, 450], traducao.pega("pressionequalquertecla"), (255, 255, 0), 24) self.universo.escreva([-1, 200], "[P]Português [E]English [S]Spañol [F]Français", (255, 255, 0), 24) self.universo.atualize() while True: for event in pygame.event.get(): if event.type == QUIT: return(1) if event.type == KEYDOWN or event.type == JOYBUTTONDOWN: teclas = pygame.key.get_pressed() if teclas[K_p]: traducao.dicionario("pt_br") if teclas[K_e]: traducao.dicionario("en") if teclas[K_s]: traducao.dicionario("es") if teclas[K_f]: traducao.dicionario("fr") self.nova_partida() return(0)
[documentos] def tela_fim_de_jogo(self): self.universo.desenhe([-1, -1], self.fim_de_jogo.imagem) self.universo.escreva([-1, 450], traducao.pega("pressionexour"), (255, 255, 0), 24) self.universo.atualize() while True: for event in pygame.event.get(): if event.type == QUIT: return True if event.type == KEYDOWN: teclas = pygame.key.get_pressed() if teclas[K_r]: return 0 elif teclas[K_x]: return True if event.type == JOYBUTTONDOWN: if event.button % 2 == 0: return False else: return True
[documentos] def movemouse(self, evento): if evento.rel[0] < -self.sensibilidade_mouse: self.jogador.move(1) elif evento.rel[0] > self.sensibilidade_mouse: self.jogador.move(0) if evento.rel[1] < -self.sensibilidade_mouse: self.jogador.move(3) elif evento.rel[1] > self.sensibilidade_mouse: self.jogador.move(2) if evento.buttons[0] == 1: # and c % 3 == 0: self.atira(evento)
[documentos] def movejoystick(self, evento): if event.axis == 0: if event.value > 0.0: self.jogador.ix = 5 elif event.value < -1.0: self.jogador.ix = -5 elif event.axis == 1: if event.value > 0.0: self.jogador.iy = 5 elif event.value < -1.0: self.jogador.iy = -5
[documentos] def inicializa_eventos(self): self.eventos[MOUSEBUTTONDOWN] = self.atira self.eventos[MOUSEMOTION] = self.movemouse self.eventos[JOYAXISMOTION] = self.movejoystick self.eventos[MOUSEBUTTONDOWN] = self.atira self.eventos[QUIT] = self.saida self.eventos[JOYBUTTONDOWN] = self.atira
# self.eventos[MOUSEBUTTONUP] # self.eventos[JOYBALLMOTION] # self.eventos[JOYBUTTONUP] # self.eventos[JOYHATMOTION]
[documentos] def esquerda(self): self.jogador.move(1)
[documentos] def direita(self): self.jogador.move(0)
[documentos] def cima(self): self.jogador.move(3)
[documentos] def baixo(self): self.jogador.move(2)
[documentos] def aumentamisseis(self): """Cheat para aumentar o número de mísseis do jogador em 1000""" self.jogador.misseis += 1000
[documentos] def aumentaresistencia(self): """Cheat para aumentar a resistência do jogador em 1000 pontos""" self.jogador.resistencia += 1000
[documentos] def inicializa_comandos(self): self.comandos[K_LEFT] = self.esquerda self.comandos[K_RIGHT] = self.direita self.comandos[K_UP] = self.cima self.comandos[K_DOWN] = self.baixo self.comandos[K_SPACE] = self.atira self.comandos[K_x] = self.saida self.comandos[K_ESCAPE] = self.saida self.comandos[K_m] = self.aumentamisseis self.comandos[K_r] = self.aumentaresistencia self.comandos[K_KP_PLUS] = self.video.proximo_modo self.comandos[K_PLUS] = self.video.proximo_modo self.comandos[K_EQUALS] = self.video.proximo_modo self.comandos[K_KP_MINUS] = self.video.anterior_modo self.comandos[K_MINUS] = self.video.anterior_modo self.comandos[K_KP_MULTIPLY] = self.video.faz_tela_cheia self.comandos[K_ASTERISK] = self.video.faz_tela_cheia self.comandos[K_8] = self.video.faz_tela_cheia
[documentos] def saida(self, evento=None): self.sair = True
[documentos] def carrega_fase(self): self.frame = 0 self.estado_tempo_script = 0 self.tempo_script = 0 self.ultimo_tiro = 0 self.fases[self.fase]()
[documentos] def avanca_fase(self): self.fase += 1 if self.fase == len(self.fases): return False else: self.carrega_fase() return True
[documentos] def repeticao_do_jogo(self): """ Loop principal do jogo. Apaga a tela, carrega a fase e repete até o jogador morrer ou escolher para sair. """ self.universo.desenhe_fundo() self.sair = False self.carrega_fase() pos_script = 0 while self.jogador.resistencia > 0 and not self.sair: self.frame += 1 self.incrementa_tempo_script() while True: event = pygame.event.poll() if event.type == NOEVENT: break if event.type in self.eventos: self.eventos[event.type](event) # Pega todas as teclas pressionadas no momento teclas = pygame.key.get_pressed() # Verifica se cada tecla com comando foi pressionada for comando in self.comandos.keys(): if teclas[comando]: # Chama o gerenciador da tecla self.comandos[comando]() # Processa as instruções da fase tempo, funcao, *parametros = self.script[pos_script] if self.script[pos_script][0] <= self.tempo_script: if funcao: funcao(*parametros) #exec(self.script[pos_script][1]) pos_script += 1 if pos_script == len(self.script): pos_script = 0 if not self.avanca_fase(): return 0 self.universo.desenhe_fundo() self.universo.desenhe_objetos() self.universo.atualize() self.universo.finalize_sincronia() self.universo.desenhe_fundo() self.placar.respire() self.universo.desenhe_objetos() self.universo.atualize() return self.sair
# Jogo - Principal
[documentos]def jogo(): """ Cria o loop do jogo. Alterna entre os três estados principais do invasores: - :meth:`Invasores.tela_inicial` - :meth:`Invasores.repeticao_do_jogo` - :meth:`Invasores.tela_fim_de_jogo` O usuário pode pressionar X para sair em qualquer tela. """ try: # Cria o jogo em uma janela de 800x600 jogo = Invasores([800, 600]) # Esconde o mouse pygame.mouse.set_visible(0) # Loop principal do Jogo while True: if jogo.tela_inicial(): break # Ativa captura eventos pygame.event.set_grab(1) jogo.nova_partida() if jogo.repeticao_do_jogo(): break # Desativa captura eventos pygame.event.set_grab(0) if jogo.tela_fim_de_jogo(): break finally: pygame.display.quit()
if __name__ == "__main__": # Carrega o dicionário padrão, no caso, Português do Brasil traducao.dicionario("pt_br") # traducao.dicionario("en") jogo() # profile.run("jogo()")