viernes, 28 de febrero de 2014

Desarrollo de videojuegos con Qt Quick + QML

 

image

Qt es un framework que consta de herramientas destinadas a la creación rápida y eficiente de aplicaciones e interfaces de usuario para escritorio, sistemas embebidos y plataformas móviles. Con Qt es posible reutilizar el código de forma eficiente para ser desplegado en diferentes plataformas con un mismo código base. La biblioteca de clases en C++ y las diferentes herramientas permiten al programador crear aplicaciones en una plataforma y compilarla y distribuirlas en otras.

Entre los diferentes módulos de Qt se encuentra Qt Quick el cual es una biblioteca estándar para el desarrollo de aplicaciones con QML. Mientras el módulo QML brinda el motor y la infraestructura del lenguaje, Quick brinda todos los tipos básicos necesarios para la creación de interfaces gráficas. Posee un canvas para mostrar el contenido y diferentes tipos de datos para la creación y animación de componentes visuales, procesamiento de la entrada de teclado y ratón, creación de modelos y vistas de datos y la creación retardada de objetos. El módulo Quick brinda una API QML la cual provee los tipos de datos QML para la creación de interfaces gráficas y una API C++ para extender las aplicaciones QML con código C++.

Qt Quick provee todo lo necesario para crear aplicaciones potentes con una interfaz gráfica dinámica y fluida. Las animaciones y los efectos de transición entre estados son elementos de vital importancia para este módulo. Los efectos visuales pueden ser complementados con componentes especiales como sistemas de partículas y shaders. A continuación se muestran algunas características de Qt Quick que lo convierten en una buena elección para el desarrollo de videojuegos sencillos:

Alto rendimiento con grafo de escena: Qt Quick (versión 2.0) requiere OpenGL 3.0 (u OpenGL 2.x con la extensión framebuffer_object) para renderizar la ventana diseñada en QML. El módulo define un grafo de escena que es luego renderizado. Mediante el uso de la GPU se logra mucho mayor rendimiento que en la versión anterior.

Entradas de usuarios: Qt Quick brinda los siguientes elementos para procesar entradas:

  • Táctil: Qt Quick fue diseñado teniendo en mente las pantallas táctiles y por esto cuenta con eventos táctiles soportados por diferentes elementos visuales.
  • Ratón: el módulo cuenta con el elemento MouseArea el cual recibe automáticamente eventos de ratón (como clicks y eventos de rueda).
  • Teclado: cualquier elemento visual recibe entradas de teclados a través del tipo Key.
  • Gestos de movimientos en dispositivos: Qt Quick por si mismo no ofrece soporte de nativo para gestos físicos de dispositivos pero el módulo Qt Sensors provee tipos QML los cuales soportan dichos gestos.

Estados, transiciones y animaciones: un aspecto llamativo de los juegos son las transiciones entre estados y las animaciones que brindan un atractivo visual al usuario, en Qt Quick estos son conceptos de máxima importancia.

· Estados: el estado de un elemento visual es el conjunto de informaciones que describe cómo y dónde se muestran las diferentes partes que conforman el elemento y todos los datos asociados al estado. Qt Quick provee el elemento State que contiene propiedades que definen su semántica y se puede utilizar para desencadenar comportamiento o animaciones.

· Transiciones: cuando un elemento cambia de un estado a otro su apariencia cambia, una transición es lo que separa dos estados. Qt Quick provee el elemento Transition el cual define lo que ocurre cuando se pasa de un estado a otro.

· Animaciones: cuando se pasa de un estado a otro se puede utilizar una animación para suavizar la transición. Cambios abruptos de la interfaz resultan en una mala experiencia visual y deben ser evitados utilizando animaciones.

· Animación de propiedades: las animaciones no solo están relacionadas con estados y transiciones entre estados. A veces es útil animar el cambio de ciertas propiedades de los elementos, por ejemplo la opacidad. Qt Quick provee el elemento PropertyAnimation que se puede utilizar para este fin.

· Animadores: el tipo Animator es un tipo especial de animación el cual sobrepasa el objeto QML y opera directamente en las primitivas del grafo de escena. Entre los animadores se encuentran: XAnimator, YAnimator, ScaleAnimator, RotationAnimator, OpacityAnimator y UniformAnimator.

