Análisis de código de aplicaciones ejemplo MS Windows 7 Multitouch: Puzzle Animales II

Windows Técnico

Sindicación

Proximos HOLs

Loading...

image

Para continuar con la descripción de código que se encuentra por detrás del proyecto didáctico “PuzzleAnimalesTouch” que ya se inicio en “Análisis de codigo de aplicaciones ejemplo MS Windows 7 Multitouch: Puzle Animales I” , en esta oportunidad se va a centrar la atención en los métodos que implementa la clase principal , ya que son los encargados de describir el comportamiento de los elementos que se encuentran dentro de la aplicación.

Para tener una visión general sobre lo que se va a analizar se puede observar la siguiente imagen donde de manera genérica se nombran a todos los métodos incluidos dentro de la clase “MainWindow”.

clip_image002

 Metodos de la clase MainWindow

·         Window_Loaded:

Esta función se genera automáticamente  ya que es llamada al iniciar  la ejecución de la aplicación y en ella se pueden inicializar los valores de los atributos de la clase, crear instancias que se van a usar a posteriori, etc..

Su equivalente en una aplicación de escritorio seria la función “Form_load

·         MainWindow

Este es el constructor de la clase principal, aquí se podrían inicializar o cambiar los valores de los atributos del objeto a crear.

public MainWindow()

{

     InitializeComponent();//

     this.pintar();

}

 

Como se puede apreciar, primero se hace una llamada a “InitializeComponent()“ para que cargue la página compilada de la ventana “MainWindow”.

Luego se realiza una llamado a la función “Pintar()”, que se describirá a continuación.

 

·         Pintar:

Esta función tiene como principal objetivo inicializar el panel de juego y dejarlo listo para que se interactúe con él.

Para ver el funcionamiento completo de este método se va a estudiar de la forma más detallada posible el código que implementa.

private void pintar()

{

 

       // Se inicializa los valores.

completado = 0;

 

// En la variable cconfig se va a guardar la información almacenada en 

// el fichero de configuración XML, para usarlo posteriormente.

 

var cconfig = from c in

             XElement.Load("configuracion.xml").Elements("animal")

select c;

 

      int nodos = 12; //Se define la cantidad total de nodos que tiene cconfig

           

// En esta sección se van a establecer la posición de las imágenes dentro // de lienzo principal donde están ubicados, especificando la distancia a // la que se debe ubicar, según las resolución de la pantalla.

 

this.image12.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) –

(SystemParameters.FullPrimaryScreenHeight / 4) -(60));

      this.image12.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) –

(SystemParameters.FullPrimaryScreenWidth / 4) - (60));

 

      this.image2.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) –

(SystemParameters.FullPrimaryScreenHeight / 4) –

(60));

      this.image2.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) +

(SystemParameters.FullPrimaryScreenWidth / 4) - (60));

 

      this.image3.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) +

(SystemParameters.FullPrimaryScreenHeight / 4) -(60));

this.image3.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) –

(SystemParameters.FullPrimaryScreenWidth / 4) - (60));

 

 

      this.image4.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) +

(SystemParameters.FullPrimaryScreenHeight / 4) -(60));

      this.image4.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) +

(SystemParameters.FullPrimaryScreenWidth / 4) - (60));

 

 

// Se va a crear 4 variables llamadas “uno” , ”dos” , ”tres” y “cuatro”, y

// se les va a asignar un numero aleatorio a cada uno de ellos.

// Si el numero aleatorio es igual a alguno anterior, se volverá a generar

// un numero aleatorio para esa variable.

// Estas variables serán utilizadas para coger cuatro animales del fichero

// de configuración XML

 

 

      Random numero = new Random();

      int uno = numero.Next(nodos);

      int dos = numero.Next(nodos);

      while (dos == uno)

         dos = numero.Next(nodos);

 

      int tres = numero.Next(nodos);

      while ((tres == uno) || (tres == dos))

         tres = numero.Next(nodos);

 

      int cuatro = numero.Next(nodos);

      while ((cuatro == uno) || (cuatro == dos) || (cuatro == tres))

         cuatro = numero.Next(nodos);

 

 

// Genera una lista inicializada llamada “lista”, y posteriormente se

// mezcla con la función desarrollada para tal fin

 

      int[] lista = { 0, 300, 600, 900 };

      lista = mezclar(lista);

 

 

// ###################################################################

// ################        ANIMAL    1          ######################

// ###################################################################

 

 

// Se va a usar una variable tipo “Var” para extraer los animales, según

// el numero aleatorio que contenga las variables.

     

