diff options
author | jmpc <jumapico@gmail.com> | 2009-10-08 06:48:47 (GMT) |
---|---|---|
committer | jmpc <jumapico@gmail.com> | 2009-10-08 06:48:47 (GMT) |
commit | 548e70b6dbadc522de252a771e88717617ecb2f3 (patch) | |
tree | 706edbe898f8ab4afaac6100246707d8ae9fcf43 | |
parent | 09e035610147571cdd2709de2726b33a00fe0022 (diff) |
Pasamos a utilizar una máquina de estados para la secuencia del juego.
El boton de check solo sirve si estamos eligiendo la torta.
Hay que cambiar la forma en que se le pasan a la clase Jugar1 y sus
estados los parametros para el draw y el update. Ver la forma de
encapsular más aun dichos metodos.
Por ahora se utilizaron imagenes para que el fondo no sea monotono, hay
que ver de hacer esas imagenes escalables.
-rw-r--r-- | background.png | bin | 0 -> 41026 bytes | |||
-rw-r--r-- | completed.png | bin | 0 -> 1941 bytes | |||
-rw-r--r-- | failed.png | bin | 0 -> 3838 bytes | |||
-rw-r--r-- | gameover.png | bin | 0 -> 36776 bytes | |||
-rw-r--r-- | juego1.py | 231 | ||||
-rw-r--r-- | start.png | bin | 0 -> 16189 bytes | |||
-rw-r--r-- | torta.py | 64 | ||||
-rw-r--r-- | utils.py | 18 | ||||
-rw-r--r-- | win.png | bin | 0 -> 45490 bytes |
9 files changed, 313 insertions, 0 deletions
diff --git a/background.png b/background.png Binary files differnew file mode 100644 index 0000000..e4a8351 --- /dev/null +++ b/background.png diff --git a/completed.png b/completed.png Binary files differnew file mode 100644 index 0000000..c6d04c3 --- /dev/null +++ b/completed.png diff --git a/failed.png b/failed.png Binary files differnew file mode 100644 index 0000000..b5c1896 --- /dev/null +++ b/failed.png diff --git a/gameover.png b/gameover.png Binary files differnew file mode 100644 index 0000000..085c038 --- /dev/null +++ b/gameover.png diff --git a/juego1.py b/juego1.py new file mode 100644 index 0000000..ff8cb0d --- /dev/null +++ b/juego1.py @@ -0,0 +1,231 @@ +import logging +import cairo +from torta import Torta + + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger(__name__) + +MAXLEVEL = 5 +IMAGE = { + "start": cairo.ImageSurface.create_from_png("start.png"), + "background": cairo.ImageSurface.create_from_png("background.png"), + "completed": cairo.ImageSurface.create_from_png("completed.png"), + "failed": cairo.ImageSurface.create_from_png("failed.png"), + "win": cairo.ImageSurface.create_from_png("win.png"), + "gameover": cairo.ImageSurface.create_from_png("gameover.png"), +} + + +class JuegoModo1: + def __init__(self): + log.debug("init - JuegoModo1") + self.change_state(Inicio(self)) + self.vidas = 5 + self.nivel = 1 + + + def change_state(self, state): + self.state = state + + + def draw(self, widget, event): + cr = widget.window.cairo_create() + self.state.draw(cr) + + + def update(self, widget, event): + if self.state.update(widget, event): + self.draw(widget, event) + + + def check(self, widget, event): + if isinstance(self.state, Jugar): + self.state.check(widget, event) + + +class Inicio: + """ + Mostramos pantalla de inicio y esperamos a que el usuario pulse el raton + para comenzar el juego. + + """ + def __init__(self, juego): + self.juego = juego + + + def update(self, widget, event): + self.juego.change_state(Jugar(self.juego)) + self.juego.draw(widget, event) + + + def draw(self, cairo_surface): + log.debug("draw - INICIO") + cairo_surface.set_source_surface(IMAGE["start"], 0, 0) + cairo_surface.paint() + + +class Jugar: + """ + Obtenemos los click's del usuario y esperamos por el resultado del juego. + + """ + def __init__(self, juego): + self.juego = juego + self.torta = Torta([3, 5], [100, 100], 80) + + + def update(self, widget, event): + """ + Verifica donde se pulso en el area del usuario y pasa a la torta. + + """ + log.debug("update - Jugar") + pos = event.get_coords() + if self.torta.select(pos): + log.debug("> torta") + return True + return False + + + def check(self, widget, event): + """ + Cambia de estado tomando en cuenta los trozos seleccionados. + + """ + log.debug("check - Jugar") + if self.torta.check(): + self.juego.change_state(Gana(self.juego)) + self.juego.draw(widget, event) + else: + self.juego.change_state(Pierde(self.juego)) + self.juego.draw(widget, event) + + + def draw(self, cairo_surface): + """ + Dibujamos la torta. + + """ + log.debug("draw - JUGAR") + cairo_surface.set_source_surface(IMAGE["background"], 0, 0) + cairo_surface.paint() + self.torta.draw(cairo_surface) + + +class Gana: + """ + Mostramos pantalla de felicitacion y avanzamos al siguiente nivel. + + """ + def __init__(self, juego): + self.juego = juego + + + def update(self, widget, event): + """ + """ + self.juego.nivel += 1 + if self.juego.nivel == MAXLEVEL: + self.juego.change_state(Win(self.juego)) + self.juego.draw(widget, event) + else: + self.juego.change_state(Jugar(self.juego)) + self.juego.draw(widget, event) + + + def draw(self, cairo_surface): + """ + Dibujamos felicitacion. + + """ + log.debug("draw - Gana") + cairo_surface.set_source_surface(IMAGE["completed"], 0, 0) + cairo_surface.paint() + + +class Pierde: + """ + Mostramos pantalla de error. Volvemos al siguiente nivel. + + """ + def __init__(self, juego): + self.juego = juego + + + def update(self, widget, event): + """ + Quita una vida. Si quedan reinicia el juego sino se va al game over. + + """ + self.juego.vidas -= 1 + if self.juego.vidas == 0: + self.juego.change_state(GameOver(self.juego)) + self.juego.draw(widget, event) + else: + self.juego.change_state(Jugar(self.juego)) + self.juego.draw(widget, event) + + + def draw(self, cairo_surface): + """ + Dibuja pantalla de error. + + """ + log.debug("draw - Pierde") + cairo_surface.set_source_surface(IMAGE["failed"], 0, 0) + cairo_surface.paint() + + +class GameOver: + """ + El jugador pierde por vidas. + + """ + def __init__(self, juego): + self.juego = juego + + + def update(self, widget, event): + """ + No hace nada. + + """ + pass + + + def draw(self, cairo_surface): + """ + Dibuja game over. + + """ + log.debug("draw - GameOver") + cairo_surface.set_source_surface(IMAGE["gameover"], 0, 0) + cairo_surface.paint() + + +class Win: + """ + El jugador llega al final del juego. + + """ + def __init__(self, juego): + self.juego = juego + + + def update(self, widget, event): + """ + No hace nada. + + """ + pass + + + def draw(self, cairo_surface): + """ + Dibuja felicitacion. + + """ + log.debug("draw - Win") + cairo_surface.set_source_surface(IMAGE["win"], 0, 0) + cairo_surface.paint() diff --git a/start.png b/start.png Binary files differnew file mode 100644 index 0000000..cc9d314 --- /dev/null +++ b/start.png diff --git a/torta.py b/torta.py new file mode 100644 index 0000000..fd14709 --- /dev/null +++ b/torta.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 +import math +from utils import draw_arc + + +class Torta: + def __init__(self, fraction, pos, radius): + """ + Creamos una torta de centro pos, radio radius y que corresponda a la + fraccion fraction. El parametro fraction es una lista cuyo primer + elemento es el numerador y el segundo el denominador de la fraccion. + + """ + self.M = fraction[0] + self.N = fraction[1] + self.center = pos + self.radius = radius + self.selected = [0] * self.N + + + def select(self, pos): + """ + Si pos esta dentro del area de la torta cambia el estado del trozo y + devuelve True, en caso contrario devuelve False. + + """ + x = pos[0] - self.center[0] + y = pos[1] - self.center[1] + if math.pow(x, 2) + math.pow(y, 2) > math.pow(self.radius, 2): + return False + angle = math.atan2(y, x) + if angle < 0: + angle += 2 * math.pi + sector = angle * self.N / (2 * math.pi) + index = int(math.floor(sector)) + self.selected[index] = 1 - self.selected[index] + return True + + + def check(self): + """ + Devuelve True si esta seleccionada la cantidad de sectores + correspondientes a la fraccion, False en caso contrario. + + """ + return sum(self.selected) == self.M + + + def draw(self, cairo_drawing_area): + """ + Dibuja la torta. + + """ + for i in xrange(self.N): + angle_start = 2 * math.pi * i / self.N + angle_end = 2 * math.pi * (i + 1) / self.N + if self.selected[i]: + fg = (1.0, 1.0, 0.0) + bg = (0.0, 1.0, 1.0) + else: + fg = (1.0, 0.0, 0.0) + bg = (0.0, 1.0, 0.0) + draw_arc(cairo_drawing_area, fg, bg, self.center[0], self.center[1], + self.radius, angle_start, angle_end) diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..3ec288a --- /dev/null +++ b/utils.py @@ -0,0 +1,18 @@ +import math + + +def draw_arc(cr, color_fg, color_bg, center_x, center_y, radius, angle_start, angle_end): + """ + Dibuja un arco sobre una superficie de cairo. + + """ + cr.set_source_rgb(*color_fg) + cr.move_to(center_x, center_y) + nx = center_x + radius * math.cos(angle_start) + ny = center_y + radius * math.sin(angle_start) + cr.line_to(nx, ny) + cr.arc(center_x, center_y, radius, angle_start, angle_end) + cr.close_path() + cr.stroke_preserve() + cr.set_source_rgb(*color_bg) + cr.fill() Binary files differ |