Datos, Modelos, Vistas y Almacenamiento de datos: la mayoría de los juegos tienen datos guardados que necesitan mostrar al usuario, estos datos pueden venir de la red, ficheros locales o bases de datos.

· Modelos y vistas: a veces es útil mostrar un mismo dato de diferentes maneras, de esta manera surge la idea de tener un modelo que contiene los datos y las vistas las cuales muestran los datos. El paradigma Modelo/Vista está implementado en Qt Quick el cual puede ser utilizado en el juego.

· Almacenamiento y acceso a datos: las bases de datos son utilizados comúnmente para almacenar información en los juegos, como por ejemplo los records de puntos o de tiempo alcanzados por los jugadores en los diferentes niveles. El módulo Qt Quick local storage provee acceso simplificado a bases de datos relacionales.

Partículas y efectos gráficos: los juegos con interfaces gráficas llamativas resultan más interesantes. El módulo Qt Quick provee herramientas para lograr una aplicación visualmente atractiva pero manteniendo la experiencia de usuario.

  • Transformación visual: los elementos visuales pueden ser transformados, por ejemplo escalados o rotados.
  • Efectos de shader: los efectos de shader permiten utilizar al máximo la capacidad de procesamiento de la tarjeta grafica mediante vextex o fragment shaders.
  • Partículas: el sistema de partículas permite crear explosiones, fuegos artificiales, humo, niebla, efectos de viento incluso gravedad y turbulencia.
  • Sprites: un sprite es un tipo de imagen animada constituida por frames. Qt Quick provee un tipo de dato visual para visualizar sprites los cuales pueden ser utilizados en juegos.
  • Opacidad: los objetos pueden ser opacos o traslucidos, por ejemplo se puede hacer un objeto opaco y otro transparente para centrar la atención del usuario en el opaco.

Tipos de datos convenientes: en un juego muchas veces el programador necesita reaccionar a eventos y desencadenar varias respuestas. QML tiene soporte para estos conceptos a través de enlaces, señales, gestores de señales e inicialización dinámica de objetos.

  • Inicialización dinámica de objetos: QML provee varias maneras de crear y gestionar objetos. Se pueden crear dinámicamente mediante Javascript o utilizando los tipos de datos Loader, Repeater, ListView, GridView y PathView.
  • Conexión dinámica de señales: QML soporta la conexión dinámica de señales a través del método connect().
  • Eventos basados en timers: otro caso común es desencadenar una funcionalidad un periodo de tiempo después de que un evento ocurra. Qt Quick provee el tipo Timer, el cual posee soporte para eventos simples o recurrentes.

Lógica del juego en Javascript: la lógica del juego se puede programar mediante un fichero Javascript. Este es un lenguaje mucho más sencillo que C++ pero que tiene todas las herramientas para desarrollar un juego de calidad. Para llamar a las funciones desde la interfaz solo basta con importar el fichero, y para acceder a los elementos de la interfaz desde el fichero Javascript simplemente hay que utilizar el id de cada elemento. Además el código puede ser depurado mediante Qt Creator solo hay que poner un breakpoint en la función y ejecutar la aplicación con F5. En el modo de depuración se puede ir observando el valor de las variables y así encontrar errores que de otra manera serían difíciles de detectar.

Todas las características de Qt Quick mencionadas anteriormente demuestran que es un módulo muy potente para la creación de juegos. Con relativamente poco código haciendo uso del lenguaje declarativo QML se puede lograr un juego atractivo y tan complejo como se quiera. En la ayuda de Qt se pueden encontrar varios ejemplos de todo lo que se puede lograr con este módulo. Es recomendable utilizarlo en juegos 2D y aplicaciones para pantallas táctiles para sacarle el máximo provecho a todas las características que posee.

{ Leer Más }


miércoles, 19 de febrero de 2014

Leer ficheros de texto con Php.

En algunas aplicaciones nos es necesario entrar información al sistema obtenida desde ficheros de texto en lugar de utilizar formularios. Por ejemplo si tenemos facturas de productos vendidos, el proceso sería más rápido si cargamos estos ficheros y procesamos la información que nos interesa en un proceso automático.

En este artículo queremos brindar algunas prácticas interesantes para realizar este procesamiento utilizando las ventajas para el trabajo con ficheros que nos brinda Php.