var animal1 = cconfig.ElementAt(uno); // recoge el primer animal

 

// Se navega por el XML en busca de sus elementos.

 

      string foto = animal1.Element("foto").Value;

      string sonido = animal1.Element("sonido").Value;

 

// Y por último se crea un UserControl en tiempo real, con los valores que han sido recuperados del XML.

 

 

      u1 = new UserControl1(foto, sonido,

(double)this.image12.GetValue(Canvas.LeftProperty),

(double)this.image12.GetValue(Canvas.TopProperty),

"imagen1");

 

// También se definirá la ubicación de dicho UserControl dentro del lienzo donde será introducido.

 

 

      u1.SetValue(Canvas.LeftProperty, 30.0 + (lista[0] % 600) +

(SystemParameters.FullPrimaryScreenWidth / 3));

      u1.SetValue(Canvas.TopProperty, 150.0 * (lista[0] / 600) +

(SystemParameters.FullPrimaryScreenHeight / 3));

 

// Por último se define el manejador que determinará la coincidencia de

// las imágenes de los animales.

 

 

u1.Coincidencia += new EventHandler(u1_Coincidencia);

     

// se añade el UserControl “u1” al lienzo “juego”

 

      juego.Children.Add(u1);

           

// Y se cambia la imagen correspondiente al objeto “imagen12”, y se le da

// la imagen que se encuentra en el nodo “fotout” dentro del objeto  

// “animal1”

 

this.image12.Source = new BitmapImage(

new Uri(@animal1.Element("fotoout").Value)

);

 

// Se establece cual será la imagen que se mostrará cuando la figura del

//animal encaje correctamente en su posición final.

 

       fin1 = animal1.Element("fotoin").Value;

      

 

// De igual manera para los animales 2 , 3 y 4.

 

// ###################################################################

// ################        ANIMAL    2          ######################

// ###################################################################

 

animal1 = cconfig.ElementAt(dos);

 

       fin2 = animal1.Element("fotoin").Value;

       foto = animal1.Element("foto").Value;

       sonido = animal1.Element("sonido").Value;

 

       u2 = new UserControl1(foto, sonido,

(double)this.image2.GetValue(Canvas.LeftProperty),

(double)this.image2.GetValue(Canvas.TopProperty),

"imagen2");

 

       u2.SetValue(Canvas.LeftProperty, 30.0 + (lista[1] % 600) +

(SystemParameters.FullPrimaryScreenWidth / 3));

       u2.SetValue(Canvas.TopProperty, 150.0 * (lista[1] / 600) +

(SystemParameters.FullPrimaryScreenHeight / 3));

       u2.Coincidencia += new EventHandler(u1_Coincidencia);

      

 

       juego.Children.Add(u2);

 

       this.image2.Source = new BitmapImage(

new Uri(@animal1.Element("fotoout").Value)

);

 

// ###################################################################

// ################        ANIMAL    3         ######################

// ###################################################################

 

 

       animal1 = cconfig.ElementAt(tres);

 

       fin3 = animal1.Element("fotoin").Value;

       foto = animal1.Element("foto").Value;

       sonido = animal1.Element("sonido").Value;

 

        u3 = new UserControl1(foto, sonido,

(double)this.image3.GetValue(Canvas.LeftProperty), (double)this.image3.GetValue(Canvas.TopProperty), "imagen3"

);

        u3.SetValue(Canvas.LeftProperty, 30.0 + (lista[2] % 600) +

(SystemParameters.FullPrimaryScreenWidth / 3));

 u3.SetValue(Canvas.TopProperty, 150.0 * (lista[2] / 600) +

(SystemParameters.FullPrimaryScreenHeight / 3));

        u3.Coincidencia += new EventHandler(u1_Coincidencia);

       

        juego.Children.Add(u3);

 

        this.image3.Source = new BitmapImage(

new Uri(@animal1.Element("fotoout").Value)

);

 

 

// ###################################################################

// ################        ANIMAL    4          ######################

// ###################################################################

 

        animal1 = cconfig.ElementAt(cuatro);

 

        fin4 = animal1.Element("fotoin").Value;

        foto = animal1.Element("foto").Value;

        sonido = animal1.Element("sonido").Value;

 

 

u4 = new UserControl1(foto, sonido,

(double)this.image4.GetValue(Canvas.LeftProperty), (double)this.image4.GetValue(Canvas.TopProperty), "imagen4");

        u4.SetValue(Canvas.LeftProperty, 30.0 + (lista[3] % 600) +

(SystemParameters.FullPrimaryScreenWidth / 3));

        u4.SetValue(Canvas.TopProperty, 150.0 * (lista[3] / 600) +

(SystemParameters.FullPrimaryScreenHeight / 3));

           

