Como se venía anunciando en la anterior entrada de la serie “Desarrollo de aplicaciones MS Windows 7 Multitouch: SonidosAnimales I”, en esta ocasión se intentará desarrollar por completo el código que describe el funcionamiento de la aplicación “SonidoAnimales”, en concreto se analizará el código que se encuentra en la clase “MainWindow”, dejando para el siguiente post la descripción minuciosa de los controles de usuario que componen esta aplicación.

La clase “MainWindow” podría ser considerada el alma de la aplicación, ya que en ella se encuentra la base para la ejecución del proyecto y desde allí se hace llamada a las demás clases que complementarían de funcionalidades a las características que disponga “MainWindow”.Para obtener una idea global de la clase mencionada, en el siguiente grafico se muestran los campos y métodos que implementa, para posteriormente definirlos uno a uno de la forma más detallada posible.

Campo “handle”:
El campo “handle” es un número entero que será utilizado como referencia a la hora de hacer una llamada a la función “midiOutOpen” que será descrita una vez más en esta entrada.
Métodos o funciones:
· midiOutOpen:
Esta función hace llamadas a la API de Windows en relación con la apertura 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, como se puede apreciar en el código que la implementa.
[DllImport("winmm.dll")]
private static extern int midiOutOpen(ref int handle, int deviceID,
MidiCallback proc, int instance, int flags);
· Window_Loaded:
Función con finalidad similar al método “Form_load” de un proyecto “.Net”, y es donde se podrían inicializar varios de los campos necesarios para el inicio de la aplicación. En este proyecto, el “Window_Loaded” estará vacío ya que los campos que serán inicializados lo serán directamente desde el constructor de la clase.
· MainWindow
Es el constructor de la clase y en esta oportunidad la clase “MainWindow” solo dispone de un constructor implícito en el cual se van a inicializar los valores que se consideren necesarios.
Como una pequeña aclaración se dirá que cuando se haga alusión a “image1” se estará haciendo referencia a la imagen
que es utilizada para generar el evento de “TouchDown”, con el cual se inicia el juego.
Se procederá a ver el código del constructor línea a línea describiendo, en forma de comentario, cada acción que se realice.
public MainWindow()
{
InitializeComponent();
// Al iniciar la ejecución solo es visible el lienzo “inicio” por lo tanto
// el lienzo “juego”debe estar oculto
juego.Visibility = System.Windows.Visibility.Hidden;
// Se genera un ImageBrush para ser utilizado como fondo del lienzo principal
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(
new Uri(@"pack://application:,,,/JuegoSonidosAnimales;
component/Images/FondoSonidosAnimales.png"));
// El “botonRepetir” debe está oculto también, ya que solo debe estar
// visible cuando el lienzo “juego” este visible.
this.BotonRepetir.Visibility = System.Windows.Visibility.Hidden;
// Se establece la localización del “botonSalir” dentro del lienzo
this.botonSalir.SetValue(Canvas.TopProperty,
(SystemParameters.FullPrimaryScreenHeight / 2) + 123);
this.botonSalir.SetValue(Canvas.LeftProperty,
(SystemParameters.FullPrimaryScreenWidth / 2) - 45);
// Se igual manera con el “image1”.
this.image1.SetValue(Canvas.TopProperty,
(SystemParameters.FullPrimaryScreenHeight / 2) - 83);
this.image1.SetValue(Canvas.LeftProperty,
(SystemParameters.FullPrimaryScreenWidth / 2) - 160);
// Se cambia el fondo del lienzo principal
this.Padre.Background = imgBrush;
}
· BotonRepetir_TouchDown:
Este método es llamado cuando se desencadena el evento relacionado a pulsar sobre el “botonRepetir”, y su finalidad es volver a pintar el lienzo de juego, lo cual originará que se coloquen seis nuevos animales aleatorios.
private void BotonRepetir_TouchDown(object sender, TouchEventArgs e)
{
pintarjuego();
}
· botonSalir_TouchDown:
Esta función se ejecutará cuando el usuario pulse sobre el “botonSalir” que se encuentra situado en el lienzo “Inicio”, ocasionando el cierre por completo de la aplicación.
private void botonSalir_TouchDown(object sender, TouchEventArgs e)
{
this.Close();
}
· botonSalirjuego_TouchDown:
Esta función difiere de la anterior sobre todo por lo que uno entiende por “salir”.
En este caso cuando se hace referencia a la palabra “Salir” se está hablando de salir del lienzo “juego” y volver al lienzo de “inicio”.
Si lo que se desea es salir completamente de la aplicación, se puede dar a salir al botón correspondiente dentro del lienzo “inicio”.
El código que hay por detrás de este método es fácilmente interpretable, y será descrito como se ha hecho con anterioridad por medio de comentarios en dicho código.
private void botonSalirjuego_TouchDown(object sender, TouchEventArgs e)
{
// Se ocultan los botones que se mostraban en el lienzo “juego”
botonSalirjuego.Visibility = System.Windows.Visibility.Hidden;
this.BotonRepetir.Visibility = System.Windows.Visibility.Hidden;
// Se oculta el lienzo de juego, ya que se desea volver al de inicio
this.juego.Visibility = System.Windows.Visibility.Hidden;
// Se vuelve a hacer visible el lienzo de inicio
this.Inicio.Visibility = System.Windows.Visibility.Visible;
// y se vuelven a hacer visibles los botones propios de dicho lienzo.
this.image1.Visibility = System.Windows.Visibility.Visible;
this.botonSalir.Visibility = System.Windows.Visibility.Visible;
// Por último se cambia el fondo del panel padre.
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new
Uri(@"pack://application:,,,/JuegoSonidosAnimales;
component/Images/FondoSonidosAnimales.png"));
this.Padre.Background = imgBrush;
}
· image1_TouchDown:
Este botón corresponde con
, por lo tanto al pulsar sobre él se desencadena el evento “Click” que llamara a este método, como puede verse en el código, hará una llamada al método “pintarJuego”, reiniciándose el juego con seis nuevos animales cogidos de manera aleatoria.
private void image1_TouchDown(object sender, TouchEventArgs e)
{
pintarjuego();
}
· pintarJuego:
Esta es la función principal de la clase “MainWindow” que se encargará de eliminar todos los controles que se encuentren dentro del lienzo de juego, colocando seis nuevos en cada ocasión valiéndose de números aleatorios, con los cual podrían salir seis animales de los catorce posibles. Todo esto se realizara en tiempo de ejecución.
En el código esta descrito todas las acciones paso a paso, para que no quede duda de la funcionalidad de este método.
public void pintarjuego()
{
// Se establecen una variable nodos, que corresponde con el número de
// animales que se encuentran contenidos en el fichero “configuración.xml”
int nodos=14;
// Se oculta todo lo relacionado con el lienzo de inicio
Inicio.Visibility = System.Windows.Visibility.Hidden;
this.image1.Visibility = System.Windows.Visibility.Hidden;
this.botonSalir.Visibility = System.Windows.Visibility.Hidden;
// Se muestra todo lo relacionado con el lienzo “juego”
juego.Visibility = System.Windows.Visibility.Visible;
botonSalirjuego.Visibility = System.Windows.Visibility.Visible;
this.BotonRepetir.Visibility = System.Windows.Visibility.Visible;
botonSalirjuego.SetValue(Canvas.LeftProperty,
SystemParameters.FullPrimaryScreenWidth - 120);
int numerohijos = juego.Children.Count; // Número de controles que “juego”
// Se buscará, si existen, controles de usuario en el lienzo, y si es así
// se añaden a una lista, para posteriormente preguntar por su ubicación
// dentro de la lista de controles y posteriormente eliminarlos, para que
// en la próxima carga hayan controles completamente nuevos.
int posicionEliminar = 0;
List<UIElement> controlespropios = new List<UIElement>();
foreach (UIElement hijo in juego.Children)
if (hijo.GetType().Name == "UserControl1")
{
controlespropios.Add(hijo);
}
foreach (UIElement hijo2 in controlespropios)
{
//Aquí se elimina un control en tiempo de ejecución.
posicionEliminar = juego.Children.IndexOf(hijo2);
juego.Children.RemoveAt(posicionEliminar);
}
// Se genera una imagen para posteriormente cambiar el fondo del lienzo “padre”
ImageBrush imgBrush = new ImageBrush();
imgBrush.ImageSource = new BitmapImage(new
Uri(@"pack://application:,,,/JuegoSonidosAnimales;
component/Images/fondo_rojo.jpg"));
// Se carga en cconfig el conjunto de animales que se encuentran en el
// fichero configuración.xml que se encuentra en la raíz de la
// aplicación. Si se desease coger el fichero del mismo nombre que se
// encuentra en la carpeta “config”, bastaría con cambiar
// XElement.Load("configuracion.xml") por XElement.Load("config/configuracion.xml")
int i = 0;
var cconfig = from c in XElement.Load("configuracion.xml").Elements("animal")
select c;
// Se genera una lista de números aleatorios.
List <int> numeros = new List<int>();
Random numero = new Random();
int uno = numero.Next(nodos);
numeros.Add(uno); //El primero ingresa directamente
//Los siguientes entrarán a la lista solo si no son iguales a los anteriores.
int dos = numero.Next(nodos);
while (dos == uno)
dos = numero.Next(nodos);
numeros.Add(dos);
int tres = numero.Next(nodos);
while ((tres == uno) || (tres == dos))
tres = numero.Next(nodos);
numeros.Add(tres);
int cuatro = numero.Next(nodos);
while ((cuatro == uno) || (cuatro == dos) || (cuatro == tres))
cuatro = numero.Next(nodos);
numeros.Add(cuatro);
int cinco = numero.Next(nodos);
while ((cinco == uno) || (cinco == dos) || (cinco == tres) || (cinco==cuatro))
cinco = numero.Next(nodos);
numeros.Add(cinco);
int seis = numero.Next(nodos);
while ((seis == uno)||(seis == dos)||(seis == tres)||(seis==cuatro)||(seis==cinco) )
seis = numero.Next(nodos);
numeros.Add(seis);
// Casi para terminar, por cada elemento que haya en la lista “números”, se
// hace una búsqueda en el objeto “cconfig”, y de allí se crea un control
// de usuario en que será insertado en el lienzo en tiempo de ejecución
foreach (int pos in numeros)
{
var cadena = cconfig.ElementAt(pos);
string foto = cadena.Element("foto").Value;
string sonido = cadena.Element("sonido").Value;
string nombre = cadena.Element("nombre").Value;
//Se crea un control de usuario con los parámetros recogidos anteriormente
UserControl1 u2 = new UserControl1(foto, sonido, nombre);
u2.SetValue(Canvas.LeftProperty, 30.0 + (i % 600));
u2.SetValue(Canvas.TopProperty, 150.0 * (i / 600));
i = 300 + i;
// Y se inserta en el lienzo de juego en tiempo de ejecución
juego.Children.Add(u2);
}
// Para finalizar se cambia la imagen de fondo del lienzo “padre”.
this.Padre.Background = imgBrush;
}
Como ya se ha adelantado, en la próxima entrada se hará estudio de los controles de usuario creados en esta aplicación, de forma que quede visible la extensa lista de posibilidades que ofrece a los desarrolladores.
Si deseas continuar informado sobre las publicaciones de desarrollo, seguridad y novedades en torno a las tecnologías Microsoft no dudes en suscribirte al canal de RSS de Windows Técnico .

------------------------------------------------------------------------------------------------------------------------
Desarrollo de aplicaciones MS Windows 7 Multitouch: SonidosAnimales I
Desarrollo de aplicaciones MS Windows 7 Multitouch: SonidosAnimales II
Desarrollo de aplicaciones MS Windows 7 Multitouch: SonidosAnimales III
------------------------------------------------------------------------------------------------------------------------
Enviado
ago 17 2011, 07:35
por
Jhonattan Fiestas