Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmpc <jumapico@gmail.com>2009-10-08 06:48:47 (GMT)
committer jmpc <jumapico@gmail.com>2009-10-08 06:48:47 (GMT)
commit548e70b6dbadc522de252a771e88717617ecb2f3 (patch)
tree706edbe898f8ab4afaac6100246707d8ae9fcf43
parent09e035610147571cdd2709de2726b33a00fe0022 (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.pngbin0 -> 41026 bytes
-rw-r--r--completed.pngbin0 -> 1941 bytes
-rw-r--r--failed.pngbin0 -> 3838 bytes
-rw-r--r--gameover.pngbin0 -> 36776 bytes
-rw-r--r--juego1.py231
-rw-r--r--start.pngbin0 -> 16189 bytes
-rw-r--r--torta.py64
-rw-r--r--utils.py18
-rw-r--r--win.pngbin0 -> 45490 bytes
9 files changed, 313 insertions, 0 deletions
diff --git a/background.png b/background.png
new file mode 100644
index 0000000..e4a8351
--- /dev/null
+++ b/background.png
Binary files differ
diff --git a/completed.png b/completed.png
new file mode 100644
index 0000000..c6d04c3
--- /dev/null
+++ b/completed.png
Binary files differ
diff --git a/failed.png b/failed.png
new file mode 100644
index 0000000..b5c1896
--- /dev/null
+++ b/failed.png
Binary files differ
diff --git a/gameover.png b/gameover.png
new file mode 100644
index 0000000..085c038
--- /dev/null
+++ b/gameover.png
Binary files differ
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
new file mode 100644
index 0000000..cc9d314
--- /dev/null
+++ b/start.png
Binary files differ
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()
diff --git a/win.png b/win.png
new file mode 100644
index 0000000..18f6b8c
--- /dev/null
+++ b/win.png
Binary files differ