diff --git a/.gitignore b/.gitignore index cd2946a..11f6837 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,6 @@ $RECYCLE.BIN/ # Thumbnails ._* -# Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 @@ -45,3 +44,6 @@ $RECYCLE.BIN/ Network Trash Folder Temporary Items .apdisk + +*.pyc +*.ini \ No newline at end of file diff --git a/config.ini.example b/config.ini.example new file mode 100644 index 0000000..51771e5 --- /dev/null +++ b/config.ini.example @@ -0,0 +1,5 @@ +[saveconf] +savepath = MUDAR +filename = .highscores + + diff --git a/config_manager.py b/config_manager.py new file mode 100644 index 0000000..e4e389d --- /dev/null +++ b/config_manager.py @@ -0,0 +1,35 @@ +# encoding: utf-8 +import ConfigParser +from hex_encoding import randomstring +from singleton import Singleton + +CONFIG_FILE = 'config.ini' +APPKEY = 'appkey' + + +class ConfigManager(object): + __metaclass__ = Singleton + + def __init__(self): + self.configuration = ConfigParser.ConfigParser() + + def load(self): + self.configuration.read(CONFIG_FILE) + + def get_session(self, session): + items = self.configuration.options(session) + session_dict = {} + for item in items: + session_dict.update( + dict.fromkeys([item], self.__get_config(session, item))) + return session_dict + + def generate_appkey(self, session): + key = randomstring(6) + self.configuration.set(session, APPKEY, key) + with open(CONFIG_FILE, 'w+') as config_file: + self.configuration.write(config_file) + return key + + def __get_config(self, session, key): + return self.configuration.get(session, key) diff --git a/flappyladies.py b/flappyladies.py index b55d9eb..af8fa79 100644 --- a/flappyladies.py +++ b/flappyladies.py @@ -1,185 +1,197 @@ -import pygame -import random - -# Inicialização do pygame -pygame.init() - -# Tamanho e nome da janela -screen = pygame.display.set_mode([700,497]) -pygame.display.set_caption("FlapPyLadies") - -# Frame por segundo -clock = pygame.time.Clock() - -# Carrega imagens e efeitos sonoros -img_player = pygame.image.load('img/player.png') -img_wallup = pygame.image.load('img/img_wallup.png') -img_walldown = pygame.image.load('img/img_walldown.png') -img_gameover = pygame.image.load('img/gameover.png') -img_bg1 = pygame.image.load('img/bg.jpg') -img_bg2 = pygame.image.load('img/bg.jpg') -img_start = pygame.image.load('img/start.png') -img_logo = pygame.image.load('img/logoPython.png') -jump = pygame.mixer.Sound('sounds/jump.wav') -hit = pygame.mixer.Sound('sounds/explode.wav') -jump.set_volume(0.1) -hit.set_volume(0.1) - -# Funçoes para desenhar objetos na tela -def player(player_area): - #pygame.draw.rect(screen, [0,0,0], player_area) - screen.blit(img_player, player_area) - -#def wall(wallup, walldown): -def wall(): - #pygame.draw.rect(screen, [0,255,0], wallup) - #pygame.draw.rect(screen, [0,255,0], walldown) - screen.blit(img_wallup, [wall_locx, wall_alt - 500]) - screen.blit(img_walldown, [wall_locx, wall_alt + dist]) - -def score(points): - font = pygame.font.Font('fonts/geo.ttf', 55) - text = font.render(str(points), True, [255,255,255]) - screen.blit(text, [350,20]) - -# Funçao para exibir a introduçao -def intro(): - screen.fill([255, 255, 255]) - screen.blit(img_logo, [40, 300]) - screen.blit(img_start, [170, 50]) - pygame.display.update() - pygame.time.wait(2000) - -# # # VARIAVEIS # # # -# Janela esta aberta ou fechada -close = False -# Jogador -playerx = 350 # Posiçao inicial -playery = 250 -# Velocidade inicial do jogador -speed = 5 -# Obstaculo -wall_locx = 700 #localizaçao -wall_larg = 70 # tamanho -wall_alt = random.randint(0, 350) -dist = 150 -speedwall = 4 -up = 0 -down = 450 -# Pontuaçao -points = 0 -# Jogar novamente -gameover = False -# Imagem de fundo -Img = 1320 -posImg = 0 - -intro() - -# # # Loop do jogo # # # -while not close: - - #Inicio FOR - # Reconhece eventos do jogador (mouse e teclado) - for event in pygame.event.get(): - if event.type == pygame.QUIT: - close = True - # Apertar uma tecla - if event.type == pygame.KEYDOWN: - # Aperta Tecla "espaço" - if event.key == pygame.K_SPACE: - jump.play() - speed = -10 - # Solta Tecla "espaço" - if event.type == pygame.KEYUP: - if event.key == pygame.K_SPACE: - speed = 5 - - # # # BACKGROUND # # # - #screen.fill([255,255,255]) - screen.blit(img_bg1, (posImg, 0)) - screen.blit(img_bg2, (posImg + Img, 0)) - posImg -= 2 # Velocidade - if posImg * -1 == Img: #Recomeçar - posImg = 0 - - # # # JOGADOR # # # - # Cria jogador (retangulo para colisao) - player_area = pygame.Rect(playerx, playery, 45, 45) - # Desenha jogador - player(player_area) - # Incrementa a posiçao y do jogador - playery += speed - - # # # OBSTACULO # # # - # Cria obstaculo - wallup = pygame.Rect(wall_locx, 0, wall_larg, wall_alt) - walldown = pygame.Rect(wall_locx, (wall_alt + dist), wall_larg, wall_alt + 500) - # Desenha obstaculo - #wall(wallup, walldown) - wall() - # Decrementa a posição x do obstaculo - wall_locx -= speedwall - # Cria mais obstaculos - if wall_locx < -60: - wall_locx = 700 - wall_alt = random.randint(0, 350) - - # # # PONTUAÇÃO # # # - # Desenha pontos - score(points) - # Conta pontos - if playerx == wall_locx + wall_larg: - points += 1 - - # # # COLISAO # # # - if (playery > down or playery < up): - hit.play() - speed = 0 - speedwall = 0 - gameover = True - - if player_area.colliderect(wallup) or player_area.colliderect(walldown): - hit.play() - speed = 0 - speedwall = 0 - gameover = True - - # Atualiza o fundo - pygame.display.flip() - clock.tick(60) - - # # # JOGAR NOVAMENTE # # # - while gameover: - pygame.time.wait(300) - for event in pygame.event.get(): - if event.type == pygame.QUIT: - close = True - gameover = False - # Apertar uma tecla - if event.type == pygame.KEYDOWN: - # Aperta Tecla "espaço" - if event.key == pygame.K_SPACE: - # Jogador - playerx = 350 # Posiçao inicial - playery = 250 - # Velocidade inicial do jogador - speed = 0 - # Obstaculo - wall_locx = 700 #localizaçao - wall_alt = random.randint(0, 350) - speedwall = 4 - # Pontuaçao - points = 0 - # Jogar novamente - gameover = False - - # Imagem game over - screen.fill([255,255,255]) - screen.blit(img_gameover, (175,20)) - font = pygame.font.Font('fonts/geo.ttf', 40) - text = font.render(str(points), True, [238,37,79]) - screen.blit(text, [410,43]) - pygame.display.flip() - -pygame.quit() +# encoding: utf-8 +import pygame +import random +from score_manager import ScoreManager + +# Carregar arquivo de highscores +score_manager = ScoreManager() +score_manager.initialize() + +# Inicialização do pygame +pygame.init() + +# Tamanho e nome da janela +screen = pygame.display.set_mode([700,497]) +pygame.display.set_caption("FlapPyLadies") + +# Frame por segundo +clock = pygame.time.Clock() + +# Carrega imagens e efeitos sonoros +img_player = pygame.image.load('img/player.png') +img_wallup = pygame.image.load('img/img_wallup.png') +img_walldown = pygame.image.load('img/img_walldown.png') +img_gameover = pygame.image.load('img/gameover.png') +img_bg1 = pygame.image.load('img/bg.jpg') +img_bg2 = pygame.image.load('img/bg.jpg') +img_start = pygame.image.load('img/start.png') +img_logo = pygame.image.load('img/logoPython.png') +jump = pygame.mixer.Sound('sounds/jump.wav') +hit = pygame.mixer.Sound('sounds/explode.wav') +jump.set_volume(0.1) +hit.set_volume(0.1) + +# Funçoes para desenhar objetos na tela +def player(player_area): + #pygame.draw.rect(screen, [0,0,0], player_area) + screen.blit(img_player, player_area) + +#def wall(wallup, walldown): +def wall(): + #pygame.draw.rect(screen, [0,255,0], wallup) + #pygame.draw.rect(screen, [0,255,0], walldown) + screen.blit(img_wallup, [wall_locx, wall_alt - 500]) + screen.blit(img_walldown, [wall_locx, wall_alt + dist]) + + +def score(points): + font = pygame.font.Font('fonts/geo.ttf', 55) + text = font.render("Score: " + str(points), True, [255, 255, 255]) + highscores = font.render( + "Highest: " + str(score_manager.highscore), True, [255, 255, 255]) + screen.blit(text, [40, 20]) + screen.blit(highscores, [300, 20]) + + +# Funçao para exibir a introduçao +def intro(): + screen.fill([255, 255, 255]) + screen.blit(img_logo, [40, 300]) + screen.blit(img_start, [170, 50]) + pygame.display.update() + pygame.time.wait(2000) + +# # # VARIAVEIS # # # +# Janela esta aberta ou fechada +close = False +# Jogador +playerx = 350 # Posiçao inicial +playery = 250 +# Velocidade inicial do jogador +speed = 5 +# Obstaculo +wall_locx = 700 #localizaçao +wall_larg = 70 # tamanho +wall_alt = random.randint(0, 350) +dist = 150 +speedwall = 4 +up = 0 +down = 450 +# Pontuaçao +points = 0 +# Jogar novamente +gameover = False +# Imagem de fundo +Img = 1320 +posImg = 0 + +intro() + +# # # Loop do jogo # # # +while not close: + + #Inicio FOR + # Reconhece eventos do jogador (mouse e teclado) + for event in pygame.event.get(): + if event.type == pygame.QUIT: + close = True + # Apertar uma tecla + if event.type == pygame.KEYDOWN: + # Aperta Tecla "espaço" + if event.key == pygame.K_SPACE: + jump.play() + speed = -10 + # Solta Tecla "espaço" + if event.type == pygame.KEYUP: + if event.key == pygame.K_SPACE: + speed = 5 + + # # # BACKGROUND # # # + #screen.fill([255,255,255]) + screen.blit(img_bg1, (posImg, 0)) + screen.blit(img_bg2, (posImg + Img, 0)) + posImg -= 2 # Velocidade + if posImg * -1 == Img: #Recomeçar + posImg = 0 + + # # # JOGADOR # # # + # Cria jogador (retangulo para colisao) + player_area = pygame.Rect(playerx, playery, 45, 45) + # Desenha jogador + player(player_area) + # Incrementa a posiçao y do jogador + playery += speed + + # # # OBSTACULO # # # + # Cria obstaculo + wallup = pygame.Rect(wall_locx, 0, wall_larg, wall_alt) + walldown = pygame.Rect(wall_locx, (wall_alt + dist), wall_larg, wall_alt + 500) + # Desenha obstaculo + #wall(wallup, walldown) + wall() + # Decrementa a posição x do obstaculo + wall_locx -= speedwall + # Cria mais obstaculos + if wall_locx < -60: + wall_locx = 700 + wall_alt = random.randint(0, 350) + + # # # PONTUAÇÃO # # # + # Desenha pontos + score(points) + # Conta pontos + if playerx == wall_locx + wall_larg: + points += 1 + score_manager.save_score(points) + + # # # COLISAO # # # + if (playery > down or playery < up): + hit.play() + speed = 0 + speedwall = 0 + gameover = True + + if player_area.colliderect(wallup) or player_area.colliderect(walldown): + hit.play() + speed = 0 + speedwall = 0 + gameover = True + + # Atualiza o fundo + pygame.display.flip() + clock.tick(60) + + # # # JOGAR NOVAMENTE # # # + while gameover: + pygame.time.wait(300) + for event in pygame.event.get(): + if event.type == pygame.QUIT: + close = True + gameover = False + # Apertar uma tecla + if event.type == pygame.KEYDOWN: + # Aperta Tecla "espaço" + if event.key == pygame.K_SPACE: + # Jogador + playerx = 350 # Posiçao inicial + playery = 250 + # Velocidade inicial do jogador + speed = 0 + # Obstaculo + wall_locx = 700 #localizaçao + wall_alt = random.randint(0, 350) + speedwall = 4 + # Pontuaçao + points = 0 + # Jogar novamente + gameover = False + + # Imagem game over + screen.fill([255,255,255]) + screen.blit(img_gameover, (175,20)) + font = pygame.font.Font('fonts/geo.ttf', 40) + text = font.render(str(points), True, [238,37,79]) + screen.blit(text, [410,43]) + pygame.display.flip() + +pygame.quit() diff --git a/hex_encoding.py b/hex_encoding.py new file mode 100644 index 0000000..58bfb4a --- /dev/null +++ b/hex_encoding.py @@ -0,0 +1,28 @@ +# encoding: utf-8 +import base64 +import random +import string + + +def randomstring(size): + return ''.join( + random.sample((string.ascii_uppercase + string.digits), size)) + + +def encode(key, clear): + enc = [] + for i in range(len(clear)): + key_c = key[i % len(key)] + enc_c = chr((ord(clear[i]) + ord(key_c)) % 256) + enc.append(enc_c) + return base64.urlsafe_b64encode("".join(enc)) + + +def decode(key, enc): + dec = [] + enc = base64.urlsafe_b64decode(enc) + for i in range(len(enc)): + key_c = key[i % len(key)] + dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) + dec.append(dec_c) + return "".join(dec) diff --git a/score_manager.py b/score_manager.py new file mode 100644 index 0000000..836ed4b --- /dev/null +++ b/score_manager.py @@ -0,0 +1,59 @@ +# encoding: utf-8 +import json +import os +from hex_encoding import (encode, decode) +from config_manager import (ConfigManager, APPKEY) + + +CONFIG_SESSION = 'saveconf' + + +class ScoreManager(object): + + def __init__(self): + self.configuration = ConfigManager() + + def initialize(self): + self.configuration.load() + self.saveconfigs = self.configuration.get_session(CONFIG_SESSION) + self.savefolder = self.saveconfigs.get('savepath') + self.filepath = os.path.join(self.savefolder, + self.saveconfigs.get('filename')) + + self.code_key = self.__retrieve_appkey() + self.load_score() + + def load_score(self): + if os.path.exists(self.filepath): + with open(self.filepath, 'r') as savefile: + self.highscore = self.__read(savefile) + else: + if not os.path.exists(self.savefolder): + os.makedirs(self.savefolder) + self.highscore = 0 + self.save_score(self.highscore) + + def save_score(self, points): + if points < self.highscore: + return + + with open(self.filepath, 'w+') as savefile: + scores = { + "highscores": points + } + self.__write(savefile, json.dumps(scores)) + self.highscore = points + + def __retrieve_appkey(self): + appkey = self.saveconfigs.get(APPKEY) + if not appkey: + return self.configuration.generate_appkey(CONFIG_SESSION) + return appkey + + def __write(self, savefile, scores): + string_scores = encode(self.code_key, str(scores)) + savefile.write(string_scores) + + def __read(self, savefile): + string_scores = decode(self.code_key, savefile.read()) + return json.loads(string_scores).get('highscores') diff --git a/singleton.py b/singleton.py new file mode 100644 index 0000000..2d35c93 --- /dev/null +++ b/singleton.py @@ -0,0 +1,16 @@ +# encoding: utf-8 + + +class Singleton(type): + _instances = {} + + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + cls._instances[cls] = super( + Singleton, cls).__call__(*args, **kwargs) + cls.dispatch = cls.__dispatch + return cls._instances[cls] + + @classmethod + def __dispatch(cls): + cls._instances = {} # pragma: no cover