#! /usr/bin/env python # Conozco # Copyright (C) 2010 Gabriel Eirea # # This program 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 3 of the License, or # (at your option) any later version. # # This program 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 this program. If not, see . # # Contact information: # Gabriel Eirea geirea@gmail.com # Ceibal Jam http://ceibaljam.org import sys import random import os import pygame import olpcgames import gtk # constantes XMAPAMAX = 786 DXPANEL = 414 XCENTROPANEL = 1002 YGLOBITO = 310 DXBICHO = 218 DYBICHO = 268 XBICHO = 1200-DXBICHO YBICHO = 900-DYBICHO CAMINORECURSOS = "recursos" CAMINOLAMINA = "lamina" CAMINOCOMUN = "comun" CAMINOFUENTES = "fuentes" ARCHIVOINFO = "info.txt" CAMINODATOS = "datos" ARCHIVONIVELES = "niveles.txt" ARCHIVOZONAS = "zonas.txt" ARCHIVOCREDITOS = "creditos.txt" ARCHIVONOMBRE = "nombre.txt" CAMINOIMAGENES = "imagenes" CAMINOSONIDOS = "sonidos" COLORNOMBREDEPTO = (200,60,60) COLORPREGUNTAS = (80,80,155) COLORPANEL = (156,158,172) TOTALAVANCE = 7 EVENTORESPUESTA = pygame.USEREVENT+1 TIEMPORESPUESTA = 2300 EVENTOREFRESCO = EVENTORESPUESTA+1 TIEMPOREFRESCO = 250 # variables globales para adaptar la pantalla a distintas resoluciones scale = 1 shift_x = 0 shift_y = 0 xo_resolution = True clock = pygame.time.Clock() def wait_events(): """ Funcion para esperar por eventos de pygame sin consumir CPU """ global clock clock.tick(20) return pygame.event.get() class Zona(): """Clase para zonas de una imagen. La posicion esta dada por una imagen bitmap pintada con un color especifico, dado por la clave (valor 0 a 255 del componente rojo). """ def __init__(self,mapa,nombre,claveColor,tipo,posicion,rotacion): self.mapa = mapa self.nombre = nombre self.claveColor = int(claveColor) self.tipo = int(tipo) self.posicion = (int(int(posicion[0])*scale+shift_x), int(int(posicion[1])*scale+shift_y)) self.rotacion = int(rotacion) def estaAca(self,pos): """Devuelve True si la coordenada pos esta en la zona""" if pos[0] < XMAPAMAX*scale+shift_x: colorAca = self.mapa.get_at((pos[0]-shift_x, pos[1]-shift_y)) if colorAca[0] == self.claveColor: return True else: return False else: return False def mostrarNombre(self,pantalla,fuente,color,flipAhora): """Escribe el nombre de la zona en su posicion""" text = fuente.render(self.nombre, 1, color) textrot = pygame.transform.rotate(text, self.rotacion) textrect = textrot.get_rect() textrect.center = (self.posicion[0], self.posicion[1]) pantalla.blit(textrot, textrect) if flipAhora: pygame.display.flip() class Nivel(): """Clase para definir los niveles del juego. Cada nivel tiene un dibujo inicial, los elementos pueden estar etiquetados con el nombre o no, y un conjunto de preguntas. """ def __init__(self,nombre): self.nombre = nombre self.preguntas = list() self.indicePreguntaActual = 0 self.elementosActivos = list() def prepararPreguntas(self): """Este metodo sirve para preparar la lista de preguntas al azar.""" random.shuffle(self.preguntas) def siguientePregunta(self,listaSufijos,listaPrefijos): """Prepara el texto de la pregunta siguiente""" self.preguntaActual = self.preguntas[self.indicePreguntaActual] self.sufijoActual = random.randint(1,len(listaSufijos))-1 self.prefijoActual = random.randint(1,len(listaPrefijos))-1 lineas = listaPrefijos[self.prefijoActual].split("\\") lineas.extend(self.preguntaActual[0].split("\\")) lineas.extend(listaSufijos[self.sufijoActual].split("\\")) self.indicePreguntaActual = self.indicePreguntaActual+1 if self.indicePreguntaActual == len(self.preguntas): self.indicePreguntaActual = 0 return lineas def devolverAyuda(self): """Devuelve la linea de ayuda""" self.preguntaActual = self.preguntas[self.indicePreguntaActual-1] return self.preguntaActual[2].split("\\") def mostrarPregunta(self,pantalla,fuente,sufijo,prefijo): """Muestra la pregunta en el globito""" self.preguntaActual = self.preguntas[self.indicePreguntaActual] lineas = prefijo.split("\\") lineas.extend(self.preguntaActual[0].split("\\")) lineas.extend(sufijo.split("\\")) yLinea = 100 for l in lineas: text = fuente.render(l, 1, COLORPREGUNTAS) textrect = text.get_rect() textrect.center = (XCENTROPANEL,yLinea) pantalla.blit(text, textrect) yLinea = yLinea + fuente.get_height() pygame.display.flip() class ConozcoUy(): """Clase principal del juego. """ def mostrarTexto(self,texto,fuente,posicion,color): """Muestra texto en una determinada posicion""" text = fuente.render(texto, 1, color) textrect = text.get_rect() textrect.center = posicion self.pantalla.blit(text, textrect) def cargarZonas(self): """Carga las imagenes y los datos de las zonas""" self.zonas = self.cargarImagen("zonas.png") self.listaZonas = list() # falta sanitizar manejo de archivo f = open(os.path.join(self.camino_datos,ARCHIVOZONAS),"r") linea = f.readline() while linea: if linea[0] == "#": linea = f.readline() continue [nombreZona,claveColor,posx,posy,rotacion] = \ linea.strip().split("|") nuevaZona = Zona(self.zonas, unicode(nombreZona,'iso-8859-1'), claveColor,1,(posx,posy),rotacion) self.listaZonas.append(nuevaZona) linea = f.readline() f.close() def cargarNiveles(self): """Carga los niveles del archivo de configuracion""" self.listaNiveles = list() self.listaPrefijos = list() self.listaSufijos = list() self.listaCorrecto = list() self.listaMal = list() self.listaDespedidas = list() # falta sanitizar manejo de archivo f = open(os.path.join(self.camino_datos,ARCHIVONIVELES),"r") linea = f.readline() while linea: if linea[0] == "#": linea = f.readline() continue if linea[0] == "[": # empieza nivel nombreNivel = linea.strip("[]\n") nuevoNivel = Nivel(nombreNivel) self.listaNiveles.append(nuevoNivel) linea = f.readline() continue if linea.find("=") == -1: linea = f.readline() continue [var,valor] = linea.strip().split("=") if var.startswith("Prefijo"): self.listaPrefijos.append( unicode(valor.strip(),'iso-8859-1')) elif var.startswith("Sufijo"): self.listaSufijos.append( unicode(valor.strip(),'iso-8859-1')) elif var.startswith("Correcto"): self.listaCorrecto.append( unicode(valor.strip(),'iso-8859-1')) elif var.startswith("Mal"): self.listaMal.append( unicode(valor.strip(),'iso-8859-1')) elif var.startswith("Despedida"): self.listaDespedidas.append( unicode(valor.strip(),'iso-8859-1')) elif var.startswith("Pregunta"): [texto,respuesta,ayuda] = valor.split("|") nuevoNivel.preguntas.append( (unicode(texto.strip(),'iso-8859-1'), unicode(respuesta.strip(),'iso-8859-1'), unicode(ayuda.strip(),'iso-8859-1'))) linea = f.readline() f.close() self.indiceNivelActual = 0 self.numeroNiveles = len(self.listaNiveles) self.numeroSufijos = len(self.listaSufijos) self.numeroPrefijos = len(self.listaPrefijos) self.numeroCorrecto = len(self.listaCorrecto) self.numeroMal = len(self.listaMal) self.numeroDespedidas = len(self.listaDespedidas) def pantallaAcercaDe(self): """Pantalla con los datos del juego, creditos, etc""" global scale, shift_x, shift_y, xo_resolution self.pantallaTemp = pygame.Surface( (self.anchoPantalla,self.altoPantalla)) self.pantallaTemp.blit(self.pantalla,(0,0)) self.pantalla.fill((0,0,0)) self.pantalla.blit(self.terron, (int(20*scale+shift_x), int(20*scale+shift_y))) self.mostrarTexto("Acerca de Conozco Uruguay", self.fuente40, (int(600*scale+shift_x), int(100*scale+shift_y)), (255,255,255)) # falta sanitizar acceso a archivo f = open(os.path.join(CAMINORECURSOS, CAMINOCOMUN, CAMINODATOS, ARCHIVOCREDITOS),"r") yLinea = int(200*scale+shift_y) for linea in f: self.mostrarTexto(linea.strip(), self.fuente32, (int(600*scale+shift_x),yLinea), (155,155,255)) yLinea = yLinea + int(40*scale) f.close() self.mostrarTexto("Presiona cualquier tecla para volver", self.fuente32, (int(600*scale+shift_x), int(800*scale+shift_y)), (255,155,155)) pygame.display.flip() while 1: for event in wait_events(): if event.type == pygame.KEYDOWN: self.click.play() self.pantalla.blit(self.pantallaTemp,(0,0)) pygame.display.flip() return elif event.type == EVENTOREFRESCO: pygame.display.flip() def pantallaInicial(self): """Pantalla con el menu principal del juego""" global scale, shift_x, shift_y self.pantalla.fill((0,0,0)) self.mostrarTexto("CONOZCO NUMEROS", self.fuente48, (int(600*scale+shift_x), int(80*scale+shift_y)), (255,255,255)) self.mostrarTexto("Juego", self.fuente48, (int(300*scale+shift_x), int(220*scale+shift_y)), (200,100,100)) yLista = int(300*scale+shift_y) for n in self.listaNiveles: self.pantalla.fill((20,20,20), (int(10*scale+shift_x), yLista-int(24*scale), int(590*scale), int(48*scale))) self.mostrarTexto(n.nombre, self.fuente40, (int(300*scale+shift_x), yLista), (200,100,100)) yLista += int(50*scale) self.pantalla.fill((20,20,20), (int(10*scale+shift_x), int(801*scale+shift_y), int(590*scale),int(48*scale))) self.mostrarTexto("Sobre este juego", self.fuente40, (int(300*scale+shift_x),int(825*scale+shift_y)), (100,200,100)) self.pantalla.fill((20,20,20), (int(610*scale+shift_x), int(801*scale+shift_y), int(590*scale),int(48*scale))) self.mostrarTexto("Volver", self.fuente40, (int(900*scale+shift_x),int(825*scale+shift_y)), (100,200,100)) pygame.display.flip() while 1: for event in wait_events(): if event.type == pygame.KEYDOWN: if event.key == 27: # escape: volver self.click.play() self.elegir_directorio = True return elif event.type == pygame.MOUSEBUTTONDOWN: self.click.play() pos = event.pos if pos[1] > 275*scale + shift_y: # zona de opciones if pos[0] < 600*scale + shift_x: # primera columna if pos[1] < 275*scale + shift_y + \ len(self.listaNiveles)*50*scale: # nivel self.indiceNivelActual = \ int((pos[1]-int(275*scale+shift_y))//\ int(50*scale)) self.jugar = True return elif pos[1] > 800*scale + shift_y and \ pos[1] < 850*scale + shift_y: # acerca de self.pantallaAcercaDe() else: # segunda columna if pos[1] > 800*scale + shift_y and \ pos[1] < 850*scale+shift_y: # volver self.elegir_directorio = True return elif event.type == EVENTOREFRESCO: pygame.display.flip() def cargarImagen(self,nombre): """Carga una imagen y la escala de acuerdo a la resolucion""" global scale, xo_resolution if xo_resolution: imagen = pygame.image.load( \ os.path.join(self.camino_imagenes,nombre)) else: imagen0 = pygame.image.load( \ os.path.join(self.camino_imagenes,nombre)) imagen = pygame.transform.scale(imagen0, (int(imagen0.get_width()*scale), int(imagen0.get_height()*scale))) del imagen0 return imagen def __init__(self): """Esta es la inicializacion del juego""" global scale, shift_x, shift_y, xo_resolution pygame.init() # crear pantalla self.anchoPantalla = gtk.gdk.screen_width() self.altoPantalla = gtk.gdk.screen_height() self.pantalla = pygame.display.set_mode((self.anchoPantalla, self.altoPantalla)) if self.anchoPantalla==1200 and self.altoPantalla==900: xo_resolution = True scale = 1 shift_x = 0 shift_y = 0 else: xo_resolution = False if self.anchoPantalla/1200.0 975*scale+shift_x and \ event.pos[0] < 1175*scale+shift_x and \ event.pos[1] > 25*scale+shift_y and \ event.pos[1] < 75*scale+shift_y: # terminar return elif event.type == EVENTORESPUESTA: pygame.time.set_timer(EVENTORESPUESTA,0) if self.esCorrecto: if self.avanceNivel == TOTALAVANCE: return self.avanceNivel = self.avanceNivel + 1 if self.avanceNivel == TOTALAVANCE: # fin self.lineasPregunta = self.listaDespedidas[\ random.randint(1,self.numeroDespedidas)-1]\ .split("\\") self.mostrarGlobito(self.lineasPregunta) pygame.time.set_timer( EVENTORESPUESTA,TIEMPORESPUESTA) else: # pregunta siguiente self.lineasPregunta = \ self.nivelActual.siguientePregunta(\ self.listaSufijos,self.listaPrefijos) self.mostrarGlobito(self.lineasPregunta) self.nRespuestasMal = 0 else: if self.nRespuestasMal >= 2: # ayuda self.mostrarGlobito( self.nivelActual.devolverAyuda()) self.nRespuestasMal = 0 pygame.time.set_timer( EVENTORESPUESTA,TIEMPORESPUESTA) else: # volver a preguntar self.mostrarGlobito(self.lineasPregunta) elif event.type == EVENTOREFRESCO: pygame.display.flip() def principal(self): """Este es el loop principal del juego""" global scale, shift_x, shift_y pygame.time.set_timer(EVENTOREFRESCO,TIEMPOREFRESCO) while 1: self.cargarDirectorio() while 1: # pantalla inicial de juego self.elegir_directorio = False self.pantallaInicial() if self.elegir_directorio: # volver a seleccionar mapa sys.exit() # dibujar fondo y panel self.pantalla.blit(self.fondo, (shift_x, shift_y)) # CORRECCION por tamanio equivocado del fondo self.mostrarPanel("") self.pantalla.fill(COLORPANEL, (int(XMAPAMAX*scale+shift_x),shift_y, int(DXPANEL*scale),int(900*scale))) self.pantalla.blit(self.bicho, (int(XBICHO*scale+shift_x), int(YBICHO*scale+shift_y))) # mostrar pantalla pygame.display.flip() # ir al juego self.jugarNivel() def main(): juego = ConozcoUy() juego.principal() if __name__ == "__main__": main()