Por ejemplo utilizando el caso de productos que habíamos mencionado, supongamos que tenemos un fichero en formato txt que tiene la información de una factura, pondremos un caso bien sencillo donde tenemos el número de factura, algunos datos adicionales del emisor y receptor de la factura y una tabla que contiene los detalles de la venta realizada:

En este caso podemos leer el fichero línea a línea e ir realizando las validaciones que nos interesan y recoger la información. Para realizar el procesamiento del fichero e ir sacándonos del programa cuando se encuentre que no cumple algunas reglas de validación podemos usar las sentencias Try-catch y lanzamos el error detectado.

Por ejemplo:

<?php          
try{
if (file_exists("Factura.txt")===FALSE)
throw new Exception('El fichero no existe.');
$text = file_get_contents("Factura.txt");
if ($text === FALSE)
{
throw new Exception('El fichero no puedo ser leído.');
}
$text= mb_convert_encoding($text, 'UTF-8',mb_detect_encoding($text, 'UTF-8, ISO-8859-1', true));
$texts = explode("\n",$text);
echo "Fichero leído correctamente." ;
}
catch (Exception $e)
{
echo 'Excepción capturada: ', $e->getMessage(), "\n";
}
?>

Con la función file_exists verificamos que efectivamente el fichero exista en nuestro directorio, y procedemos a leer el archivo completo como una única cadena con file_get_contents, en caso de fallo esta función devuelve false. Y finalmente en este bloque dividimos esa cadena en líneas, para esto hacemos uso de una función muy interesante para este caso que es la función explode que divide una cadena ($text) por otra (“/n”) en este caso fin de línea y nos devuelve una matriz que contiene las subcadenas contenidas en la cadena $text y separadas por el fin de línea. Ya con esto tenemos en $texts el fichero línea a línea.

Para las primeras cuatro líneas hacemos un procesamiento similar en todos los casos, siempre debe leerse una etiqueta determinada y después la información asociada a esta etiqueta:

$invoice_no = trim($texts[0]);
$invoice_no = explode("Factura No.",$invoice_no);
if(count($invoice_no)!=2)
throw new ErrorException('La etiqueta "Factura No." no existe o está escrita incorrectamente');
$invoice_no = trim($invoice_no[0]);

Siempre es interesante utilizar la función trim para eliminar los espacios en blanco (u otros caracteres) del principio y final de la cadena. Siempre verificamos en estos caso que la cantidad de elementos contenidos en la matriz $invoice_no después de aplicar explode no puede ser diferente de 2, porque si la información viene correctamente en la posición 1 vamos a obtener la que nos interesa.

Lo que sigue es leer la información de la tabla de productos, para eso primeramente verificamos que los datos de la cabecera sean correctos, comparándolo con un arreglo que previamente tenemos y después en un ciclo recorremos los productos hasta llegar al fin de la tabla, asumimos que terminamos la lectura de la tabla cuando llegamos a encontrar la cadena “Total:” que es lo que sigue detrás de la misma.

$cabecera = array('Cantidad','Nombre','Precio Unitario', 'Descuento', 'Importe');
$cabecera_tabla = trim($texts[5]);
$cabecera_tabla = explode("\t",$cabecera_tabla);
$result= array_diff($cabecera_tabla,$cabecera);
if(!empty($result))
throw new ErrorException("Los datos de la cabecera de la tabla de productos están escritos incorrectamente");

$datos = array();
$tabla = true;
$no_producto = 0;
$j= 6;
while ($tabla==TRUE)
{
//Verificar si se terminó la tabla
$end = strpos($texts[$j], 'Total:');
if($end === FALSE)
{
$detalle = explode("\t",trim($texts[$j]));
$datos[$no_producto]->CANTIDAD = $detalle[0];
$datos[$no_producto]->NOMBRE = $detalle[1];
$datos[$no_producto]->PRECIOUNITARIO = $detalle[2];
$datos[$no_producto]->DESCUENTO = $detalle[3];
$datos[$no_producto]->IMPORTE = $detalle[4];
$no_producto++;
$j++;
}
else
{
//termino la tabla
$tabla = false;
}
}

La función strpos devuelve la posición numérica de la primera aparición de una cadena, si necesitáramos la cadena en sí utilizáramos strstr aunque esta última es más lenta y consume más memoria. Si no queremos distinguir entre mayúsculas y minúsculas podemos utilizar stripos y stristr.

