Cinco programas para la creación de aventuras gráficas.

Sin dejar el tema de la programación, pero acerándonos a un terreno más lúdico hoy hablaremos de programas para la creación de aventuras gráficas. Si como yo eras de los que flipaban con Monkey Island, Day of the Tentacle, Maniac Mansion, Full Throttle… y tienes alguna noción de programación podrás, con este software, dar forma a tu aventura gráfica deseada. Eso sí, necesitarás también a alguien con nociones de diseño gráfico para que te haga los fondos, personajes y demás diseños.

WinterMute Engine: Se trata de un motor muy potente para crear aventuras gráficas. Es un proyecto GNU que os permitirá crear tanto aventuras comerciales como gratuítas, que permite el uso de gráficos 3D, alta definición, gran cantidad de recursos multimedia y un scripting con una sintaxis similar a PHP, por lo que si tienes nociones de este lenguaje o de C++ no te costará mucho trabajar con él.

En su página oficial podrás descargar el programa y encontrar ejemplos, ayuda, hacer donaciones…

Open SLUDGE: Basado en SLUDGE, de HungrySoftware, se trata de una alternativa abierta muy simple e intuitivo. Existe para Windows, Linux y MacOS. Gráficamente no es tan potente como WinterMute, pero tiene una gran cantidad de características que implementar. En su página de sourceforge podéis encontrar todas sus características, juegos creados con este software y el programa en si.

Javascript Graphic Adventure Maker: Bueno, el nombre ya dice bastante. Se trata de un programa que nos permitirá crear aventuras gráficas en javascript. JSGAM se trata de un proyecto libre y proporciona la ventaja de que el juega pueda ser incrustado en una página y jugado desde un navegador. De nuevo en sourceforge podéis encontrar la página del proyecto con el programa para descargar. También podéis jugar a este juego de ejemplo

DAGE: Un editor de aventuras complejo y muy potente, orientado sobre todo a la realización de aventuras con gráficos en 3D. Existen versiones para Windows y Linux y soporta OpenGL, el motor de física open source Newton Game Dynamic y usa scripting Lua. En su portal podrás no sólo descargar el editor, sino también varias aventuras subidas por otros creadores.

ALPACA: Finalmente un editor para diseñadores en Flash. Dudé si incluirlo o no, ya que todos sabéis que no soy muy partidario de esta tecnología, pero la gran cantidad de desarrolladores flash que hay por el mundo supongo que hará de ALPACA una opción interesante para ellos. Su nombre es un acrónimo de ActionScript LDU Point-And-Click Adventure. Al igual que JSGAM nos permite hacer juegos ejecutables en un navegador. En la página del proyecto tenéis juegos de ejemplo, documentación y el propio editor.

Estos cinco ejemplos no son los únicos. Tenéis también Adventure Game Studio, potente, fácile de usar pero privativo. Y si sois fans de los juegos old school podéis encontrar SCIStudio, basado en el mítico motor de Sierra (Larry2, Kings Quest IV); o NAGI, basado en el motor AGI que usaban, por ejemplo, los tres primeros King’s Quest o Larry I, y además permite hacer juegos compatibles con el motor SCUMM o con Sarien (que pemite modo multijudaor on-line).

En fin, con todo este montón malo será que no encontréis una opción que os convenza. Ahora sólo necesitáis tener una buena idea y trabajarla bien…

100 años de Stoker

El 20 de abril de 1912, en St George’s Square, Londres, agonizaba consumido por la sífilis uno de los grandes autores del romanticismo en lengua inglesa. Dice la leyenda que entre delirios musitaba «strigoi» (vampiro en rumano) mientras señalaba a una esquina de la habitación. Nunca sabremos si sólo es un cuento chino para mitificarle más o si fue fruto de su obesisión por los mitos sobre el vampirismo. En cualquier caso, hoy se cumplen 100 años de la muerte de Bram Stoker, y como desde que leí Drácula con 12 años ha sido una de mis novelas favoritas no podía dejarle sin un pequeño homenaje.