u4.Coincidencia += new EventHandler(u1_Coincidencia);

      

       juego.Children.Add(u4);

      

       this.image4.Source = new BitmapImage(

new Uri(@animal1.Element("fotoout").Value)

);

 

// Por último se establecen las posiciones en las que se encontraran los // botones “Jugar”, “Salir” y “FinJuego”

 

       this.btnJugar.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) - 123);

       this.btnJugar.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) - 213);

 

       this.botonSalir.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) + 123);

       this.botonSalir.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) -45);

 

this.FINJuego.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) - 123);

       this.FINJuego.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) - 150);

 

       this.BotonRepetir.SetValue(Canvas.TopProperty,

(SystemParameters.FullPrimaryScreenHeight / 2) + 43);

       this.BotonRepetir.SetValue(Canvas.LeftProperty,

(SystemParameters.FullPrimaryScreenWidth / 2) - 50);

 

       this.BotonRepetir.Visibility = System.Windows.Visibility.Hidden;

       this.FINJuego.Visibility = System.Windows.Visibility.Hidden;

 

           

}

 

·         Mezclar

Esta función devuelve un array de números enteros, como resultado de reunir los valores del parámetro recibido y cambiarlos aleatoriamente de posición. Esta función será usada por “Pintar()” para posicionar aleatoriamente los animales en el lienzo de juego.

private int []  mezclar(int[]x) {

         // Vamos a recorrer la lista desde el final

         int i = x.Length;

         while (i>0) {

         // aleatoriamente elegimos otro elemento entre [0] e [i] (incluido)

             Random numero = new Random();

             int k = numero.Next(4);

      

             i--;

             //intercambiamos x[i] con x[k]

             int temp = x[i];

             x[i] = x[k];

             x[k] = temp;

         }

         return x;

}

 

·         midiOutClose,midiOutOpen,midiOutShrtMsg

Estas funciones hacen llamadas a la API de Windows en relación con la apertura y cierre de dispositivos de salida, como puede ser los altavoces del equipo. Para poder hacer uso de estas funciones se tiene que agregar la referencia a la librería “winmm.dll” de Windows Media Player.

 

·         MidiOutShrtMsg:

Una vez abierto un dispositivo de salida, una de las operaciones más sencillas a realizar, pero a la vez más operativas, consiste en enviar mensajes MIDI. El envío de cada mensaje (un Note On, un Note Off, un cambio de programa, etc.) requerirá una nueva llamada a la función “MidiOutShrtMsg”, que contendrá como argumento el mensaje que deseemos enviar.

·         u1_Coincidencia

Este evento es lanzado cuando se cumple la condición del “UserControl1” de encajar la figura del animal en su lugar correspondiente.

Para conocer dicha condición, en la siguiente entrada se describirá extensamente la clase “UserControl1” del proyecto  PuzleAnimales”.

 

void u1_Coincidencia(object sender, EventArgs e)

{

     if ((string)sender == "imagen1")

     {

           this.image12.Source = new BitmapImage(new Uri(@fin1));

           this.final();

     }

     if ((string)sender == "imagen2")

     {

           this.image2.Source = new BitmapImage(new Uri(@fin2));

           this.final();

     }

     if ((string)sender == "imagen3")

     {

           this.image3.Source = new BitmapImage(new Uri(@fin3));

           this.final();

     }

     if ((string)sender == "imagen4")

     {

           this.image4.Source = new BitmapImage(new Uri(@fin4));

           this.final();

     }

}

 

Si dicha condición se cumple, la imagen del objeto “image” cambiará por su versión final que es similar a la anterior con el detalle que tiene un borde amarillo como si de una luz de tratase.

Después de cambiar la imagen se emitirá un sonido identificando el acierto.

·         final

Cuando se encaja correctamente una pieza en su lugar correspondiente, se incrementa la variable “completado” hasta llegar a un valor de cuatro.
En ese momento se procederá mostrar el “botonRepetir”, por si se desea reiniciar el juego. También se muestra el texto “FINJuego” dando a conocer que se han colocado correctamente todas las piezas correctamente y por último se emitirá un sonido conclusivo que corresponde al valor de la variable “sonidoFinal”.

 

private void final()

   {

       completado++;

       if (completado == 4)

       {

           this.BotonRepetir.Visibility = System.Windows.Visibility.Visible;

           this.FINJuego.Visibility = System.Windows.Visibility.Visible;

           WMPLib.WindowsMediaPlayer Player;

           Player = new WindowsMediaPlayer();

           string r = System.IO.Directory.GetCurrentDirectory();

           r = r + sonidofinal;

           string ruta = r;

           Player.URL = @ruta;

           Player.controls.play();

       }

  

  

          

   }

 

