From 6bb256cc9262578799835a41442799083ea10cd2 Mon Sep 17 00:00:00 2001 From: Sin Nombre Date: Thu, 15 Apr 2010 21:50:19 +0000 Subject: Create repository and load --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e6eeb1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +*.e4p +*.zip +.eric4project/ diff --git a/MANIFEST b/MANIFEST new file mode 100755 index 0000000..b6ffa17 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,41 @@ +conozcomx.py +run.py +activity.py +setup.py +NEWS +COPYING +activity/conozco-numeros.svg +activity/activity.info +olpcgames/COPYING +olpcgames/_cairoimage.py +olpcgames/svgsprite.py +olpcgames/util.py +olpcgames/__init__.py +olpcgames/pangofont.py +olpcgames/_gtkmain.py +olpcgames/canvas.py +olpcgames/gtkEvent.py +olpcgames/_version.py +olpcgames/video.py +olpcgames/eventwrap.py +olpcgames/camera.py +olpcgames/mesh.py +olpcgames/pausescreen.py +olpcgames/activity.py +olpcgames/textsprite.py +olpcgames/buildmanifest.py +olpcgames/dbusproxy.py +olpcgames/data/__init__.py +olpcgames/data/sleeping_svg.py +recursos/comun/datos/creditos.txt +recursos/comun/fuentes/AllCaps.ttf +recursos/comun/fuentes/Share-Regular.ttf +recursos/comun/imagenes/globito.png +recursos/comun/imagenes/bicho.png +recursos/comun/imagenes/terron.png +recursos/comun/imagenes/LICENSE +recursos/comun/sonidos/junggle_btn045.wav +recursos/lamina/niveles.txt +recursos/lamina/zonas.txt +recursos/lamina/zonas.png +recursos/lamina/lamina.png diff --git a/activity.py b/activity.py new file mode 100755 index 0000000..3300269 --- /dev/null +++ b/activity.py @@ -0,0 +1,9 @@ +from olpcgames import activity +from gettext import gettext as _ + +class Activity(activity.PyGameActivity): + """Your Sugar activity""" + + game_name = 'conozcomx' + game_title = _('Conozco Mexico') + game_size = (1200,900) diff --git a/activity/activity.info b/activity/activity.info new file mode 100755 index 0000000..d24a302 --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,8 @@ +[Activity] +name = Conozco Numeros +activity_version = 1 +host_version = 1 +bundle_id = org.ceibaljam.conozconumeros +icon = conozco-numeros +exec = sugar-activity activity.Activity +license = GPL+ diff --git a/activity/conozco-numeros.svg b/activity/conozco-numeros.svg new file mode 100644 index 0000000..4c2fd79 --- /dev/null +++ b/activity/conozco-numeros.svg @@ -0,0 +1,109 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 27 + 85 + 48 + diff --git a/conozcomx.py b/conozcomx.py new file mode 100755 index 0000000..3044e1e --- /dev/null +++ b/conozcomx.py @@ -0,0 +1,642 @@ +#! /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 . +# +# +# Based off of Conozco - Numeros / Uruguay +# Contact information: +# Cole cshaw@cidesi.mx + +import sys +import random +import os +import pygame +import olpcgames +import gtk +from gettext import gettext as _ + +# 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 ConozcoMx(): + """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 Mexico"), + 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 MEXICO"), + 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(_("Salir"), + 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)) + 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 = ConozcoMx() + juego.principal() + + +if __name__ == "__main__": + main() diff --git a/run.py b/run.py new file mode 100755 index 0000000..aeb5b36 --- /dev/null +++ b/run.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python +"""Skeleton project file mainloop for new OLPCGames users""" +import olpcgames, pygame, logging +from olpcgames import pausescreen + +log = logging.getLogger( 'conozco-uruguay run' ) +log.setLevel( logging.DEBUG ) + +def main(): + """The mainloop which is specified in the activity.py file + + "main" is the assumed function name + """ + size = (800,600) + if olpcgames.ACTIVITY: + size = olpcgames.ACTIVITY.game_size + screen = pygame.display.set_mode(size) + + clock = pygame.time.Clock() + + running = True + while running: + screen.fill( (0,0,128)) + milliseconds = clock.tick(25) # maximum number of frames per second + + # Event-management loop with support for pausing after X seconds (20 here) + events = pausescreen.get_events() + # Now the main event-processing loop + if events: + for event in events: + log.debug( "Event: %s", event ) + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_ESCAPE: + running = False + pygame.display.flip() + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..d37b6ed --- /dev/null +++ b/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from sugar.activity import bundlebuilder +if __name__ == "__main__": + bundlebuilder.start("conozco-mexico") -- cgit v0.9.1