Aunque publicó su primer libro a los 27 años siempre vivió, de una forma u otra, de la literatura. Comenzó siendo crítico de teatro y tras eso director del teatro Lyceum de Londres, actividades que compaginó con su carrera como escritor. Estuvo siempre metido en el meollo cultural, pero también era un hombre de ciencia, habiéndose graduado con honores en matemáticas. Pero fue a los 40 años cuando la publicación de su obra más famosa, Drácula, le llevaría al Olimpo de las letras.

Como, gracias a la providencia, los derechos de autor todavía no son de por vida podéis disfrutar de gran parte de su obra en este enlace y en este. Para la industria del entretenimiento será un crimen que podamos leerlo sin que el tátarasobrinonieto de Stoker cobre pos los derechos de autor, así que aprovechemos antes de que ganen alguna votación en el parlamento yankee y nos impongan su ley a nivel mundial.

Por mi parte, tomaré una copa de buen whisky irlandés a la salud del centenario difunto.

Procedimiento que hace una select desde un XML en SQL-Server

Bueno, estoy realizando un cursillo de SQL-Server2008 R2 cortesía de la Xunta y la UE (hay que aprovechar, que a ver lo que dura la formación gratis en este país). Así que vamos con pequeño ejemplo: un procedmiento que realiza un select sobre un fichero xml, que recibe como parámetro.

Primero vamos a definir una variable como xml (podríamos también importarlo usando un bulk import, pero así veis más clara):

declare @EjemploXML as xml

set @EjemploXML=
'<?xml version="1.0"?>
<SalespersonMods>
    <SalespersonMod SalespersonID="274">
        <Mods>
            <Mod SalesTerritoryID="3"/>
        </Mods>
    </SalespersonMod>
    <SalespersonMod SalespersonID="278">
        <Mods>
            <Mod SalesTerritoryID="4"/>
        </Mods>	
    </SalespersonMod>
<SalespersonMods>'

En fin, ahí tenéis el xml que vamos a recorrer. Como véis la «chicha» está en los atributos SalespersonID y SalesTerritoryID, que son los datos que queremos sacar en la consulta. Ahora os dejo el código y debajo explico todo el procedimiento:


create procedure selectFromXML
@SalesPersonMods xml
as
begin
  declare @XMLdoc int
  exec sp_xml_preparedocument @XMLdoc output, @SalesPersonMods
  select * from
  openxml(@XMLdoc, '/SalespersonMods/SalespersonMod/Mods/Mod')
  with
  (
	SalesTerritoryID int '@SalesTerritoryID',
	SalespersonId int '../../@SalespersonID'
  )

  exec sp_xml_removedocument @XMLdoc
end

En fin, y explicado rápido: Lo primero es crear el procedimiento con create procedure seguido del nombre que queremos darle, y especificando que recibirá como parámetro @SalesPersonMods, que será un xml. Tras eso declaramos un variable entera (la he llamado @XMLdoc) que almacenará un manejador. Para crear dicho manejador usamos el procedimiento almacenado de sistema sp_xml_preparedocument, que recibe como parámetros la variable entera @XMLdoc (definido como output) y la variable xml @SalesPersonMods. Ya tenemos el manejador listo. Ahora queda hacer la select, que empieza como cualquier select normal: select ‘loquesea’ from (en este caso *, o sea, todo). Y en este caso en vez del nombre de tabla irá la función openxml, que recibirá como parámetros el manejador que creamos antes (@XMLdoc) y una cadena de texto con el elemento del xml en el que queremos posicionarnos.

Movernos por el xml es como movernos por MS-DOS, usamos la jerarquía de etiquetas separadas por barras (/) como si fuera una jerarquía de directorios, usando el punto (.) para referirnos a elementos que parten del mismo nivel jerárquico y el doble punto (..) para navegar hacia atrás en la jerarquía. En este caso queremos acceder al atributo SalesTerritoryID, que es un atributo de /Mod (donde nos hemos situado), por lo que no hay que navegar, accedemos a él simplemente con @SalesTerritoryID (a los atributos nos referimos siempre precediéndolos de una arroba, si fuera texto en la etiqueta lo haríamos sin ella) dándole como nombre de columna SalesTerritoryID (definida como entero, en este caso, por ser el valor más adecuado). SalespersonID en cambio está dos niveles más arriba, así que llegamos a él indicándolo con el doble punto: «../../SalespersonID».

