6. IMPLEMENTACIÓN Y CONTROL DEL MINI-MAPA DE ORIENTACIÓN
6.5. Aspectos avanzados
6.5.2. Orientación de la cámara “camara_mapa” en la dirección de avance de la
la pelota
Hasta este punto, la cámara del mini-mapa (“camara_mapa”) ha conservado siempre la misma orientación. En este apartado y en el siguiente se estudian otros modos de funcionamiento en los que la cámara rota en el plano horizontal en función de determinadas variables del juego. En el módulo “control_mapa_3.py” del fichero de ejemplo hay tres bloques de código correspondientes a estos dos apartados, desactivados en un principio mediante comillas triples. Cuando se quiera usar alguno es necesario editar las comillas de forma que sólo uno de los tres esté activo.
En este apartado concretamente, se hace girar a la cámara para colocarse en la dirección en la que avanza la pelota. Esto supone que la cámara gira solidariamente con el icono, y por tanto éste aparecerá siempre en el centro del mapa y sin moverse. En este caso es especialmente importante que los giros sean suaves, ya que en casos de cambios rápidos de dirección toda la ventana del mini-mapa sufriría brusquedades indeseables que ocasionarían distracciones de la acción principal.
En todos los casos donde se modifique o consulte la matriz “worldOrientation” de la cámara hay que tener en cuenta la colocación de sus ejes: como se aprecia en la Figura 16, donde aparecen las posiciones y orientaciones relativas entre la cámara “camara_mapa” y el icono “icono_mapa”, el eje de la cámara que se debe hacer coincidir con la dirección de la pelota no es el X sino el Y.
Figura 16. Orientación de los ejes de la cámara “camara_mapa” y el icono “icono_mapa”.
En caso de implementar un giro completamente solidario con el icono, el proceso consiste simplemente en aplicar a la cámara sus mismos cambios de orientación, cambios que ya incluyen el suavizado correspondiente (apartado 6.5.1). Simplemente habrá que tener en cuenta la orientación distinta de los ejes a la hora de introducir la dirección en la matriz “worldOrientation” de la cámara. La dirección deseada (“direccion_camara_final”) se debe colocar en la segunda columna de la matriz, correspondiente al eje Y. En la primera columna (eje X) se debe colocar un vector perpendicular a ésta hacia la derecha.
En el Fragmento de código 50 aparece el código que hace girar a la cámara solidariamente con el icono. La variable “direccion_camara_final” solamente se define para mantener la coherencia a la hora de hacer las asignaciones.
# Asignaciones del nivel superior... def main():
# Resto de lógica...
direccion_camara_final = direccion_icono_final
camara_mapa.worldOrientation[0][1] = direccion_camara_final[0]
camara_mapa.worldOrientation[1][1] = direccion_camara_final[1]
camara_mapa.worldOrientation[0][0] = direccion_camara_final[1]
camara_mapa.worldOrientation[1][0] = -direccion_camara_final[0]
Fragmento de código 50. Giro de la cámara “camara_mapa” solidariamente con el icono “icono_mapa”.
Una variante de esta modalidad consiste en hacer que la cámara y el icono adapten su orientación a la dirección de la pelota con velocidades distintas. El resultado es que el icono
Implementación y control del mini-mapa de orientación
se ladea hacia la dirección en que se está girando, en mayor o menor medida según sea la diferencia entre lo rápido que la cámara y el icono adoptan la nueva orientación.
Esta rapidez está controlada, como se ha visto, por la constante “RAPIDEZ_GIRO_ICONO” en el caso del icono, y paralelamente por “RAPIDEZ_GIRO_CAMARA” en el de la cámara. Para poder tratar a cámara e icono de forma diferente es necesario calcular el proceso de suavizado del giro independientemente para cada uno de ellos. El único elemento en común es la dirección objetivo, la dirección que adoptarían si no se suavizasen los movimientos, que es la que lleva la pelota. El proceso de obtención de la dirección a aplicar a la cámara es exactamente igual al que se usa para el icono, explicado en el apartado 6.5.1.
En el Fragmento de código 51 se incluye el código correspondiente al cálculo y aplicación de la dirección que debe adoptar la cámara en cada cuadro.
# Resto de asignaciones... RAPIDEZ_GIRO_CAMARA = 0.05 def main(): # Resto de lógica... direccion_camara_actual =
Vector([camara_mapa.worldOrientation[0][1],camara_mapa.worldOrientatio
n[1][1]])
direccion_camara_deseada = direccion_pelota
angulo_camara_actual = obtener_angulo_x(direccion_camara_actual)
angulo_camara_deseado = obtener_angulo_x(direccion_camara_deseada)
diferencia_angulos_camara = angulo_camara_deseado - angulo_camara_actual if diferencia_angulos_camara > pi: diferencia_angulos_camara -= 2*pi if diferencia_angulos_camara < -pi: diferencia_angulos_camara += 2*pi
angulo_camara_final = angulo_camara_actual + RAPIDEZ_GIRO_CAMARA *
diferencia_angulos_camara direccion_camara_final =
[cos(angulo_camara_final),sin(angulo_camara_final)]
camara_mapa.worldOrientation[0][0] = direccion_camara_final[1]
camara_mapa.worldOrientation[1][0] = -direccion_camara_final[0]
camara_mapa.worldOrientation[0][1] = direccion_camara_final[0]
camara_mapa.worldOrientation[1][1] = direccion_camara_final[1]
Fragmento de código 51. Cálculo y aplicación del giro suavizado de la cámara “camara_mapa” en la dirección de la pelota.
6.5.3.Orientación de la cámara “camara_mapa” en la dirección en la que
apunta la cámara “camara_principal”
Consiste en orientar la cámara “camara_mapa” de tal manera que, lo que en el mapa se entiende como su dirección de apunte (en realidad la cámara apunta hacia abajo, pero se considera que en este caso el mini-mapa apunta hacia la parte que queda arriba en la ventana,
que coincide con el eje Y de la cámara, ver Figura 16), coincida con la dirección en la que apunta la cámara principal, es decir, con la orientación opuesta a la del eje Z de la misma.
Dado que la cámara principal no apunta completamente en horizontal, y que en el mini- mapa sólo se considera este plano, al obtener la dirección en la que apunta el eje Z de su matriz “worldOrientation” (tercera columna) hay que eliminar lo relativo al plano vertical. Esto se hace tomando sólo sus dos primeras componentes y normalizando el resultado, como muestra el Fragmento de código 52.
Una vez se tiene el vector con la dirección de apunte de la cámara principal, que a su vez es la dirección a adoptar por la cámara del mini-mapa (“direccion_camara_final”), sólo resta modificar correctamente su matriz “worldOrientation”. De nuevo debe tenerse en cuenta que hay que modificar tanto la columna correspondiente al eje Y (la segunda), como la correspondiente al X (la primera), colocando respectivamente el vector “direccion_camara_deseada” y uno perpendicular a él hacia la derecha.
En este caso, dado que la dirección a adoptar es la de apunte de la cámara principal, no es necesario aplicar suavizado: ya se ha hecho lo propio con los movimientos de dicha cámara en el módulo “control_camara.py”. Además, cualquier movimiento brusco que pudiera darse en la cámara principal ocurriría al mismo tiempo en el mini-mapa, con lo que no constituirá una molestia mayor que la ocasionada en la propia pantalla principal.
En el Fragmento de código 52 aparecen las líneas del módulo “control_mapa_3.py” correspondientes a este método. Para usarlo en el fichero de prueba es necesario activarlo, quitando las comillas triples, y desactivar el anterior.
# Asignaciones del nivel superior... def main():
# Resto de lógica...
direccion_camara_final = -
Vector([camara_principal.worldOrientation[0][2],camara_principal
.worldOrientation[1][2]])
direccion_camara_final.normalize()
camara_mapa.worldOrientation[0][0] = direccion_camara_final[1]
camara_mapa.worldOrientation[1][0] = -direccion_camara_final[0]
camara_mapa.worldOrientation[0][1] = direccion_camara_final[0]
camara_mapa.worldOrientation[1][1] = direccion_camara_final[1]
Fragmento de código 52. Orientación de la cámara “camara_mapa” en la dirección de apunte de la cámara “camara_principal”.
Aspectos comunes