Package pilas :: Package demos :: Module piezas
[hide private]
[frames] | no frames]

Source Code for Module pilas.demos.piezas

  1  # -*- encoding: utf-8 -*- 
  2  # pilas engine - a video game framework. 
  3  # 
  4  # copyright 2010 - hugo ruscitti 
  5  # license: lgplv3 (see http://www.gnu.org/licenses/lgpl.html) 
  6  # 
  7  # website - http://www.pilas-engine.com.ar 
  8   
  9  import pilas 
 10  import random 
 11   
 12   
13 -class Piezas(pilas.escena.Base):
14 """Representa la escena de rompecabezas. 15 16 La escena comienza con una imagen que se descompone en muchos 17 actores Pieza. 18 """ 19
20 - def __init__(self, ruta_a_la_imagen="fondos/noche.jpg", filas=4, columnas=4, al_terminar=None):
21 pilas.escena.Base.__init__(self) 22 self.ruta_a_la_imagen = ruta_a_la_imagen 23 self.filas = filas 24 self.columnas = columnas 25 self.al_terminar = al_terminar
26
27 - def iniciar(self):
28 pilas.actores.utils.eliminar_a_todos() 29 grilla = pilas.imagenes.cargar_grilla(self.ruta_a_la_imagen, self.columnas, self.filas) 30 self.crear_piezas(grilla, self.filas, self.columnas) 31 self.pieza_en_movimiento = None 32 33 pilas.eventos.click_de_mouse.conectar(self.al_hacer_click) 34 pilas.eventos.termina_click.conectar(self.al_soltar_el_click) 35 pilas.eventos.mueve_mouse.conectar(self.al_mover_el_mouse) 36 37 self.sonido_tick = pilas.sonidos.cargar("tick.wav") 38 self.al_terminar = self.al_terminar 39 self.piezas_desconectadas = self.filas * self.columnas -1
40
41 - def crear_piezas(self, grilla, filas, columnas):
42 "Genera todas las piezas en base al tamaño del constructor." 43 self.piezas = [] 44 self.grupos = {} 45 46 for x in range(filas * columnas): 47 self.grupos[x] = set([x]) 48 pieza = Pieza(self, grilla, x, filas, columnas) 49 self.piezas.append(pieza) 50 pieza.x = random.randint(-200, 200) 51 pieza.y = random.randint(-200, 200)
52 53
54 - def al_hacer_click(self, evento):
55 "Atiente cualquier click que realice el usuario en la pantalla." 56 x, y = evento.x, evento.y 57 pieza_debajo_de_mouse = pilas.actores.utils.obtener_actor_en(x, y) 58 59 if pieza_debajo_de_mouse and isinstance(pieza_debajo_de_mouse, Pieza): 60 self.pieza_en_movimiento = pieza_debajo_de_mouse 61 self.pieza_en_movimiento.mostrar_arriba_todas_las_piezas()
62
63 - def al_soltar_el_click(self, evento):
64 if self.pieza_en_movimiento: 65 self.pieza_en_movimiento.soltar_todas_las_piezas_del_grupo() 66 self.pieza_en_movimiento.mostrar_abajo_todas_las_piezas() 67 self.pieza_en_movimiento = None
68
69 - def al_mover_el_mouse(self, evento):
70 if self.pieza_en_movimiento: 71 self.pieza_en_movimiento.x += evento.dx 72 self.pieza_en_movimiento.y += evento.dy
73
74 - def conectar(self, pieza_a, pieza_b):
75 a = pieza_a.numero 76 b = pieza_b.numero 77 78 79 if a in self.grupos[b]: 80 #Evita contectar mas de una vez a dos piezas. 81 return 82 83 """Inicialmente comienzo con:: 84 85 86 0: [0, 1, 2] 87 1: [0, 1, 2] 88 2: [0, 1, 2] 89 3: [3] 90 91 ¿y si conecto la pieza 3 con la 2? 92 93 - tendría que obtener todas las piezas que conoce 2. 94 95 - iterar en ese grupo y decirle a cada pieza que sume a 3 en su grupo:: 96 97 0: [0, 1, 2, 3] 98 1: [0, 1, 2, 3] 99 2: [0, 1, 2, 3] 100 101 - luego solo me falta tomar a uno de esos grupos actualizados 102 y decirle a 3 que ese será su grupo:: 103 104 3: [0, 1, 2, 3] 105 """ 106 107 grupo_nuevo = set(self.grupos[a]).union(self.grupos[b]) 108 109 for pieza in grupo_nuevo: 110 self.grupos[pieza] = grupo_nuevo 111 112 self.piezas_desconectadas -= 1 113 114 if self.piezas_desconectadas < 1: 115 if self.al_terminar: 116 self.al_terminar() 117 118 self.sonido_tick.reproducir()
119
120 -class Pieza(pilas.actores.Animado):
121 """Representa una pieza del rompecabezas. 122 123 Esta pieza se puede arrastrar con el mouse y cuando se suelta 124 intentará conectarse con las demás.""" 125
126 - def __init__(self, escena_padre, grilla, cuadro, filas, columnas):
127 "Genera la pieza que representa una parte de la imagen completa." 128 self.escena_padre = escena_padre 129 self.numero = cuadro 130 pilas.actores.Animado.__init__(self, grilla) 131 132 self.z_de_la_pieza_mas_alta = 0 133 self.asignar_numero_de_piezas_laterales(cuadro, columnas) 134 135 self.definir_cuadro(cuadro) 136 137 self.radio_de_colision = self.obtener_ancho() / 2 + 12 138 self.piezas_conectadas = []
139
140 - def asignar_numero_de_piezas_laterales(self, cuadro, columnas):
141 "Guarda el numero de las piezas que se pueden conectar en sus bordes." 142 self.numero_arriba = cuadro - columnas 143 self.numero_abajo = cuadro + columnas 144 145 if cuadro % columnas == 0: 146 self.numero_izquierda = -1 147 else: 148 self.numero_izquierda = cuadro - 1 149 150 if cuadro % columnas == columnas -1: 151 self.numero_derecha = -1 152 else: 153 self.numero_derecha = cuadro + 1
154
156 for numero in self.escena_padre.grupos[self.numero]: 157 pieza = self.escena_padre.piezas[numero] 158 pieza.soltar()
159
160 - def soltar(self):
161 # Busca todas las colisiones entre esta pieza 162 # que se suelta y todas las demás. 163 colisiones = pilas.escena_actual().colisiones.obtener_colisiones(self, self.escena_padre.piezas) 164 165 for x in colisiones: 166 self.intentar_conectarse_a(x)
167
168 - def se_pueden_conectar_los_bordes(self, borde1, borde2):
169 distancia = pilas.utils.distancia(borde1, borde2) 170 return distancia < 12
171
172 - def intentar_conectarse_a(self, otra):
173 "Intenta vincular dos piezas, siempre y cuando coincidan en sus bordes." 174 175 # Intenta conectar los bordes laterales 176 if self.numero_derecha == otra.numero: 177 if self.se_pueden_conectar_los_bordes(self.derecha, otra.izquierda): 178 otra.izquierda = self.derecha 179 otra.arriba = self.arriba 180 self.conectar_con(otra) 181 182 elif self.numero_izquierda == otra.numero: 183 if self.se_pueden_conectar_los_bordes(self.izquierda, otra.derecha): 184 otra.derecha = self.izquierda 185 otra.arriba = self.arriba 186 self.conectar_con(otra) 187 188 # Intenta conectar los bordes superior e inferior 189 if self.numero_abajo == otra.numero: 190 if self.se_pueden_conectar_los_bordes(self.abajo, otra.arriba): 191 otra.arriba = self.abajo 192 otra.izquierda = self.izquierda 193 self.conectar_con(otra) 194 195 elif self.numero_arriba == otra.numero: 196 if self.se_pueden_conectar_los_bordes(self.arriba, otra.abajo): 197 otra.abajo = self.arriba 198 otra.izquierda = self.izquierda 199 self.conectar_con(otra)
200 201
202 - def conectar_con(self, otra_pieza):
203 self.escena_padre.conectar(self, otra_pieza)
204 205
206 - def __repr__(self):
207 return "<<Pieza %d>>" %(self.animacion.obtener_cuadro())
208 209
210 - def set_x(self, x):
211 "A diferencia de los actores normales, las piezas tienen que mover a todo su grupo." 212 dx = x - self.x 213 214 for numero in self.escena_padre.grupos[self.numero]: 215 try: 216 pieza = self.escena_padre.piezas[numero] 217 pieza.definir_posicion(pieza.x + dx, pieza.y) 218 except IndexError: 219 pass
220
221 - def set_y(self, y):
222 "A diferencia de los actores normales, las piezas tienen que mover a todo su grupo." 223 dy = y - self.y 224 225 for numero in self.escena_padre.grupos[self.numero]: 226 try: 227 pieza = self.escena_padre.piezas[numero] 228 pieza.definir_posicion(pieza.x, pieza.y + dy) 229 except IndexError: 230 pass
231
232 - def get_x(self):
233 x, y = self.obtener_posicion() 234 return x
235
236 - def get_y(self):
237 x, y = self.obtener_posicion() 238 return y
239 240 x = property(get_x, set_x, doc="Define la posición horizontal.") 241 y = property(get_y, set_y, doc="Define la posición vertical.") 242
244 for numero in self.escena_padre.grupos[self.numero]: 245 pieza = self.escena_padre.piezas[numero] 246 pieza.z = -1
247
249 for numero in self.escena_padre.grupos[self.numero]: 250 pieza = self.escena_padre.piezas[numero] 251 pieza.z = 0
252