Finalmente, tras todas las operaciones, quitamos el manejador de la memoria para liberarla. Si quieres probar la funcionalidad de esto te basta con copiar y todo el código en el QueryManager de SQL-Server. Finalmente ejecuta el procedimiento pasándole como parámetro la variable sql que definimos arriba y comprueba el resultado.

Un añito

Bueno, una entrada rápida, que estas semanas estoy ocupado y ha caído mi ritmo de publicación. Pero hoy tenía que escribir, estaba obligado. ¿Por qué? Porque hace un año que empecé con este WP. Con un mero «hola mundo» y la pretensión de hacer un blog sobre rock and roll. El por qué progresivamente se ha llenado de entras sobre informática supongo que tiene que ver con los meses de desempleo. Al final hay que dar salida al conocimiento por algún lado. Al final rock and roll, baloncesto, política, informática (tando sistemas como redes o desarrollo), cocktelería y paranoias varias. Al menos no se ha convertido en un blog de cocina (y me ha sobrevolado la cabeza subir recetas pero… tal vez en este segundo año).

Lo que desde luego nunca esperé es tener esta cantidad de visitas. De las primeras semanas, donde había días de 0 visitantes y donde 15 personas en un día eran un buen dato, a algunos miles de visitas mensuales la cosa se ha disparado en un año. De que sólo entrasen a consultar gente de mi entorno a través de facebook a recibir visitas de todos los países hispanohablantes.

En fin, primer añito de donnierock, con 171 entradas (esta hace la 172), algunas más exitosas que otras. Y con muchas visitas de varias partes del planeta. Un saludo a todos, gracias por leerme y espero poder seguir aportando cosas interesantes.

Selección FIBA: Podría ganar a los USA

Desde hace años existe el debate de si una selección FIBA podría derrotar a una selección USA que llevara a sus mejores jugadores. Las derrotas de USA en 2002, 2004 y 2006 dejaron claro que ya no eran invencibles y que si quieren ganar un Mundial u Olimpiada tienen que llevar a sus mejores hombres. En 2008 lo hicieron, se llevaron a sus mejores hombres y necesitaron una ayudita arbitral para llevarse el oro frente a España en una final que será recordada como «la mejor de la historia». En 2010 se llevaron el mundial sin problemas con un equipo formado muy inteligentemente, sin los típicos «megaestrellas» pero con una plantilla sólida de jugadores prometedores (Kevin Durant, Kevin Love, Derrick Rose, Rusell Westbrook, Stephen Curry… hace dos años eran promesas, ahora son all stars)

Los tiempos en los que los colaboradores de la revista NBA decían aquello de que «algún día una selección FIBA puede que logre acercarse en el marcador a una selección USA, les darán un susto y entrarán en la historia por casi ganar, pero al victoria es imposible». Es más recuerdo que en aquel artículo el autor, indulgentemente, afirmaba que Kobe Bryant tendría que jugar con el equipo FIBA para que estos no fueran humillados. De esto hará 10 u once años ¿Alguien seguirá pensando así?

Pero entonces ¿se puede derrotar a una USA Team con sus mejores jugadores?. Bueno, empecemos planteando el escenario. Eliminatoria al mejor de 5 partidos con reglas FIBA. El equipo FIBA necesitaría un buen entrenador, ya que la clave para ganar es jugar a la europea: duro, serio, intensos desde el primer minuto y con cabeza en ataque. Sin lugar a dudas el entrenador tendría que ser «Mr Euroliga», el hombre que más veces ha ganado ese título (más que cualquier club incluso): Zeljko Obradovic. También había barajado a Aíto García Reneses y Boza Maljkovic, pero finalmente los títulos pesan en mi decisión.

Contando con un director así desde el banquillo, hará falta otro de nivel en la cancha. Apostaría por llevar tres bases y, para tener un detalle con los yankees, hasta voy a prescindir de Tony Parker por sus orígenes estadounidenses. También dejaré fuera a Theo Papaloukas y Steve Nash, los cuales ya empiezan a acusar el paso de los años… (bueno, Nash hostias, que está liderando la NBA en asistencias con 39 años). Yo contaría para este puesto con Dimitris Diamantidis, el «guante» que durante años ha dirigido a la selección griega y al Panathinaikos, que además puede ocupar los puestos de escolta y alero de ser necesario. Junto a él un base más puro como Jose Calderón, con dilatada experiencia FIBA y NBA (donde logró el record de mejor porcentaje de tiros libres en una temporada y donde ha estado entre los 5 mejores asistentes varios años). Y terminando el capítulo de bases Milos Teodosic, un base alocado capaz de romper cualquier partido con su velocidad y creatividad. Dejo fuera a Ricky Rubio por tener un estilo muy similar al de Teodosic, aunque podría estar perfectamente en ese puesto, he elegido a Teodosic porque tiene mejor tiro y complementa mejor a los dos bases.

Pensar en dos escoltas se torna complejo, aunque mi primero opción sería el veterano Manu Ginobili, el argentino que fue capaz de poner de acuerdo a Bilardo y Menotti con su calidad. Junto al porteño, el esloveno Goran Dragic. Aunque en la NBA le pongan de base por su físico (bajito y sin músculo) en Europa sería un claro escolta, veloz, con buen tiro y gran pase (aprendido al lado de Steve Nash, no se puede tener mejor maestro). Tras tres años de papeles secundarios este año al fin ha sido el protagonista gracias a la lesión de Lowry, que le ha dado los minutos y balones necesarios para mostrar su potencial, siendo jugador de la semana en el Oeste a principios de abril.

El puesto de alero iría sobrado de centímetros: por un lado los del espigado ruso Andrei Kirilenko, el hombre para todo, seguramente uno de los jugadores más completos que hayan salido de Europa, capaz de aportar tiro, rebote, visión de juego, defensa, veteranía… Y su falta de músculo la compensaría el sudanés nacionalizado inglés Luol Deng, el all-star de los Bulls es toda una garantía a la hora de aportar defensa y rebote, y con una buena disposición a la hora de penetrar hacia la canasta.

El juego interior empezaría con tres «cuatros», la posición en la que hay más donde elegir. Y es que hay talento para dar y tomar, empezando por el germano Dirk Nowitzki, el primer europeo que ha sido MVP de la liga regular, también MVP de las finales de 2011, 11 veces all-star y 19º anotador histórico de la NBA a día de hoy. Como el debate desde hace tiempo es si el mejor cuatro europeo es Nowitzki o Pau Gasol, claro está quién será el otro cuatro. Los números de Pau y su palmarés sin duda le hacen una leyenda del balonceto por méritos propios, al mejor jugador español de la historia sólo se le han escapado dos títulos por el momento: el oro olímpico y la Euroliga, el resto se lo ha llevado todo. Y como último cuatro, el argentino Luis Scola, otro palmarés impresionante para un jugador con unos fundamentos, agresividad y muñeca impecables.

Finalmente dos «cincos» completarían el equipo. Es el puesto que más dudas me plantea, porque tengo tres favoritos y al menos uno se tendrá que quedar fuera. Me mojaré y diré que Marc Gasol tendría que ser uno de los seleccionados. Tiene tiro, tiene fuerza, tiene juego de pies y no se esconde en los momentos grandes, como demostró en la final del mundial 2006 o en los PO de la NBA 2011. Y el otro puesto ya se me pone más complicado, aunque yo diría Thiago Splitter. No acaba de encontrar minutos en unos Spurs con una rotación muy larga, pero su agilidad y sus movimientos en el poste son una delicia que disfrutamos durante años en la ACB y que disfrutaría la NBA si le dieran más minutos y balones. Se queda fuera, por muy poco (podría estar perfectamente la lista) Nikola Pekovic, el pivot montenegrino que por fin ha conseguido que los T-Wolves le den minutos, demostrando por fin su calidad en la NBA tras una primera temporada gris.

Diamantidis, Calderón, Teodosic, Ginobili, Dragic, Kirilenko, Luol Deng, Nowitzki, Pau Gasol, Scola, Marc Gasol y Splitter. Nombre por nombre parece que no podrían competir contra una selección de los mejores jugadores USA pero no olvidemos que un partido lo gana un equipo, no cinco individuos.

Creando un menú con HTML5 y CSS3

Volviendo con los artículos sobre HTML5 hoy vamos a ver cómo hacer un menú horizontal básico utilizando html5 y CSS3 (sobre todo CSS3).

En fin, en el marcado poca chicha hay. Es decir, lista desordenada de toda la vida, y el único cambio es que usaremos la etiqueta nav:

<nav>
  <ul>
<ul>
	<li><a class="hiddenSpellError">title="Primero" href="#">First</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Segundo" href="#">Second</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Tercero" href="#">Third</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Cuarto" href="#">Fourth</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Quinto" href="#">Fifth</a></li>
</ul>
  </ul>
<!--<span class="hiddenSpellError" pre=""-->nav>

Con esto la parte HTML5 ya está liquidada. Ahora toca empezar a trastear con CSS3. Lo primero es el css de la sección NAV, donde pondremos bordes redondeados, degradado de blanco a gris y definiremos el tamaño. Luego a los elementos de lista les quitaremos el botón de lista y los flotaremos a la izquierda(como en cualquier menú horizontal tradicional). También añadiremos una transición a cada enlace. Como CSS3 todavía no está estandarizado hay que usar propiedades espcíficas para cada navegador. En el futuro debería funcionar en todos con la propiedad estandar.

nav{
    /*Borde redondeado*/
    -webkit-border-radius:9px;/*Chrome y Safari*/
    -moz-border-radius:9px;/*Firefox*/
    -o-border-radius:9px;/*Opera*/
    border-radius:9px;/*Estandar*/
    /*Color degradado*/
    background-image: -webkit-gradient(linear, left top, left bottom, from(#FFF), to(#BBB));/*Chrome y Safari*/
    background-image: -moz-linear-gradient(top center, #FFF, #BBB);/*Firefox*/
    background-image: -o-linear-gradient(top, #FFF, #BBB);/*Opera*/
    background-image: linear-gradient(top, #FFF, #BBB);/*Estandar*/
    overflow:hidden;
    padding:12px;
    width:890px;
}

nav ul{
    list-style:none;
    margin:0 10px 0 10px;
    padding:0;
}

nav ul li{
    /*Borde redondeado*/
    -webkit-border-radius:6px;/*Chrome y Safari*/
    -moz-border-radius:6px;/*Firefox*/
    -o-border-radius:6px;/*Opera*/
    border-radius:6px;/*Estandar*/
    float:left;
    font-size:16px;
    font-weight:bold;
    margin-right:11px;
    text-align:center;
    /*Sombras*/
    text-shadow: 0px 1px 0px #FFF;
}

nav ul li a{
    color:#AAA;
    display:block;
    padding:10px;
    text-decoration:none;
    /*Transiciones*/
    -webkit-transition: 0.3s linear all;
    -moz-transition: 0.3s linear all;
    -o-transition: 0.3s linear all;
    transition: 0.3s linear all;
}

Bueno, tenemos el color de fondo, tenemos los bordes, tenemos la lista en formato horizontal… ¿Qué nos falta? Pues nos falta definir qué ocurre cuando naveguemos sobre los enlaces, cuando pongamos el ratón encima. Para eso utilizamos la pseudo-clase :hover de toda la vida, pero en este caso con degradados y sombras. Además, el texto se oscurecerá.

nav ul li:hover{
    /*Color degradado*/
    background-image: -webkit-gradient(linear, left top, left bottom, from(#FFF), to( #E3E3E3));/*Chrome y Safari*/
    background-image: -moz-linear-gradient(top center, #FFF, #E3E3E3);/*Firefox*/
    background-image: -o-linear-gradient(top, #FFF, #E3E3E3);/*Opera*/
    background-image: linear-gradient(top, #FFF, #E3E3E3);/*Estandar*/
    /*Sombras*/
    -webkit-box-shadow:  1px -1px 0px #999;/*Chrome y Safari*/
    -moz-box-shadow:  1px -1px 0px #999;/*Firefox*/
    -o-box-shadow:  1px -1px 0px #999;/*Opera*/
    box-shadow:  1px -1px 0px #999;/*Estandar*/
    border:1px solid #E3E3E3;
}

nav ul li a:hover {
    color:#000;
}

Y ahí tenéis un menú con estilo css3 bien chulo, recordad si lo testeáis que en los navegadores antiguos no va a funcionar, así que si tenéis IE6 o 7… instalad un navegador actualizado, que son gratis, joder.

Cambiando el escritorio de Ubuntu, de Unity a GNOME

Bueno, por no aburriros con la programación web, y a pesar de que Ubunto 12.04 está al caer, vamos con una nueva entrada: Cambiar el escritorio Unity por GNOME.

Y para quedar de guays lo vamos a hacer por línea de comandos (tampoco tengo muy claro si se puede hacer de otra forma, pero…). Así que abre tu terminal y empieza:

sudo apt-get update
sudo apt-get install gnome-panel gnome-session-fallback
sudo apt-get install gnome-shell

Ale, ya está. Escritorio y shell instalado. Ahora basta con reiniciar y elegir en LightDM el escritorio GNOME. Pero ¿cómo hacer GNOME el escritorio por defecto? Vuelta al terminal y:

sudo /usr/lib/lightdm/lightdm-set-defaults -s gnome-shell
sudo /usr/lib/lightdm/lightdm-set-defaults -s gnome-fallback

Y ale, ¡ya está! Listo y finiquitado el cambio.

Detectando navegadores de móviles (PHP y Javascript)

Es habitual en los tiempos que correr desarrollar una página web para navegadores de escritorio y otras optimizadas para el uso en navegadores móviles (smartphone, tablet). Una maquetación puede parecer cojonuda para una pantalla grande, de un sobremesa, pero ser incómoda en una pantalla de cuatro pulgadas.

En ese caso tenéis dos posibilidades: detectar el dispositivo móvil en el servidor (PHP) o en el cliente (javascript). El ejemplo para PHP sería el siguiente:

<?php
$mobile_browser = ’0';

//$_SERVER['HTTP_USER_AGENT'] -> el agente de usuario que está accediendo a la página.
//preg_match -> Realizar una comparación de expresión regular
if(preg_match(‘/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone)/i’,strtolower($_SERVER['HTTP_USER_AGENT']))){
	$mobile_browser++;
}

//$_SERVER['HTTP_ACCEPT'] -> Indica los tipos MIME que el cliente puede recibir.
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),’application/vnd.wap.xhtml+xml’)>0) or
((isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE'])))){

	$mobile_browser++;
}

$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents = array(
‘w3c ‘,’acs-’,'alav’,'alca’,'amoi’,'audi’,'avan’,'benq’,'bird’,'blac’,
‘blaz’,'brew’,'cell’,'cldc’,'cmd-’,'dang’,'doco’,'eric’,'hipt’,'inno’,
‘ipaq’,'java’,'jigs’,'kddi’,'keji’,'leno’,'lg-c’,'lg-d’,'lg-g’,'lge-’,
‘maui’,'maxo’,'midp’,'mits’,'mmef’,'mobi’,'mot-’,'moto’,'mwbp’,'nec-’,
‘newt’,'noki’,'oper’,'palm’,'pana’,'pant’,'phil’,'play’,'port’,'prox’,
‘qwap’,'sage’,'sams’,'sany’,'sch-’,'sec-’,'send’,'seri’,'sgh-’,'shar’,
‘sie-’,'siem’,'smal’,'smar’,'sony’,'sph-’,'symb’,'t-mo’,'teli’,'tim-’,
‘tosh’,'tsm-’,'upg1',’upsi’,'vk-v’,'voda’,'wap-’,'wapa’,'wapi’,'wapp’,
‘wapr’,'webc’,'winw’,'winw’,'xda’,'xda-’);
//buscar agentes en el array de agentes
if(in_array($mobile_ua,$mobile_agents)){
	$mobile_browser++;
}

//$_SERVER['ALL_HTTP'] -> Todas las cabeceras HTTP
//strpos -> Primera aparición de una cadena dentro de otra

if(strpos(strtolower($_SERVER['ALL_HTTP']),’OperaMini’)>0) {
	$mobile_browser++;
}

if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),’windows’)>0) {
	$mobile_browser=0;
}

if($mobile_browser>0){
//Aquí redireccionamos hacia la aplicación móvil
}else{
//Aquí nos vamos a la versión para escritorio
}
?>

Se trata de una vieja función que econtré hace tiempo y detecta todo tipo de navegadores. La utilicé en mi proyecto de fin de curso y funcionaba. Utiliza un array con referencias a muchos navegadores de dispositivos móviles. La función de javascript por su parte es más sencillita y detectará el SO:

 var ua = navigator.userAgent.toLowerCase();
 var isAndroid = ua.indexOf("android") > -1; // && ua.indexOf("mobile");
 var isiPhone = ua.indexOf("iphone") > -1;
 var isiPod = ua.indexOf("ipod") > -1;
 var isiPad = ua.indexOf("ipad") > -1;
 if(!isiPad) isiPad = /iPad/i.test(ua) || /iPhone OS 3_1_2/i.test(ua) || /iPhone OS 3_2_2/i.test(ua);
 var isWPx = ua.indexOf("windows phone") > -1;

En este caso detecta si se trata de Android, un dispositivo Apple o WindowsPhone.

En último caso, en el siguiente enlace tenéis ejemplos de código actualizados para varios lenguajes. Os puede servir de mucha ayuda.

Estructura en HTML5

Si eres un programador web de la old school seguramente recuerdes la época en que las tablas eran el elemento más utilizado para estructurar tu web. La generalización del uso de cajas (div) acabó con esta forma de maquetar, siendo a día de hoy la fórmula predominante. Esto provoca el uso indiscriminado de elementos div por todo el documento, que nos vemos obligados a ir posicionando con CSS (a veces rompiéndonos mucho los huevos para conseguir la compatibilidad en todos los navegadores) a base de definirlos a base de id y clases. Los nuevos elementos que incorpora HTML5 para la estructura son los siguientes, y nos permitirán un código mucho más limpio:

  • header: El elemento header es el encabezado de la página web, formado por una serie de elementos introductorios o de navegación.
  • footer: Este elemento es el pié de la página o la sección, donde suele insertarse información sobre la licencia, el autor, fecha de creación, empresa relacionada…
  • nav: Se usa para insertar un menú de navegación en la página, formado por enlaces. No todos los grupos de enlaces de la página tienen que estar dentro de una sección nav, sólo los principales, como el menú de navegación bajo el encabezado o un menú en el pie.
  • section: Define una sección general en un documento o aplicación, como si fuera una especie de «capítulo». Puede contener subsecciones y si se utilizan con elementos h1-h6 se pueden crear jerarquías, muy útiles para una buena estructuración de la web.
  • article: Un elemento article es seguramente lo más complicado de explicar. Es un elemento, una seccion reutilizable de la página web para mostrar un determinado contenido, como un post en un foro, un artículo en un periódico, un widget interactivo… Los elementos article pueden anidarse, siendo el artículo anidado parte del principal, como los comentarios a una publicación en un blog.
  • aside: Es una sección de la página que abarca un contenido relacionado con el contenido que lo rodea, perp que se puede considerar un contenido independiente. Puede utilizarse para barras laterales, elementos publicitarios, grupos de elementos de la navegación…

Ahora un ejemplillo de código bien tochaco con una página html. Desde la declaración hasta el último pie:

html>
lang="es">
<head>
  charset="utf-8" />
  IE=edge,chrome=1" />
  <title>prueba</title>
  name="description" content="EjemploHTML5" />
  name="author" content="DonnieRock" />
  name="viewport" content="width=device-width; initial-scale=1.0" />
</head>

<body>
  <div>
    <header>
      <h1>prueba</h1>
    </header>
    <nav></pre>
<a class="hiddenSpellError">href="/">Home</a>
<pre></pre>
<a class="hiddenSpellError">href="/contact">Contact</a>
<pre>
    </nav>

    <div>
      <article>
      	<h2>Artículo1</h2>
<section>El artículo1: Ninguna banda finlandesa llegará nunca aser como Black Sabbath</section>
      	<h2>Artículo34</h2>
      	<section>El artículo34: Hago lo que quiero, donde quiero y cuando quiero</section>
      	<article>
      		<h3>Subartículo</h3>
<section>Kobe Bryant nunca será Michael Jordan</section>
      	</article>
      </article>
      <aside>Esto, para el lado</aside>
    </div>

    <footer></pre>
© Copylefted by Old Dog Donnie Rock
<pre>
    </footer>
  </div>
</body>
</html>

En fin, espero que estoy os sea de ayuda empezando con HTML5.

El API de geolocalización en HTML5

Aunque la geolocalización no forme parte de la especificación original de HTML5 (al menos según dice el manual de Remy Sharp, que es el que en un primer momento fue manual de referencia), su funcionalidad es una de las más atractivas e interesantes de dicho lenguaje, sobre todo en un contexto de web cada vez más orientada a dispositivos móviles (tablet, smartphone).

En fin, el API de geolocalización de HMTL5 permite que el navegador acceda a los datos de la posición del dispositivo desde el que se está accediendo a la web, ya sea por triangulación usando el GPS, o el GSM del teléfono; o a través de la posición de tu dirección IP.

El API posee tres métodos básicos:

  • getCurrentPosition(): Recoge la posición del dispositivo una vez.
  • watchPosition(): Recupera y actualiza la posición conforme va cambiando.
  • clearWatch(): Detiene la actualización de la posición.

En caso de éxito, getCurrentPosition() y watchPosition() devuelven un objeto Position, formado a su vez por un objeto coords (con todas las coordenadas) y un timestamp. El objeto coords tiene varias propiedades, algunas reconocidas por todos los navegadores y otras no:

  • latitude: un número flotante de sólo lectura que indica la latitud.
  • longitude: un número flotante de sólo lectura que indica la longitud.
  • accuracy: un número flotante de sólo lectura que indica la precisión de la longitud y la latitud en metros.
  • altitude: un número flotante de sólo lectura que indica la altura. No todos los dispositivos los permiten, en esos casos viene a nulo
  • altitudeAccuracy: un número flotante de sólo lectura que indica la precisión de la altura en metros. No todos los dispositivos los permiten, en esos casos viene a nulo
  • heading: un número flotante de sólo lectura que indica la dirección y el recorrido, expresada en grados. No todos los dispositivos los permiten, en esos casos viene a nulo
  • speed: un número flotante de sólo lectura que indica la velocidad de desplazamiento, expresada en metros por segundo. No todos los dispositivos los permiten, en esos casos viene a nulo

Ahora que te has leído la teoría, lo mejor es un ejemplo práctico, similar al que aparece en el manual de Lawson y Sharp (Introducing HTML5):

if(navigator.geolocation){
    navigator.geolocation.getCurrentPosition(function (position{
        var coordenadas = position.coords;
        showMap(coordenadas.latitude, coordenadas.longitude, coordenadas.accuracy);
    });
}else{
    window.alert("El navegador no soporta el API de geolocalización");
}

Plantéate que sería un código que llame a una función que genere un mapa recibiendo las coordenadas (como las API de GoogleMaps o OpenStreetMap). Primero comprueba que el navegador soporte el API, luego almacena las coordenadas conseguidas con getCurrentPosition en una variable objeto y finalmente las envía a la función que genera el mapa.

En fin, un API con muchas posibilidades en las nuevas aplicaciones web para dispositivos móviles.