Eventos

·         BotonRepetir_TouchDown

Este evento se lanza cuando se pulsa sobre el botón “Play”, es decir, se vuelve a ejecutar la función “Pintar()” reiniciándose de esta forma el juego.

 

private void BotonRepetir_TouchDown(object sender, TouchEventArgs e)

        {

            this.pintar();

        }

 

·         botonSalir_TouchDown

Al pulsar sobre el botón de “Salir” la aplicación cancelará su ejecución,  cerrando la ventana de juego.

 

private void botonSalir_TouchDown(object sender, TouchEventArgs e)

        {

            this.Close();

        }

·         botonSalirJuego_TouchDown

Cuando se pulsa sobre el “botónSalirJuego”, que se encuentra dentro del panel de juego, dicho lienzo se oculta y se deja a la vista solamente el lienzo de inicio, dando así la posibilidad de volver al juego o salir definitivamente de la aplicación.

private void botonSalirJuego_TouchDown(object sender, TouchEventArgs e)

        {

            this.inicio.Visibility = System.Windows.Visibility.Visible;

            this.juego.Visibility = System.Windows.Visibility.Hidden;

 

            ImageBrush brush = new ImageBrush();

 

            brush.ImageSource = new BitmapImage(new Uri(

@"pack://application:,,,/PuzleAnimalTouch;

component/Images/FondoPuzzle.png",

UriKind.Absolute));

            this.canvas1.Background = brush;

        }

      

Como se puede ver, también se establece un nuevo fondo para la aplicación definiendo el “background” de la ventana sobre la que estamos interactuando.

·         btnJugar_TouchDown

Con este evento de captura la acción de pulsar sobre el botón “jugar”, y en este caso sirve para ocultar el lienzo de “inicio” y mostrar el lienzo de juego.

También se aprovecha para mostrar el “botonSalirJuego”, y establecer el fondo de la ventana, modificando el valor del “background”.

private void btnJugar_TouchDown(object sender, TouchEventArgs e)

{

        this.inicio.Visibility = System.Windows.Visibility.Hidden;

        this.juego.Visibility = System.Windows.Visibility.Visible;

        double a = (double)this.inicio.Width;

        a = SystemParameters.FullPrimaryScreenHeight;

 

 

        ImageBrush brush = new ImageBrush();

 

        brush.ImageSource = new BitmapImage(

new Uri(

@"pack://application:,,,/PuzleAnimalTouch;

component/Images/fondo.jpg",

UriKind.Absolute

)

);

        this.canvas1.Background = brush;

        this.botonSalirJuego.SetValue(Canvas.LeftProperty,

SystemParameters.FullPrimaryScreenWidth

       - 120);

 

// Se oculta el mensaje final que anuncia que todas las piezas del

// puzle han sido encajadas satisfactoriamente.

 

        this.FINJuego.Visibility = System.Windows.Visibility.Hidden;

 

        

}

En la siguiente entrada se concluirá el análisis de código de este proyecto entrando en detalle del control de usuario que posee interesantes propiedades que le permiten el movimiento dentro del lienzo de juego.

 

Para acabar, recuerda que si quieres aprender mucho más sobre los secretos de los sistemas Microsoft Windows, te recomendamos leer el libro de Sergio de los Santos "Máxima Seguridad en Windows: Secretos Técnicos" , o siempre puedes suscribirte al Canal RSS de Windows Técnico para estar al día de las novedades e información técnica de interés.

image

 

------------------------------------------------------------------------------------------------------------------------

Análisis de código de aplicaciones ejemplo MS Windows 7 Multitouch: Puzzle Animales I

Análisis de código de aplicaciones ejemplo MS Windows 7 Multitouch: Puzzle Animales II

Análisis de código de aplicaciones ejemplo MS Windows 7 Multitouch: Puzzle Animales III

------------------------------------------------------------------------------------------------------------------------


Enviado ago 06 2011, 07:36 por Jhonattan Fiestas

Comentarios

Windows Técnico escrito Análisis de código de aplicaciones ejemplo MS Windows 7 Multitouch: Puzzle Animales III
en 08-11-2011 18:17

  Con esta entrada se dará conclusión a la serie dedicada al análisis de código realizado sobre

Añadir un comentario

(requerido)  
(opcional)
(requerido)  
Recordarme
If you can't read this number refresh your screen
Enter the numbers above: