class Reproductor(): """ Reproduce un clip ya realizado """ def __init__(self, pantalla, ancho, alto, usuario, clip): # Valores por defecto self.pantalla = pantalla self.ANCHO = ancho self.ALTO = alto self.clip_elegido = clip # Usuario self.usuario = usuario # Secuencia de imagenes self.pos_img = 0 self.loop = False self.fin = False self.duracion_img = -1 self.auxiliar = 0 # Colores self.NEGRO = (0, 0, 0) self.ROJO = (244, 36, 40) self.OXFORD_BLUE = (3, 15, 69) self.VERDE = (79, 170, 90) self.DEEP_CARMINE = (170, 40, 57) self.BLANCO = (241, 241, 241) self.CELESTE_LINDO = (40, 152, 178) self.BLANCO_LINDO = (253, 250, 251) self.TIGERS_EYE = (224, 159, 62) self.VERDE_FUERTE = (51, 255, 51) self.GRIS = (194, 214, 214) # Fuentes self.font_45 = pygame.font.SysFont('Bank Gothic', 45) self.font_20 = pygame.font.SysFont('Bank Gothic', 20) # herramientas self.tools = Tools(self.pantalla) self.tamanio_img = (724, 620) self.cargar_datos_usuario() self.interfaz() def limpiar_pantalla(self): self.caja_pantalla = pygame.draw.rect( self.pantalla, self.BLANCO, (self.pantalla.get_rect().centerx - 724 / 2, 0, 724, 620)) def cargar_datos_usuario(self): """ Carga los datos almacenados en el json del usuario """ arch = open(os.path.join(os.getcwd(), 'archivos', 'usuarios.json'), 'r') self.datos = json.load(arch) self.clip = self.datos[self.usuario][self.clip_elegido] arch.close() def comenzar_musica(self): """ inicializa la musica en el clip """ if self.clip['musica']['ruta'] and not self.fin: if pygame.mixer.music.get_busy(): # Si ya hay música, renaudo pygame.mixer.music.unpause() else: # Si no hay música, reproduzco desde 0 pygame.mixer.music.load(self.clip['musica']['ruta']) pygame.mixer.music.play( loops=-1 if self.clip['musica']['loop'] else 0) def play(self): """ Inicia el reloj y comienza a reproducir las imágenes """ self.inicio = time.time() time.clock() self.avanzar_imagen() def pausa(self): """ Setea la duración de la imagen para la próxima vez que aprieten play. Así completa lo que le falta. """ # print('PAUSA',self.auxiliar) self.duracion_img = self.auxiliar def cambiar_imagen(self, duracion): """ Retorna si hay que cambiar o no de imagen """ if self.clip['imagenes']: segundos = int(time.time() - self.inicio) self.auxiliar = duracion - segundos # print(duracion, '-', segundos, '=', duracion - segundos) return duracion - segundos < 0 and not self.fin else: return False def avanzar_imagen(self): """ Reproduce las imagenes """ # Si hay que cambiar la imagen if self.cambiar_imagen(self.duracion_img): # Si no terminó el clip if (self.pos_img < len(self.clip['imagenes'])): # Inicia el RELOJ self.inicio = time.time() time.clock() imagen_actual = self.clip['imagenes'][self.pos_img] # Carga la imagen self.img = pygame.image.load(imagen_actual['directorio']) # Muestra la imagen self.pantalla.blit(self.img, self.caja_pantalla.topleft) # Reproduce el sonido if imagen_actual['sonido']: pygame.mixer.Sound(imagen_actual['sonido']).play() self.duracion_img = int( self.clip['imagenes'][self.pos_img]['duracion']) self.pos_img += 1 elif self.loop: self.pos_img = 0 else: self.fin = True def fin_clip(self, texto): """ Indicador de fin del clip """ self.fin = True self.pos_img = 0 # Avisa que terminó self.limpiar_pantalla() self.tools.sombrear(texto, self.NEGRO, self.VERDE, self.font_45, self.caja_pantalla) # Para la música pygame.mixer.music.fadeout(500) # Actualiza la pantalla para no perder el tiempo congelado pygame.display.update() time.sleep(2) def interfaz(self): """ Interfaz del reproductor """ # Opacidad opacidad = pygame.Surface((self.ANCHO, self.ALTO), pygame.SRCALPHA) opacidad.fill((26, 26, 26, 180)) self.pantalla.blit(opacidad, (0, 0)) # Cajas self.limpiar_pantalla() self.caja_botones = pygame.draw.rect( self.pantalla, (26, 26, 26), (0, self.ALTO - 100, self.ANCHO, 100)) # Botones para reproducir self.img_play = pygame.image.load(os.path.join('imagenes', 'play.png')) self.img_pausa = pygame.image.load( os.path.join('imagenes', 'pausa.png')) self.img_stop = pygame.image.load(os.path.join('imagenes', 'stop.png')) self.img_loop = pygame.image.load( os.path.join('imagenes', 'loop_off.png')) # Rectángulos de los botones self.atras = pygame.draw.rect( self.pantalla, self.DEEP_CARMINE, (self.pantalla.get_rect().width - 80, 0, 80, 30)) self.tools.sombrear('Atrás', self.BLANCO, self.OXFORD_BLUE, self.font_20, self.atras) self.rect_play = self.img_play.get_rect().move( 20, self.caja_botones.centery - self.img_play.get_height() / 2) self.rect_pausa = self.img_pausa.get_rect().move( 100, self.caja_botones.centery - self.img_play.get_height() / 2) self.rect_stop = self.img_stop.get_rect().move( 180, self.caja_botones.centery - self.img_play.get_height() / 2) self.rect_loop = self.img_loop.get_rect().move( self.tools.centrar(self.caja_botones, self.img_stop)) # Renderizado self.pantalla.blit( self.img_play, (20, self.caja_botones.centery - self.img_play.get_height() / 2)) self.pantalla.blit( self.img_pausa, (100, self.caja_botones.centery - self.img_play.get_height() / 2)) self.pantalla.blit( self.img_stop, (180, self.caja_botones.centery - self.img_play.get_height() / 2)) self.pantalla.blit( self.img_loop, (self.tools.centrar(self.caja_botones, self.img_stop))) # Clicks self.clicks = { 'play': (self.rect_play, 0), 'loop': (self.rect_loop, 0), 'pausa': (self.rect_pausa, 0), 'stop': (self.rect_stop, 0), 'atras': (self.atras, 0) } def actualizar_loop(self): """ Le da comportamiento al boton de loop """ # Limpio el sector rect = pygame.draw.rect(self.pantalla, (26, 26, 26), self.rect_loop.topleft + self.rect_loop.size) # Informo al usuario si el loop está activado img = 'loop_off.png' if self.loop else 'loop_on.png' self.img_loop = pygame.image.load(os.path.join('imagenes', img)) self.pantalla.blit( self.img_loop, (self.tools.centrar(self.caja_botones, self.img_stop))) # Actualizo estado del loop self.loop = not self.loop def chequear_botones(self, mouse): return self.tools.consulta_botones(mouse, self.clicks)
class ArmarClip(): """ Permite la creacion del clip a traves de la seleccion y edición de imagenes """ def __init__(self, pantalla, ancho, alto, usuario): """ Valores por defecto de la pestaña """ # Pantalla self.ALTO = alto self.ANCHO = ancho self.pantalla = pantalla # Colores self.NEGRO = (0, 0, 0) self.ROJO = (244, 36, 40) self.OXFORD_BLUE = (3, 15, 69) self.VERDE = (79, 170, 90) self.DEEP_CARMINE = (170, 40, 57) self.BLANCO = (241, 241, 241) self.CELESTE_LINDO = (40, 152, 178) self.BLANCO_LINDO = (253, 250, 251) self.TIGERS_EYE = (224, 159, 62) self.VERDE_FUERTE = (51, 255, 51) self.GRIS = (194, 214, 214) # Fuente self.font_50 = pygame.font.SysFont('Bank Gothic', 70) self.font_30 = pygame.font.SysFont('Bank Gothic', 30) self.font_20 = pygame.font.SysFont('Bank Gothic', 20) # Inicializaciones self.tools = Tools(self.pantalla) self.interfaz() # Usuario self.usuario = usuario def interfaz(self): """ Manejo de la intefaz principal """ # Tamaños formato x-y self.rec_pequeño = (100, 50) self.rec_medio = ((self.ANCHO - 300) / 3 - 20, 50) self.rec_grande = (self.ANCHO - 300, 75) self.cuadrado = ((self.ANCHO - 300) / 3 - 20, (self.ANCHO - 300) / 3 - 20) # Botones principales self.botones() # Render del texto sobre los botones self.texto_botones() # Grilla de rectangulos para las imagenes self.grilla_imagenes() def botones(self): """ Coloca los botones sobre la pantalla """ self.musica = pygame.draw.rect( self.pantalla, self.ROJO, (self.ANCHO / 2 - self.rec_medio[0] / 2, 10) + self.rec_medio) self.imagenes = pygame.draw.rect( self.pantalla, self.ROJO, (self.ANCHO / 2 - self.rec_grande[0] / 2, 75) + self.rec_grande) self.finalizar = pygame.draw.rect(self.pantalla, self.VERDE, (self.ANCHO - 100, self.ALTO - 50) + self.rec_pequeño) self.atras = pygame.draw.rect(self.pantalla, self.DEEP_CARMINE, (0, self.ALTO - 50) + self.rec_pequeño) self.pos_titulo = self.imagenes.topleft # Opciones de imagenes self.predefinidas = pygame.draw.rect(self.pantalla, self.DEEP_CARMINE, (self.pos_titulo[0] + 10, 150) + self.rec_medio) self.camara = pygame.draw.rect( self.pantalla, self.CELESTE_LINDO, (self.pos_titulo[0] + 10 + 2 * self.imagenes.width / 3, 150) + self.rec_medio) self.caja_buscar() self.caja_de_imagenes() def texto_botones(self): """ Render del texto sobre los botones """ self.clicks = { 'Elegir Musica': (self.musica, self.font_30), 'AGREGAR IMAGENES': (self.imagenes, self.font_50), 'Finalizar': (self.finalizar, self.font_30), 'Atras': (self.atras, self.font_30), 'Predefinidas': (self.predefinidas, self.font_30), 'Buscar': (self.buscar, self.font_30), 'Camara': (self.camara, self.font_30) } for clave, valor in self.clicks.items(): self.tools.sombrear(clave, self.BLANCO, self.OXFORD_BLUE, valor[1], valor[0]) def grilla_imagenes(self): """ Renderización de la grilla donde van a estar las imagenes """ pos = 0 self.pos_caja = self.caja_imagenes.topleft ejeY = self.pos_caja[1] self.grilla = [] for columna in range(2): for fila in range(3): img = pygame.draw.rect( self.pantalla, self.TIGERS_EYE, (self.pos_caja[0] + 10 + fila * self.imagenes.width / 3, ejeY + 10) + self.cuadrado) self.clicks[str(pos)] = (img, 0) self.grilla.append(img) pos += 1 ejeY += 240 def caja_de_imagenes(self): """Coloca la caja en donde van a estar las imagenes, se usa principalmente para limpiar""" self.caja_imagenes = pygame.draw.rect( self.pantalla, self.BLANCO_LINDO, (self.pos_titulo[0], self.pos_titulo[1] + 135, self.ANCHO - 300, 480)) def caja_buscar(self): """ Coloca la caja en donde el usuario va a escribir """ self.buscar = pygame.draw.rect( self.pantalla, self.VERDE, (self.pos_titulo[0] + 10 + self.imagenes.width / 3, 150) + self.rec_medio) # Funcionalidades def chequear_botones(self, pos_mouse): """ Identifica cual de los botones del menú fue presionado """ return self.tools.consulta_botones(pos_mouse, self.clicks) def actualizar_grilla(self, seccion): """ Inserta las imagenes del directorio de imagenes en la grilla """ # Limpio lo que haya: self.caja_de_imagenes() self.grilla_imagenes() # Actualizacion de imagenes: directorio = os.path.join(os.getcwd(), 'imagenes', seccion) list_dir = os.listdir(directorio) list_dir.sort() i = 0 for img in list_dir[:6]: imagen = pygame.image.load(os.path.join(directorio, img)) imagen = pygame.transform.scale(imagen, ((self.ANCHO - 300) // 3 - 20, (self.ANCHO - 300) // 3 - 20)) self.pantalla.blit(imagen, self.grilla[i].topleft) i += 1 def actualizar_camara(self): """ Saca una foto y la coloca en la caja de imagenes""" # Limpio lo que haya self.caja_de_imagenes() # Camara try: pygame.camera.init() self.cam = pygame.camera.Camera('/dev/video0', (640, 480), 'RGB') self.cam.start() self.captura = pygame.surface.Surface((640, 480), 0, self.pantalla) self.captura = self.cam.get_image(self.captura) pygame.image.save(self.captura, os.path.join('imagenes', 'camara', '0.jpg')) self.pantalla.blit(self.captura, (self.pos_caja[0] + 30, self.pos_caja[1])) self.cam.stop() except Exception: self.caja_de_imagenes() self.tools.sombrear( 'Se ha producido un error intentando obtener la camara lo sentimos...', self.NEGRO, self.BLANCO_LINDO, self.font_30, self.caja_imagenes) def interfaz_cancion(self): """ Muestra las canciones en pantalla """ self.caja_imagenes = pygame.draw.rect( self.pantalla, self.TIGERS_EYE, (self.pos_titulo[0], self.pos_titulo[1] + 135, self.ANCHO - 300, 480)) self.mostrar_canciones() def mostrar_canciones(self): """ Busca las canciones en el directorio y las imprime en pantalla """ # obtengo las canciones directorio_canciones = os.path.join('audio', 'canciones') canciones = os.listdir(directorio_canciones) canciones = list(sorted(canciones)) # las muestro en la grilla altura_fila = self.caja_imagenes.height / len(canciones) i = 0 for cancion in canciones: linea = pygame.draw.rect( self.pantalla, self.NEGRO, (self.caja_imagenes[0], self.caja_imagenes[1] + altura_fila * i) + (self.caja_imagenes.width, altura_fila), 1) elemento = self.font_30.render(cancion.rstrip('.ogg'), True, self.OXFORD_BLUE) self.pantalla.blit(elemento, (linea.topleft[0] + 20, linea.topleft[1] + 20)) self.clicks[str(i)] = (linea, 0) i += 1 def boton_loop(self): """ Boton que permite el loop de la cancion en el clip """ # me quedo con la pos del boton del loop pos = self.caja_imagenes.topright pos = (pos[0] + 20, pos[1] + 15) loop = pygame.draw.rect(self.pantalla, self.ROJO, pos + (30, 30)) texto_loop = self.font_30.render('Loop', True, self.BLANCO_LINDO) self.pantalla.blit(texto_loop, (loop.topright[0] + 5, loop.topright[1] + 8)) self.cancion_loop = False self.clicks['Loop'] = (loop, 0) def switch_loop(self): """ switch grafico del prendido y apagado del loop """ pos = self.caja_imagenes.topright pos = (pos[0] + 20, pos[1] + 15) if self.cancion_loop: pygame.draw.rect(self.pantalla, self.ROJO, pos + (30, 30)) self.cancion_loop = False else: pygame.draw.rect(self.pantalla, self.VERDE, pos + (30, 30)) self.cancion_loop = True def seleccionar_cancion(self, ruta, boton): """ Check al clickear una cancion """ self.interfaz_cancion() # tengo que poner el visto en la cancion que clickeó seleccion = pygame.image.load(os.path.join('imagenes', 'check_ok.png')) seleccion = pygame.transform.scale(seleccion, (50, 50)) pos_visto = self.clicks[boton][0].topright pos_visto = (pos_visto[0] - 60, pos_visto[1] + 5) self.pantalla.blit(seleccion, pos_visto) pygame.mixer.music.load(ruta) pygame.mixer.music.play() # Lógica del buscar: def espera(self, carga): """ Informa al usuario que se está realizando la búsqueda """ self.caja_de_imagenes() # Limpiar tamaniox = 200 / 6 * (carga + 1) # progreso de la barrita # Rectangulos: self.fondo_barrita = pygame.draw.rect( self.pantalla, self.GRIS, (self.caja_imagenes.centerx - 101, self.caja_imagenes.centery + 34, 202, 22)) self.contorno_barrita = pygame.draw.rect( self.pantalla, self.VERDE, (self.caja_imagenes.centerx - 101, self.caja_imagenes.centery + 34, 202, 22), 1) self.barrita = pygame.draw.rect( self.pantalla, self.VERDE_FUERTE, (self.caja_imagenes.centerx - 100, self.caja_imagenes.centery + 35, tamaniox, 20)) # Texto: self.tools.sombrear( 'Estamos buscando las imágenes, por favor espere . . .', self.NEGRO, self.BLANCO_LINDO, self.font_30, self.caja_imagenes) elemento = self.font_20.render( str(tamaniox * 100 // 200) + '%', True, self.NEGRO) pos = self.tools.centrar(self.contorno_barrita, elemento) self.pantalla.blit(elemento, pos) # Refresco: pygame.display.update() def buscar_enter(self): """Al presionar enter busca en Flickr""" try: self.buscar_Flickr(self.texto) self.actualizar_grilla('busqueda') except: self.caja_de_imagenes() self.tools.sombrear( 'Se ha producido un error con su busqueda, lo sentimos...', self.NEGRO, self.BLANCO_LINDO, self.font_30, self.caja_imagenes) def buscar_Flickr(self, texto): """ Busca en Flickr 6 imagenes y las guarda """ engine = Flickr(license=None, throttle=0.5, language='es') i = 0 for result in engine.search(texto, count=6, cached=True, copyright=False): self.espera(i) directorio = os.path.join('imagenes', 'busqueda', str(i) + extension(result.url)) f = open(directorio, 'wb') f.write(result.download(timeout=10)) f.close() i += 1 # Procesado del texto def comenzar_buscar(self): """ Limpia la caja buscar e inicializa el texto a capturar """ self.texto = '' self.renderizar_texto_buscar() def buscar_borrar(self): self.texto = self.texto[:-1] def dentro_limite(self, texto): """ Verifica si el texto no superó el limite de la caja que lo contiene """ return self.tools.centrar( self.buscar, self.font_30.render( texto, True, self.BLANCO))[0] - 20 > self.buscar.left def actualizar_texto(self, caracter): self.texto += caracter def renderizar_texto_buscar(self): """ Muestra el texto en la pantalla. Retorna si el límite fue o no superado. """ if (self.dentro_limite(self.texto)): # Limpio pantalla self.caja_buscar() pygame.draw.line(self.pantalla, self.NEGRO, (self.buscar.bottomleft[0] + 20, self.buscar.bottomleft[1] - 10), (self.buscar.bottomright[0] - 20, self.buscar.bottomright[1] - 10), 3) # Renderiza el texto self.tools.sombrear(self.texto, self.BLANCO, self.OXFORD_BLUE, self.font_30, self.buscar) return False else: return True
class Menu(): """Menu principal de la aplicación""" def __init__(self, pantalla, ancho, alto, usuario): """Valores por defecto propios del menú""" # Colores self.COLOR_FONDO_MENU = (179, 0, 0) self.ROJO = (244, 36, 40) self.BLANCO = (255, 230, 230) self.GRIS = (194, 214, 214) self.NEGRO = (0, 0, 0) self.OXFORD_BLUE = (3, 15, 69) self.NEGRO = (0, 0, 0) # Pantalla self.ANCHO = ancho self.ALTO = alto self.pantalla = pantalla # Fuentes self.font_72 = pygame.font.SysFont('monaco', 65) self.font_30 = pygame.font.SysFont('Bank Gothic', 30) # Inicializaciones self.tools = Tools(self.pantalla) self.clicks = {} self.usuario = usuario self.interfaz(self.pantalla) def interfaz(self, pantalla): if self.usuario == '': self.sesion(pantalla.get_rect()) else: self.botones(pantalla.get_rect()) def sesion(self, pantalla): """ Pone la interfaz del inicio de sesion del usuario """ pos_titulo = (pantalla.center[0] - 250, pantalla.center[1] - 200) self.titulo = pygame.draw.rect(self.pantalla, self.ROJO, pos_titulo + (500, 100)) self.tools.sombrear('Ingrese su nombre', self.GRIS, (0, 0, 0), self.font_72, self.titulo) self.limpiar_campo() self.clicks['campo'] = (self.campo, self.font_30) def limpiar_campo(self): """ Limpia el campo del input """ pos_campo = (self.titulo.bottomleft[0] - 100, self.titulo.bottomleft[1] + 20) self.campo = pygame.draw.rect(self.pantalla, self.BLANCO, pos_campo + (700, 100)) def comenzar_escribir(self): """ Limpia la caja campo e inicializa el texto a capturar """ self.texto = '' self.renderizar_texto_escrito() def renderizar_texto_escrito(self): """ Muestra el texto en la pantalla. Retorna si el límite fue o no superado. """ if (self.dentro_limite(self.texto)): # Limpio pantalla self.limpiar_campo() pygame.draw.line( self.pantalla, self.NEGRO, (self.campo.bottomleft[0] + 20, self.campo.bottomleft[1] - 10), (self.campo.bottomright[0] - 20, self.campo.bottomright[1] - 10), 3) # Renderiza el texto self.tools.sombrear(self.texto, self.OXFORD_BLUE, self.BLANCO, self.font_72, self.campo) return False else: return True def borrar(self): self.texto = self.texto[:-1] def actualizar_texto(self, caracter): self.texto += caracter def dentro_limite(self, texto): """ Verifica si el texto no superó el limite de la caja que lo contiene """ pos = self.tools.centrar(self.campo, self.font_72.render(texto, True, self.BLANCO)) return pos[0] - 20 > self.campo.left def enter(self): """Al presionar enter guarda o carga el usuario""" if self.texto == '': self.texto = 'anónimo' try: self.usuario = self.texto # Crea la carpeta del usuario en caso de no existir directorios = list( filter( lambda x: os.path.isdir( os.path.join(os.getcwd(), 'archivos', x)), os.listdir('archivos'))) if self.usuario not in directorios: os.mkdir(os.path.join('archivos', self.usuario)) else: self.aprobado() # Crea la carpeta temporal clip_temp = os.path.join('archivos', self.usuario, 'temp') if os.path.exists(clip_temp): # Si existe la carpeta, la elimina shutil.rmtree(clip_temp) os.mkdir(clip_temp) except FloatingPointError: pass def aprobado(self): """ Muestra el icono indicador de que el usuario existe """ icono = pygame.image.load(os.path.join('imagenes', 'check_ok.png')) icono = pygame.transform.scale(icono, (100, 100)) self.pantalla.blit(icono, self.campo.topright) pygame.display.update() def botones(self, pantalla): """ Renderizado de los botones de la secciones """ mis_clips = pygame.draw.rect( self.pantalla, self.COLOR_FONDO_MENU, (pantalla.centerx - 200, pantalla.centery - 150, 400, 100)) jugar = pygame.draw.rect( self.pantalla, self.COLOR_FONDO_MENU, (pantalla.centerx - 200, pantalla.centery + 50, 400, 100)) texto_clips = self.font_72.render('CLIPS', True, self.BLANCO) texto_jugar = self.font_72.render('JUGAR JUEGO', True, self.BLANCO) self.pantalla.blit(texto_clips, self.tools.centrar(mis_clips, texto_clips)) self.pantalla.blit(texto_jugar, self.tools.centrar(jugar, texto_jugar)) texto_boton = ['ARMAR CLIP', 'CARGAR CLIP', 'JUGAR JUEGO'] self.clicks['clips'] = (mis_clips, self.font_72) self.clicks['jugar juego'] = (jugar, self.font_72) def chequear_botones(self, pos_mouse): return self.tools.consulta_botones(pos_mouse, self.clicks)
class EditorClip(): """Permite modificar un clip ya realizado""" def __init__(self, pantalla, ancho, alto, usuario, clip_elegido): # .. self.pantalla = pantalla self.ANCHO = ancho self.ALTO = alto self.usuario = usuario self.clip_elegido = clip_elegido # Control de las imagenes self.pos_img = 0 # Colores self.NEGRO = (0, 0, 0) self.ROJO = (244, 36, 40) self.OXFORD_BLUE = (3, 15, 69) self.VERDE = (79, 170, 90) self.DEEP_CARMINE = (170, 40, 57) self.BLANCO = (241, 241, 241) self.CELESTE_LINDO = (40, 152, 178) self.BLANCO_LINDO = (253, 250, 251) self.TIGERS_EYE = (224, 159, 62) self.VERDE_FUERTE = (51, 255, 51) self.GRIS = (194, 214, 214) self.ROJO_CLARITO = (255, 153, 153) # Fuentes self.font_100 = pygame.font.SysFont('Bank Gothic', 100) self.font_45 = pygame.font.SysFont('Bank Gothic', 45) self.font_30 = pygame.font.SysFont('Bank Gothic', 30) self.font_20 = pygame.font.SysFont('Bank Gothic', 20) # Herramientas self.tools = Tools(self.pantalla) self.cargar_datos_usuario() self.interfaz() def cargar_datos_usuario(self): """Carga la información del clip elegido por el usuario mediante el JSON""" arch = open(os.path.join(os.getcwd(), 'archivos', 'usuarios.json'), 'r') self.datos = json.load(arch) self.clip = self.datos[self.usuario][self.clip_elegido] arch.close() def grilla(self): """Tagea los rectángulos en el diccionario de clicks""" tamanio = (800 // 3, 280) y = self.caja_principal.top + 10 for i in range(3): x = self.caja_principal.left + i * tamanio[0] + 5 rectangulo = pygame.draw.rect(self.pantalla, self.DEEP_CARMINE, (x, y) + (tamanio[0] - 10, tamanio[1])) self.clicks[str(i)] = (rectangulo, 0) def actualizar_imagenes(self): tamanio = (800 // 3, 280) lista_img = self.clip['imagenes'] y = self.caja_principal.top + 10 # Muestro las imagenes en los 3 rect de la grilla for i in range(3): x = self.caja_principal.left + i * tamanio[0] + 5 # Si está en el rango de las imagenes, la cargo y la muestro if (self.pos_img < len(lista_img)): img = pygame.image.load(lista_img[self.pos_img]['directorio']) img = pygame.transform.scale(img, (tamanio[0] - 10, tamanio[1])) self.pantalla.blit(img, (x, y)) else: # Muestra un rectángulo si no hay imágenes disponibles rectangulo = pygame.draw.rect(self.pantalla, self.DEEP_CARMINE, (x, y) + (tamanio[0] - 10, tamanio[1])) self.pos_img += 1 def interfaz(self): # Cajas titulo = pygame.draw.rect( self.pantalla, self.ROJO, (self.pantalla.get_rect().midtop[0] - 300, self.pantalla.get_rect().midtop[1] + 50, 600, 80)) finalizar = pygame.draw.rect(self.pantalla, self.VERDE, (self.ANCHO - 100, self.ALTO - 50) + (100, 50)) self.caja_principal = pygame.draw.rect( self.pantalla, self.BLANCO, (self.pantalla.get_rect().centerx - 800 / 2, self.pantalla.get_rect().centery - 350 / 2, 800, 300)) # Flechas self.f_izq = pygame.draw.rect( self.pantalla, self.ROJO_CLARITO, (self.caja_principal.left - 50, self.caja_principal.centery - 70 / 2, 50, 70)) self.f_der = pygame.draw.rect( self.pantalla, self.ROJO_CLARITO, (self.caja_principal.right, self.caja_principal.centery - 70 / 2, 50, 70)) # Texto self.tools.sombrear('«', self.BLANCO, self.NEGRO, self.font_100, self.f_izq) self.tools.sombrear('»', self.BLANCO, self.NEGRO, self.font_100, self.f_der) self.tools.sombrear('Editor de clip', self.BLANCO, self.NEGRO, self.font_100, titulo) self.tools.sombrear('Finalizar', self.BLANCO, self.OXFORD_BLUE, self.font_30, finalizar) # Clicks self.clicks = { 'izq': (self.f_izq, 0), 'der': (self.f_der, 0), 'finalizar': (finalizar, 0) } # Grilla self.grilla() # Imagenes self.actualizar_imagenes() # Funcionalidades def aumentar_imagenes(self): lista_img = self.clip['imagenes'] if (self.pos_img < len(lista_img)): self.actualizar_imagenes() def decrementar_imagenes(self): lista_img = self.clip['imagenes'] if (self.pos_img - 6 >= 0): self.pos_img -= 6 self.actualizar_imagenes() def chequear_botones(self, mouse): return self.tools.consulta_botones(mouse, self.clicks)
class JugarJuego(): """Adaptación del juego Snake realizado por el usuario apaar97""" def __init__(self, pantalla, ancho, alto, usuario): # Colores self.ROJO = pygame.Color(255, 0, 0) self.VERDE = pygame.Color(0, 255, 0) self.NEGRO = pygame.Color(0, 0, 0) self.BLANCO = pygame.Color(255, 255, 255) self.MARRON = pygame.Color(165, 42, 42) self.NEGRO_MATE = pygame.Color(26, 26, 26) # Pantalla self.pantalla = pantalla self.pantalla.fill(self.BLANCO) self.ALTO = alto self.ANCHO = ancho # Opciones del juego self.usuario = usuario self.delta = 10 self.snakePos = [100, 50] self.snakeBody = [[100, 50], [90, 50], [80, 50]] self.foodPos = [400, 50] self.foodSpawn = True self.direction = 'RIGHT' self.changeto = '' self.score = 0 # herramientas self.tools = Tools(self.pantalla) def mostrar_puntajes(self, a_json): """Muestra el mayor puntaje por usuario""" color = ((204, 0, 102), (128, 0, 0)) fuente = pygame.font.SysFont('monaco', 32) # Tabla tabla = pygame.draw.rect(self.pantalla, self.MARRON, (self.ANCHO / 2 - 250, self.ALTO / 2 - 150) + (500, 500)) # Encabezado rect_usuario = pygame.draw.rect( self.pantalla, color[0 % 2], (tabla.left, tabla.top, tabla.width / 3, tabla.height // 10)) rect_score = pygame.draw.rect(self.pantalla, color[0 % 2 - 1], (tabla.left + tabla.width / 3, tabla.top, tabla.width / 3, tabla.height // 10)) rect_tiempo = pygame.draw.rect( self.pantalla, color[0 % 2], (tabla.left + 2 * tabla.width / 3, tabla.top, tabla.width / 3, tabla.height // 10)) self.tools.sombrear('USUARIO', self.NEGRO_MATE, color[0 % 2], fuente, rect_usuario) self.tools.sombrear('SCORE', self.NEGRO_MATE, color[0 % 2 - 1], fuente, rect_score) self.tools.sombrear('FECHA', self.NEGRO_MATE, color[0 % 2], fuente, rect_tiempo) # Contenido i = 1 for clave, valor in a_json.items(): usuario = clave.upper() score = valor['score'] tiempo = valor['tiempo'] rect_usuario = pygame.draw.rect( self.pantalla, color[i % 2], (tabla.left, tabla.top + i * tabla.height // 10, tabla.width / 3, tabla.height // 10)) rect_score = pygame.draw.rect( self.pantalla, color[i % 2 - 1], (tabla.left + tabla.width / 3, tabla.top + i * tabla.height // 10, tabla.width / 3, tabla.height // 10)) rect_tiempo = pygame.draw.rect( self.pantalla, color[i % 2], (tabla.left + 2 * tabla.width / 3, tabla.top + i * tabla.height // 10, tabla.width / 3, tabla.height // 10)) self.tools.sombrear(usuario, self.BLANCO, color[i % 2 - 1], fuente, rect_usuario) self.tools.sombrear(str(score), self.BLANCO, color[i % 2], fuente, rect_score) self.tools.sombrear(tiempo, self.BLANCO, color[i % 2 - 1], fuente, rect_tiempo) i += 1 def actualizar_score(self): # Leo la lista de scores datos_usuario = { 'score': self.score, 'tiempo': datetime.now().strftime('%d-%m-%y %H:%M') } with open(os.path.join('archivos', 'score_snake.json'), 'r') as f: archivo = json.load(f) # Confirmo que el usuario existe y actualizo if self.usuario in archivo.keys(): if self.score > archivo[self.usuario]['score']: archivo[self.usuario] = datos_usuario else: archivo[self.usuario] = datos_usuario # Ordeno el archivo por puntaje archivo = dict( sorted(archivo.items(), key=lambda items: items[1]['score'], reverse=True)) with open(os.path.join('archivos', 'score_snake.json'), 'w') as f: json.dump( archivo, f, indent=4, ensure_ascii=False, ) # Armo la lista de puntajes en la pantalla self.mostrar_puntajes(archivo) def gameOver(self): '''Determina que hacer cuando el jugador perdió''' self.actualizar_score() self.perdi = True self.myFont = pygame.font.SysFont('monaco', 72) self.GOsurf = self.myFont.render("PERDISTE!", True, self.ROJO) self.GOrect = self.GOsurf.get_rect() self.GOrect.midtop = (self.ANCHO / 2, 80) self.pantalla.blit(self.GOsurf, self.GOrect) self.showScore(0) pygame.display.update() def showScore(self, choice=1): '''Muestra el puntaje del jugador en pantalla''' self.SFont = pygame.font.SysFont('monaco', 32) self.Ssurf = self.SFont.render("Score : {0}".format(self.score), True, self.NEGRO) self.Srect = self.Ssurf.get_rect() if choice == 1: self.Srect.midtop = (80, 10) else: self.Srect.midtop = (self.ANCHO / 2, 140) self.pantalla.blit(self.Ssurf, self.Srect) def chequear_eventos(self, event): '''Chequea los eventos para el movimiento de la viborita''' if event.type == pygame.KEYDOWN: if event.key == pygame.K_RIGHT or event.key == pygame.K_d: self.changeto = 'RIGHT' if event.key == pygame.K_LEFT or event.key == pygame.K_a: self.changeto = 'LEFT' if event.key == pygame.K_UP or event.key == pygame.K_w: self.changeto = 'UP' if event.key == pygame.K_DOWN or event.key == pygame.K_s: self.changeto = 'DOWN' def actualizar(self): '''Actualiza la pantalla, en caso de perder, devuelve True''' self.perdi = False # Validate direction if self.changeto == 'RIGHT' and self.direction != 'LEFT': self.direction = self.changeto if self.changeto == 'LEFT' and self.direction != 'RIGHT': self.direction = self.changeto if self.changeto == 'UP' and self.direction != 'DOWN': self.direction = self.changeto if self.changeto == 'DOWN' and self.direction != 'UP': self.direction = self.changeto # Update snake position if self.direction == 'RIGHT': self.snakePos[0] += self.delta if self.direction == 'LEFT': self.snakePos[0] -= self.delta if self.direction == 'DOWN': self.snakePos[1] += self.delta if self.direction == 'UP': self.snakePos[1] -= self.delta # Snake body mechanism self.snakeBody.insert(0, list(self.snakePos)) if self.snakePos == self.foodPos: self.foodSpawn = False self.score += 1 else: self.snakeBody.pop() if not self.foodSpawn: self.foodPos = [ random.randrange(1, self.ANCHO // 10) * self.delta, random.randrange(1, self.ALTO // 10) * self.delta ] self.foodSpawn = True self.pantalla.fill(self.BLANCO) for pos in self.snakeBody: pygame.draw.rect( self.pantalla, self.VERDE, pygame.Rect(pos[0], pos[1], self.delta, self.delta)) pygame.draw.rect( self.pantalla, self.MARRON, pygame.Rect(self.foodPos[0], self.foodPos[1], self.delta, self.delta)) # Bounds if self.snakePos[0] >= self.ANCHO or self.snakePos[0] < 0: self.gameOver() if self.snakePos[1] >= self.ALTO or self.snakePos[1] < 0: self.gameOver() # Self hit for block in self.snakeBody[1:]: if self.snakePos == block: self.gameOver() self.showScore() return self.perdi
class CargarClip(): """Sección que se encarga de abrir los clips almacenados del usuario""" def __init__(self, pantalla, ancho, alto, usuario): # Valores por defecto self.pantalla = pantalla self.ALTO = alto self.ANCHO = ancho # Usuario self.usuario = usuario self.pos_clip = 0 self.clips = [] # Colores self.NEGRO = (0, 0, 0) self.ROJO = (244, 36, 40) self.OXFORD_BLUE = (3, 15, 69) self.VERDE = (79, 170, 90) self.DEEP_CARMINE = (170, 40, 57) self.BLANCO = (241, 241, 241) self.CELESTE_LINDO = (40, 152, 178) self.BLANCO_LINDO = (253, 250, 251) self.TIGERS_EYE = (224, 159, 62) self.VERDE_FUERTE = (51, 255, 51) self.GRIS = (194, 214, 214) self.ROJO_CLARITO = (255, 153, 153) # Fuentes self.font_72 = pygame.font.SysFont('Bank Gothic', 72) self.font_50 = pygame.font.SysFont('Bank Gothic', 50) self.font_30 = pygame.font.SysFont('Bank Gothic', 30) self.font_20 = pygame.font.SysFont('Rachana', 15) self.font_10 = pygame.font.SysFont('Bank Gothic', 10) # herramientas self.tools = Tools(self.pantalla) self.clicks = {} self.iniciar_carga() def iniciar_carga(self): self.interfaz() self.cargar_clips_usuario() self.grilla() def grilla(self): """Grilla en donde aparecen todos los clips disponibles. Arma los clicks con clave: rx o ex, siendo x el numero de posición del clip en la grilla""" alto = 625 // 10 color = ((204, 0, 102), (128, 0, 0)) x = self.caja_principal.left y = self.caja_principal.top y2 = self.caja_principal.top + alto / 2 + 4 / 2 y3 = self.caja_principal.top + 4 / 2 for i in range(len(self.clips[:10])): coord = (x, y + i * alto, 724, alto) # Rectangulos rectangulo = pygame.draw.rect(self.pantalla, color[i % 2], coord) rect_r = pygame.draw.rect(self.pantalla, self.GRIS, (x + 4, y3 + i * alto, 80, alto / 2 - 4)) rect_e = pygame.draw.rect(self.pantalla, (26, 26, 26), (x + 4, y2 + i * alto, 80, alto / 2 - 4)) # Agrego a los rectángulos a los clicks self.clicks['r' + str(i)] = (rect_r, 0) self.clicks['e' + str(i)] = (rect_e, 0) # Hora de ultima modificación texto_fecha = self.font_20.render( 'Última modificación: ' + self.clips[i]['fecha'], True, self.ROJO_CLARITO) # Nombre del clip texto = self.font_50.render(self.clips[i]['clip'], True, self.BLANCO) # Textos self.tools.sombrear('EDITAR', self.GRIS, self.OXFORD_BLUE, self.font_20, rect_e) self.tools.sombrear('REPRODUCIR', (26, 26, 26), self.GRIS, self.font_20, rect_r) # Render self.pantalla.blit(texto, self.tools.centrar(rectangulo, texto)) self.pantalla.blit( texto_fecha, (rectangulo.right - texto_fecha.get_rect().width - 3, rectangulo.bottom - texto_fecha.get_rect().height)) def interfaz(self): """ Vista del cargar clip """ # Cajas self.caja_principal = pygame.draw.rect( self.pantalla, self.BLANCO, (self.ANCHO / 2 - 724 / 2, self.ALTO / 2 - 580 / 2, 724, 620)) self.caja_misclips = pygame.draw.rect( self.pantalla, self.ROJO, (self.ANCHO / 2 - 500 / 2, 0, 500, 50)) img_agregar = pygame.image.load(os.path.join('imagenes', 'agregar.png')) # Botones aux = self.pantalla.get_rect() self.rect_agregar = img_agregar.get_rect().move( aux.bottomright[0] - 70, aux.bottomright[1] - 70) self.pantalla.blit(img_agregar, (aux.bottomright[0] - 70, aux.bottomright[1] - 70)) self.atras = pygame.draw.rect( self.pantalla, self.DEEP_CARMINE, (0, self.pantalla.get_rect().height - 30, 80, 30)) # Texto self.tools.sombrear('Atrás', self.BLANCO, self.OXFORD_BLUE, self.font_30, self.atras) self.tools.sombrear('MIS CLIPS', self.BLANCO, self.OXFORD_BLUE, self.font_72, self.caja_misclips) # Clicks self.clicks['armar clip'] = (self.rect_agregar, 0) self.clicks['atras'] = (self.atras, 0) def cargar_clips_usuario(self): """ obtiene los clips guardados del usuario """ arch = open(os.path.join(os.getcwd(), 'archivos', 'usuarios.json'), 'r') datos = json.load(arch) if self.usuario in datos.keys(): self.clips = datos[self.usuario] else: # Si el usuario no posee clips guardados, lanza un cartel de error self.tools.sombrear('No hiciste ningún clip todavía. Hace uno!', self.NEGRO, self.ROJO_CLARITO, self.font_50, self.caja_principal) def chequear_botones(self, mouse): return self.tools.consulta_botones(mouse, self.clicks)
class NombreClip: """ Se encarga de procesar el nombre del clip""" def __init__(self, pantalla, ancho, alto, usuario): # Valores por defecto self.usuario = usuario self.nombre_clip = '' self.ALTO = alto self.ANCHO = ancho self.pantalla = pantalla self.tools = Tools(self.pantalla) # Colores self.COLOR_FONDO_MENU = (179, 0, 0) self.ROJO = (244, 36, 40) self.BLANCO = (255, 230, 230) self.GRIS = (194, 214, 214) self.NEGRO = (0, 0, 0) self.OXFORD_BLUE = (3, 15, 69) self.KENYAN_COPPER = (117, 19, 4) self.BLUE_YONDER = (77, 126, 168) self.VANILLA = (242, 243, 174) self.ROJO_CLARITO = (255, 153, 153) self.COLOR_TITULO = (102, 0, 51) # Fuentes self.font_72 = pygame.font.SysFont('monaco', 65) self.font_45 = pygame.font.SysFont('Bank Gothic', 45) self.font_30 = pygame.font.SysFont('Bank Gothic', 30) self.interfaz(self.pantalla.get_rect()) def interfaz(self, pantalla): """ Pone la interfaz del nombre del clip """ pos_titulo = (pantalla.center[0] - 300, pantalla.center[1] - 200) self.titulo = pygame.draw.rect(self.pantalla, self.COLOR_TITULO, (0, pantalla.center[1] - 200) + (pantalla.width, 150)) self.tools.sombrear('Ingrese el nombre del clip', self.ROJO_CLARITO, (0, 0, 0), self.font_72, self.titulo) self.limpiar_campo() self.cancelar = pygame.image.load( os.path.join('imagenes', 'cancelar.png')) self.pantalla.blit( self.cancelar, (pantalla.width / 2 - 311 / 2, pantalla.bottom - 100)) self.cancelar = self.cancelar.get_rect().move( pantalla.width / 2 - 311 / 2, pantalla.bottom - 100) def limpiar_campo(self): pos_campo = (self.pantalla.get_width() / 2 - 400, self.titulo.bottom) self.campo = pygame.draw.rect(self.pantalla, self.ROJO_CLARITO, pos_campo + (800, 100)) def enter(self): """ Guarda el clip """ if not self.nombre_clip: self.nombre_clip = 'sin nombre' directorios = os.listdir(os.path.join('archivos', self.usuario)) if self.nombre_clip in directorios: self.nombre_clip = '' self.existe = True else: self.existe = False def avisar_existe(self): """ Indicador de que el clip existe """ img = pygame.image.load(os.path.join('imagenes', 'errorclip.png')) self.pantalla.blit(img, (self.campo.left + 50, self.campo.bottom + 20)) self.interfaz(self.pantalla.get_rect()) def avisar_correcto(self): """ Indicador de que el clip no existe """ self.interfaz(self.pantalla.get_rect()) img = pygame.image.load(os.path.join('imagenes', 'checkclip.png')) self.pantalla.blit(img, (self.campo.left + 50, self.campo.bottom + 20)) pygame.display.update() time.sleep(1.5) def borrar(self): self.nombre_clip = self.nombre_clip[:-1] def actualizar_texto(self, caracter): self.nombre_clip += caracter def dentro_limite(self, texto): """ Verifica si el texto no superó el limite de la caja que lo contiene """ return self.tools.centrar( self.campo, self.font_72.render( texto, True, self.GRIS))[0] - 20 > self.campo.left def renderizar_texto_buscar(self): """ Muestra el texto en la pantalla. Retorna si el límite fue o no superado. """ if (self.dentro_limite(self.nombre_clip)): # Limpio pantalla self.limpiar_campo() pygame.draw.line( self.pantalla, self.NEGRO, (self.campo.bottomleft[0] + 20, self.campo.bottomleft[1] - 10), (self.campo.bottomright[0] - 20, self.campo.bottomright[1] - 10), 3) # Renderiza el texto self.tools.sombrear(self.nombre_clip, self.NEGRO, self.ROJO, self.font_72, self.campo) return False else: return True