Es todo, espero haya sido de utilidad.

{ Leer Más }


martes, 11 de febrero de 2014

Creando servicios en .NET

Hola, en este post le voy a explicar cómo crear servicios de Windows con .NET. ¿Pero qué son los servicios?

Los servicios de Windows son aplicaciones que corren en segundo plano y no necesitan la interacción del usuario. De hecho ni siquiera tienen interfaz visual. Son ideales ejecutar tareas de larga duración que se ejecutan cada cierto intervalo de tiempo o al desencadenarse una acción determinada en nuestra PC. Pueden ver la definición formal que dan nuestros amigos de Microsoft acá: http://msdn.microsoft.com/es-es/library/d56de412%28v=vs.110%29.aspx

Entre los beneficios más importantes de los servicios están que se ejecutan automáticamente al inicio de Windows, incluso sin la necesidad de que un usuario se haya logado, además permiten escoger el tipo de cuenta de sesión para iniciar, lo que nos la posibilidad de administrar los permisos y privilegios con que se ejecutará el servicio.

¿Cómo podemos ver un listado de todos los servicios que están ejecutándose en nuestra PC?, muy sencillo, en Microsoft Windows 7, pulsamos el botón "Iniciar" - "Panel de control" - "Herramientas administrativas" - "Servicios". Y nos mostrara una pantalla como esta con todos los servicios instalados en nuestra PC:

clip_image002

Para desarrollar nuestro propio servicio utilizaremos Visual Studio y unos de sus proyectos personalizados para la creación de servicios:

clip_image004

Después de crear el proyecto estamos listos para desarrollar nuestro servicio. Vamos a desarrollar un servicio de ejemplo que escriba en un fichero cada 15 segundos el texto:

“Mi Primer servicio!!!!!!”

Seleccionamos el fichero Service1.cs en nuestro explorador de soluciones y tendremos algo parecido a esto:

clip_image006

Como se puede observar tenemos una clase que hereda de ServiceBase que es la clase que provee las interfaces de los métodos de OnStart() y OnStop() que son los invocados automáticamente cuando se inicia y termina el servicio. Otro punto de interés son las propiedades de los servicios entre ellas podemos destacar:

· AutoLog: Indica si los comandos Iniciar, Detener, Pausar y Continuar deben notificarse en el registro de eventos.

· CanPauseAndContinue: Obtiene o establece un valor que indica si se puede pausar y reanudar el servicio.

· CanStop: Obtiene o establece un valor que indica si puede detenerse el servicio una vez se ha iniciado.

El listado completo de todas las propiedades y sus especificaciones las pueden encontrar en: http://msdn.microsoft.com/es-es/library/system.serviceprocess.servicebase%28v=vs.110%29.aspx

En la siguiente imagen se puede ver que no hay mucha complicación, creamos un componente Timer nos registramos al evento Elapsed y cada vez que pase el tiempo configurado abrimos un fichero y escribimos en él.

clip_image008

No olvidar llamar a las funciones de inicio y fin del temporizador, en los métodos OnStart() y OnStop() del servicio:

clip_image010

Justo ahora estamos listos para hacer el instalador del servicio, esta operación es muy sencilla de realizar tan solo con oprimir click derecho sobre la vista de diseño del servicio y nos saldrá una opción para la creación del instalador:

clip_image012

En este momento se nos adicionaran dos nuevas clases a nuestra solución, serviceProcessInstaller1 y serviceInstaller1:

clip_image014

Configuramos las propiedades del instalador como muestran las siguientes imágenes. Acá podemos configurar el nombre que tendrá el servicio, la descripción, el tipo de cuenta que iniciara el servicio y otras propiedades que nos podrían ser útiles.

clip_image016 clip_image018

Ya ahora lo que nos resta es instalar nuestro servicio, para ello utilizaremos la linea de comandos del Visual Studio. La podemos encontrar en "Iniciar" - "Todos los Programas" - "Microsoft Visual Studio 2010" - "Visual Studio Tools" - "Visual Studio 2010 Command Prompt". La ejecutamos en modo administrador y utilizando el aplicación InstallUtil.exe instalamos nuestro servicio.

Para instalar : InstallUtil.exe miServicio.exe

Para desintalar : InstallUtil.exe /u miServicio.exe

clip_image020

Despues de instalado el servicio lo mandamos a iniciar, en caso que no lo este, y si todo va bien pues podremos ver como cada 15 segundos se adiciona el texto en nuestro fichero:

clip_image022

clip_image024

Esto es todo, para el próximo post les estaré comentado como depurar este tipo de aplicaciones.

{ Leer Más }


miércoles, 5 de febrero de 2014

Cómo mostrar Popup utilizando Jquery sobre CodeIgniter.

En algunas aplicaciones web a veces es deseado mostrar una apariencia de aplicación de escritorio donde al dar clic sobre las acciones que deseamos realizar, en lugar de cargar páginas nuevas con la información deseada, nos mantenemos en la misma vista y lo que mostramos son ventanas emergentes (Popup) que podemos manipular siempre desde la misma vista principal.

En este artículo estaremos mostrando como mostrar esos Popup utilizando Jquery y a través de Ajax traemos la información necesaria para ello.

Lo primero que hay que tener es desde donde vamos a dar clic para que salga nuestra nueva ventana, por ejemplo algún link de este tipo:

<a href="#" class="mi_popup">Nueva Ventana</a>

Notar como hemos definido la clase “mi_popup” que es la que vamos a utilizar posteriormente para invocar la llamada a la controladora y nos traiga la información deseada.

Luego tendríamos que tener algún componente html vacío para poner en él la vista que vamos a traer desde nuestra controladora, sería algo como:

<div id="dialog_mi_popup" style="display: none" title="Nueva Ventana"></div>

En la controladora tendríamos la función en la que llamamos la vista, con la característica que hacemos un echo a la función $this->load->view('mi_ventana', '', true):

public function mostrar_ventana()
{
echo $this->load->view('mi_ventana', '', true);
}

En esta función, para este ejemplo tan sencillo no estamos trayendo a la vista datos desde la controladora en el segundo parámetro de la función, y definimos finalmente el último parámetro en true para traer los datos como una cadena, incluso después podemos hacer algún procesamiento con estos datos antes de mostrarlos.

En el código script, básicamente debemos realizar dos cosas, una: definir las propiedades del Popup que vamos a mostrar, que si nos fijamos es el componente html vacío que definimos anteriormente, y otra en el evento clic del link definido hacer la llamada controladora/función que hemos definido y finalmente con esta información mostrar el Popup.

$(document).ready(function()
{
//definiendo las propiedades del popup
$("#dialog_mi_popup").dialog({
autoOpen: false,
height: 550,
width: 650,
modal: true
});

//mostrando el popup en el evento click del link
$(document).on('click', '.mi_popup', function(ev)
{
ev.preventDefault();
$.post('<?php echo site_url().'controladora/mostrar_ventana/'; ?>',
function(data){

$("#dialog_mi_popup").html(data);

$("#dialog_mi_popup").dialog( "open" );
});

});
}

A la función que estamos llamando se le pueden pasar valores, muy útil para cuando la vista que deseamos mostrar en la nueva ventana depende de valores seleccionados en la vista general, como por ejemplo cuando seleccionamos un elemento de un grid y veremos más detalles del elemento en la ventana Popup.

$.post('<?php echo site_url().'controladora/mostrar_ventana/'; ?>', {valor:valor_seleccionado},

Donde por ejemplo valor_seleccionado se alimenta de algún id que estamos guardando en algún componente visual que tenemos oculto…

var valor_seleccionado = $('#id').val();

Tenemos que tener en cuenta entonces que esos valores tienen que ser recibidos en la función de la controladora que estamos llamando de la siguiente forma:

$id = $this->input->post('valor');

Con estos sencillos pasos tendremos nuestros Popup funcionando, hay otros elementos que tenemos que tener en cuenta, como por ejemplo si estamos mostrando un formulario en la ventana Popup y realizando las validaciones en el servidor, se “perdería” la ventana que estamos mostrando al hacer el envío del formulario cuando este falla, ese efecto podríamos evitarlo haciendo las validaciones de nuestro formulario desde el código script. Lo otro que tendríamos que tener en cuenta es que si estamos abriendo y cerrando continuamente varios Popup desde la misma ventana principal, tenemos todo un mismo código html y puede dar conflictos si tenemos variables con el mismo nombre en las diferentes vistas que estamos cargando.

Es todo, espero haya sido de utilidad.

{ Leer Más }


IconIconIcon