VISITAS:

viernes, 6 de septiembre de 2013

Solaris packages

¿Qué son packages Solaris?

Conceptos y definiciones previas:
  • En Solaris, el software de aplicación se entrega en forma de packages.
  • Un package es una colección de ficheros y directorios.
  • El package lo construye el desarrollador del software.
  • Un producto software se distribuye en uno o más packages.
  • Los packages software los instala el administrador de la máquina.

Componentes de un paquete

Un paquete se compone de: 
  • Package objects: son los ficheros que componen la aplicación
  • Control files: controlan dónde, cómo y si el paquete se instala. Se clasifican en:
    • information files
    • installation scripts
Para empaquetar una aplicación se tienen que seguir los siguientes pasos:
  1. crear los ficheros necesarios: package objects (ficheros y directorios de la aplicación), ficheros prototype y pkginfo (obligatorios), otros ficheros opcionales, scripts de instalación (opcionales)
  2. construir el paquete con el comando pkgmk
El fichero pkginfo es un fichero obligatorio que define los parámetros del package: abreviatura del package, nombre completo, arquitectura, etc.
El fichero prototype es un fichero obligatorio que lista los componentes del package. Hay una entrada por cada package object, information file e installation script. Cada entrada consta de varios campos que describen el componente: localización, atributos y tipo de fichero.
El fichero compver es un fichero opcional que define versiones previas del package que son compatibles con la versión de este package.
El fichero depend es un fichero opcional que indica otros packages necesarios para instalar este package.
El fichero space define los requerimientos de espacio en disco para el package, además de los necesarios por los package objects.
El fichero copyright es un fichero opcional que define un mensaje de copyright que saldrá cuando se instale el package.
Los installation scripts no son obligatorios. Sirven para ejecutar acciones durante la instalación del package. Tienen las siguientes características:

  • Se componen de comandos bourne shell.
  • Los permisos del script deben ser 0644
  • El script no necesita el identificador de shell #!/bin/sh

Tipos de script de instalación:

  • request: pide información al usuario que está instalando el package
  • checkinstall: realiza verificaciones
  • procedure scripts: definen acciones que ocurren en puntos particulares de la instalación y desinstalación (preinstall, postinstall, preremove, postremove)
  • class action scripts: definen acciones a realizar sobre un grupo de objetos

Consideraciones antes de construir un package

Antes de construir un package hay que decidir si el producto consta de uno o de más packages. Cuando se decide hacer múltiples packages, hay que pensar en cómo segmentar la aplicación.
Consideraciones a tener en cuenta para decidir cómo segmentar la aplicación en packages:
  • todos los packages deben ser instalables remotamente
  • los packages deben instalarse en un file system concreto (/. /usr, etc) para soportar todas las configuraciones posibles de servidor.
  • los packages deben tener una funcionalidad claramente definida
  • los packages que requieran licencia deben ir separados
  • hay que evitar duplicidades y solapes en los ficheros/directorios de cada package

Comandos para construir packages

Crear un fichero prototipo que sirva de entrada a pkgmk: pkgproto
Crear un package instalable: pkgmk
Instalar un package: pkgadd
Almacenar respuestas a un request script: pkgask
Copiar packages en  un medio: pkgtrans
Desinstalar un package: pkgrm
Verificar la integridad de un package: pkgchk
Mostrar información sobre un package instalado: pkginfo
Mostrar los parámetros de un package instalado: pkgparam
Instalar un nuevo objeto en un package ya instalado: installf
Quitar un objeto de un package ya instalado: removef

Control Files

Package information files:
  • admin: administrative defaults file
  • compver: compatibility file
  • copyright: conpyright information file
  • depend: dependencies file
  • pkginfo: characteristics file
  • pkgmap: contents description file
  • prototype: information file
  • space: disk space requirements file
Optional installation scripts:
  • request: solicita información al usuario
  • checkinstall: chequea los requisitos de la instalación
  • preinstall: ejecuta acciones previas a la instalación
  • postinstall: ejecuta acciones posteriores a la instalación
  • preremove: ejecuta acciones previas a la desinstalación
  • postremove: ejecuta acciones posteriores a la desinstalación
  • class action: ejecuta acciones sobre un grupo específico de objetos

Construcción de un package

El proceso de construcción de un package

Los pasos típicos para la construcción de un package son (cuando se tiene experiencia se puede cambiar este orden):

  • Crear un fichero pkginfo para describir las características del package
  • Organizar el contenido del package en una estructura de directorios
  • Opcionalmente, crear ficheros de información: dependencias, copyright, de espacio en disco, etc.
  • Opcionalmente, crear scripts de instalación para customizar los procesos de instalación y desinstalación
  • Crear un fichero prototype
  • Construir el package con el comando pkgmk
  • Verificar el package comprobando que se instala bien
  • Distribuir el package

Variables de entorno

Las variables de entorno se pueden utilizar dentro de los ficheros pkginfo, prototype y en los ficheros de información.
Hay dos tipos de variables:
  • Variables de construcción: empiezan con una letra minúscula y se evalúan en tiempo de construcción del package (pkgmk)
  • Variables de instalación: empiezan con una letra mayúscula y se evalúan en tiempo de instalación (pkgadd)
Reglas generales sobre las variables de entorno:

  • En el fichero pkginfo, las definiciones de variables son de la forma PARAM=value, con la primera letra en mayúscula. Estas variables se evalúan sólo en tiempo de instalación (pkgadd)
  • En el fichero prototype, las definiciones de variables son de la forma !PARAM=value o $VAR=value, la primera letra puede ser mayúscula o minúscula. Sólo se evalúan las variables conocidas en tiempo de construcción

Fichero pkginfo

El  fichero pkginfo es un fichero ASCII que describe las características de un package junto a información que ayuda a controlar el flujo de la instalación.
Cada entrada en pkginfo es una línea que establece el valor de un parámetro de la forma:
PARAM = value
donde PARAM es uno de los parámetros estándar. El valor se puede poner entre comillas (simples o dobles) en caso de que se usen caracteres especiales de la shell.
Se pueden crear parámetros de usuario, los cuales deben empezar por mayúscula, indicando así que el parámetro se evaluará en tiempo de instalación.
Los siguientes parámetros son obligatorios en pkginfo:

  • PKG
  • NAME
  • ARCH
  • VERSION
  • CATEGORY

Además, pkgmk añade automáticamente los siguientes parámetros:

  • PATH
  • PKGINST
  • INSTDATE
Un mismo package puede tener diferentes versiones o ser compatible con distintas arquitecturas. Todas las variantes de un package se denominan package instances (determinadas por PKG, ARCH y VERSION).
El programa pkgadd asigna un identificador de package a cada instancia que se instala. Este identificador consiste en un nombre abreviado más un sufijo numérico. El identificador distingue una instancia de un package unívocamente en una máquina.

La abreviatura del package se define en el parámetro PKG de pkginfo. PKG tiene las siguientes características:

  • empieza por una letra y puede contener letras y números
  • el tamaño máximo es 32
  • habitualmente, los primero cuatro caracteres identifican a la compañía

El parámetro ARCH identifica la o las arquitecturas asociadas al package: ARCK=sparc
El parámetro VERSION identifica la versión del package. VERSION=release 1.0
El parámetro NAME especifica un nombre largo para el package (máximo 256 caracteres)
El parámetro CATEGORY especifica la categoría a la que pertenece el package: application o system.

Organización del contenido del package

Los objetos (ficheros) del package se organizan en una estructura de directorios que debería ser igual a la estructura que tendrán estos objetos en el sistema instalado. Esto ahorrará mucho tiempo y esfuerzo.
En primer lugar se crea un directorio para los objetos que componen el package (se recomienda que el nombre de este directorio coincida con el nombre abreviado PKG).
Después se organizan los objetos en una estructura de directorios igual a la del package ya instalado.

Fichero prototype

El fichero prototype contiene información sobre los objetos (ficheros, directorios) que componen el package.
Cada entrada de este fichero define un único objeto del package. Estas entradas tienen varios campos de información separados por espacios (en un orden especificado). Las líneas que empiezan por # se consideran comentarios y se ignoran.
Hay dos formas de crear un fichero prototype:
  • desde cero con un editor de texto
  • ayudado con el comando pkgproto
Los normal es utilizar la segunda opción para crear el fichero la primera vez y después editarlo con un editor de texto.
El comando pkgproto explora una estructura de directorios y ficheros, y genera un fichero pkgproto que luego se puede editar.

Formato de las entradas del fichero prototype:

  • part: (opcional) numérico, permite agrupar objetos en partes (por defecto, part=1)
  • ftype: un carácter, especifica el tipo de objeto
    • f = fichero ejecutable o de datos
    • e=fichero que se guarda previamente si existe
    • v=fichero volátil (ej. log)
    • d=directorio
    • x=directorio de acceso exclusivo a este package
    • l=link
    • p=named pipe
    • c=dispositivo de caracteres
    • b=dispositivo de bloques
    • i=fichero de información o script de instalación
    • s=link simbólico
  • class: es la clase de instalación para el objeto. Si no se especifica, se asume none.
  • path: path absoluto o relativo donde se instalará el objeto. Si el path es relativo, se usa el parámetro BASEDIR definido en el fichero pkginfo.
  • major: (opcional, utilizado en dispositivos)
  • minor: (opcional, utilizado en dispositivos)
  • mode: modo octal del objeto, por ej 0644 (permisos).
  • owner: propietario del objeto
  • group: grupo del objeto
Para crear un fichero prototype desde cero con pkgproto, cambiar al directorio anterior a donde se ha metido el contenido del package y ejecutar el comando pkgproto:

$ pkgproto ./pkg > ./pkg/package/prototype

Esto creará un fichero prototype con entradas como éstas:.

d none pkg/src 0755 jane staff
f none pkg/src/file.java 0555 jane staff
etc

Este fichero es útil para empezar, pero normalmente hay que editarlo y modificar algunas cosas. Como mínimo, hay que cambiar los ficheros de información (ftype=i):

i pkginfo=pkg/package/pkginfo
Además de definir cada objeto, en el fichero prototype se pueden hacer otras cosas:

  • definir objetos adicionales que se crean en la instalación
  • crear links durante la instalación
  • distribuir packages en múltiples volúmenes
  • anidar ficheros prototype
  • poner un valor por defecto para mode, owner y group
  • dar un path de búsqueda para pkgmk (en la construcción del package)
  • poner variables de entorno
Para crear un directorio (que no va incluido en el package file):
d none /directory 0644 root other
Para crear un fichero vacío:
f none filename=/dev/null 0644 bin bin
Para crear un link:
s none etc/mount=../usr/etc/mount
Para dar valores por defecto:
!default 0644 root other













lunes, 3 de junio de 2013

Eclipse: Aplicación Web con Tomcat y Web Service

1. Integrar Tomcat en Eclipse

1.1 Pasos previos

Descargar eclipse de eclipse (vale cualquier versión de eclipse 3.4 ganymede o superior)
Descargar Tomcat 6.0.37 de tomcat 

Descomprimir apache-tomcat-6.9.37.zip en un directorio [tomcat_home]
Descomprimir eclipse-jee-juno-SR2-win32.zip en un directorio [eclipse_home]

1.2 Crear un runtime de tomcat en Eclipse

Arrancar Eclipse
Window > Preferences > Server > Runtime Environments
Add...
    Apache > Apache Tomcat v6.0
Next
    Name: [tomcat_runtime]
    Installation Directory: [tomcat_home]
    JRE: el JRE que nos interese para ejecutar tomcat
Finish

2. Aplicación Web en Eclipse

2.1 Crear la aplicación

File > New > Other > Web > Dynamic Web Project
    Name: [project_name]
    Location: [project_location]
    Target runtime: [tomcat_runtime]
    Dynamic web module version: 2.5
    Configuration: Default configuration for Apache Tomcat 6
Next
    [app_name]
Next
Finish
Package Explorer > WebContent > New > JSP File
    index.jsp
Introducir algún contenido a la página JSP, por ejemplo:
    <%= new Date().toString() %>

2.2 Crear un servidor

Pestaña Servers
New server wizard
Apache > Tomcat v6.0 server
Host name: localhost
Server name: [server_name]
Server runtime: [tomcat_runtime]
Next
    Añadir el proyecto
Finish
Botón derecho sobre el server > Start
URL: http://localhost:8080/[app_name]/index.jsp

2.3 Cambiar el puerto de tomcat

Doble click sobre el server en la pestaña Servers
Editar los puertos
Salvar

3. Web Service

3.1 Pasos previos

Descargar Apache Axis 2 de axis 2
Descomprimir axis2-1.6.2-bin.zip en [axis2_home]

3.2 Configurar Axis2 en Eclipse

Abrir eclipse.
Window > Preferences > Web Services > Axis2 Preferences
En la pestaña Axis2 Runtime, definir el directorio de Axis: [axis_home]
OK

3.3 Crear el proyecto del Web Service

Eclipse:
File > New > Other... > Web > Dynamic Web Project
Next
Project Name: [svc_name]
Location: [svc_dir]
Target runtime: [tomcat_runtime]
Dynamic Web Module Version: 2.5
Configuration:
Pulsar el botón Modify (junto a la configuración custom)
Marcar:
  • Axis2 Web Services
  • Dynamic Web Module
  • Java
OK
Next
Next
En esta ventana podemos cambiar el [context_root] y el [content_dir]
Finish

3.4 Crear un servicio bottom-up

Un servicio bottom-up se crea definiendo la interfaz del servicio en Java y generando el WSDL a partir del interfaz Java. Por el contrario, un servicio top-down se crea definiendo el WSDL y generando las clases Java correspondientes.

Eclipse:
Package Explorer > [svc_name] > Java Resources > src > New > Package
[package_name]
Package Explorer > [svc_name] > Java Resources > src > [package_name] > New > Class
[class_name]
Definir operaciones dentro del servicio

Package Explorer > [svc_name] > Java Resources > src > [package_name] > [class_name].java
New > Other... > Web Services > Web Service
Next

Web Service type: Bottom up Java bean Web Service
Service implementation: [class_name]
En la escala del servidor poner: start service
En la escala del cliente poner: No client
Next

WSDL file: [wsdl_file]
Methods: Seleccionar los métodos que queremos que sean operaciones
Style and use: document/literal (wrapped)
Next

Pulsar el botón start server

Finish








martes, 23 de abril de 2013

Introducción a Struts 2

Struts 2 es un framework para el desarrollo de aplicaciones web basado en:

  • Acciones
  • Interceptores
  • Librería de tags

Acciones

Una acción puede ser cualquier clase Java que cumpla con las condiciones del framework.
Una acción hace tres cosas:
  • Realiza la lógica asociada a una request. Esta lógica se implementa en el método execute() de la acción. Una acción no trata con la request del servlet, ni con la response. Trata con la lógica de negocio.
  • Contiene los datos que vienen de la request y que van al resultado. Estos datos se almacenan como atributos de la acción. Al estar los datos disponibles en la acción, siempre estarán disponibles para la ejecución de la lógica de negocio. La acción simplemente implementa propiedades tipo javabean para cada dato que tiene que transportar. Los parámetros de la request que coinciden con propiedades de la acción se rellenan automáticamente antes de ejecutar la acción. Además, estas propiedades tipo javabean, también estarán disponibles para renderizar el resultado (por ejemplo en la página JSP).
  • Decide cuál es el resultado que se debe visualizar. Cada acción retorna un String que selecciona el resultado que se va a renderizar.

Paquetes de acciones

Los paquetes son contenedores lógicos de acciones.
Un paquete define el namespace (URL base) para todas las acciones de ese paquete y los interceptores que se activarán en todas las acciones del paquete.
Un paquete puede heredar de otro paquete, tomando todas las propiedades del paquete padre, pudiendo añadir nuevas propiedades. Si no heredamos de otro paquete, deberíamos al menos heredar del paquete struts-default, que viene definido en la distribución de struts (fichero struts2-core.jar, struts-default.xml).
Cada paquete define los interceptores y pilas de interceptores que utilizarán las acciones de ese paquete. En caso de herencia, se heredan las pilas e interceptores de la clase padre. Se define una pila de interceptores por defecto, que será la que se ejecute en caso de que la acción no declare otra específicamente.
Normalmente, las acciones se organizan en paquetes por funcionalidad o por nivel de seguridad (por ejemplo un paquete para acciones que requieren autenticación previa y otro paquete para acciones que no requieren autenticación).

Paquete struts-default

Este paquete que viene con la distribución de struts2 (está dentro del fichero struts-core.jar) contiene muchos componentes que se pueden recoger al heredar de este paquete. Es el fichero struts-default.xml
Uno de los componentes más importantes dentro de struts-default es la pila de interceptores por defecto, o defaultStack. Esta pila de interceptores se aplica por defecto a todas las acciones dentro de los paquetes que heredan de struts-default (salvo que se defina otra pila por defecto).
Por ejemplo, la pila por defecto incluye un interceptor llamado params que se encarga de pasar los datos de la request a propiedades de la acción (javabean).
Lo habitual es que todos los paquetes que definamos hereden del paquete struts-default obteniendo así automáticamente las funcionalidades que ofrece este paquete, entre otras, la pila de interceptores por defecto.

Implementar acciones 

Una acción es cualquier clase java que tiene un método execute(). No tiene que heredar de ninguna otra clase ni implementar ningún interfaz. Sin embargo, es útil que las acciones implementen el interfaz Action, ya que entonces tendrán acceso a las constantes definidas en este interfaz. Son constantes para los valores retornados por el método execute: ERROR, SUCCESS, INPUT, LOGIN, NONE. El resultado retornado por la acción determina lo que Struts va a ejecutar la finalizar la acción. Si retorna SUCCESS, el framework dirige a la página definida como SUCCESS para la acción. Si retorna ERROR, el framework dirige a la página definida como ERROR para la acción.
Si deseamos obtener algo más de funcionalidad, podemos heredar nuestra acción de la clase ActionSupport, la cual implementa el interfaz Action. Pero además, implementa otros interfaces muy útiles para internacionalización y validación, proporcionando una implementación por defecto muy útil. Veamos a continuación estas dos importantes funcionalidades: validación e internacionalización.

Validación básica

La clase ActionSupport proporciona una validación básica que será suficiente en muchos casos. El requisito para poder utilizar esta funcionalidad de validación básica es heredar nuestro paquete del paquete struts-default y que nuestra clase acción herede de la clase ActionSupport.
La pila de interceptores por defecto (defaultStack) introduce un interceptor denominado workflow, de la clase Java DefaultWorkflowInterceptor. Este interceptor desvía el flujo a la página de entrada (página llamante) si ocurre un error en la validación. Este interceptor se ejecuta después que el interceptor params, o sea, cuando los datos ya están metidos en los atributos de la acción.
Veamos cómo se ejecuta el interceptor workflow. Cuando se dispara este interceptor, busca un método validate() en la acción. Este método puede chequear los atributos de la acción y detectar errores en los valores pasados como parámetros. Cada vez que ocurre un error de validación, se añade este error a una lista utilizando el método AddFieldError() que proporciona ActionSupport. Después de ejecutarse el método validate() de la acción, el control vuelve al interceptor workflow, el cual mira si se ha generado algún error. Si hubiera algún error, este interceptor altera el flujo de la request y devuelve el control a la página de entrada, mostrando el error junto al campo o campos que han provocado el error.
El método validate() tiene dos opciones para generar errores:
  • addFieldError(fieldName, errorMessage) : genera un error de validación asociado a un campo de entrada
  • addActionError(errorMessage) : genera un error de validación a nivel de acción
Como se puede ver hasta ahora, la filosofía de struts es dejar toda la lógica de negocio en el método execute() de la acción. Todo lo demás, validaciones, paso de parámetros, etc. queda fuera de este método.

Internacionalización

La clase ActionSupport proporciona también una implementación para el manejo de la internacionalización, es decir, gestiona los ficheros de mensajes en varios idiomas. Tenemos a nuestra disposición el método getText() de la clase ActionSupport para obtener mensajes a partir de un clave. Estos mensajes están en un fichero asociado a la acción y se recuperan a partir de una clave. El fichero de mensajes tiene el mismo nombre que la clase que implementa la acción y tiene que estar en el mismo paquete java. Este fichero es un fichero de properties normal de java.
Para definir ficheros de mensajes en varios idiomas, añadiremos a cada uno en el nombre el sufijo con el idioma correspondiente: XXX_es.properties.

Transferencia de datos a la acción

Hasta ahora hemos visto que los datos que  vienen en la request se pueden transferir a atributos de la clase acción. Esos datos son simples. Por ejemplo, si en la request va un atributo que se llama "nombre", el interceptor param intentará transferirlo al atributo "nombre" de la acción, a través de los métodos setNombre() y getNombre().





lunes, 4 de marzo de 2013

Cambiar el tono de una canción MP3

El problema

Muchas veces tenemos canciones en MP3 que no están en la tonalidad que nos gustaría.
¿Por qué? Normalmente porque queremos acompañarlas con algún instrumento, por ejemplo, la guitarra o el bajo. A estas pistas se le llama a veces "back track", refiriéndose a pistas de fondo que acompañan nuestro instrumento, para que éste no suene solo.
La solución típica es adaptar nuestro instrumento y nuestro acompañamiento a la tonalidad en que tenemos el MP3. Pero esto supone cambiar nuestras partituras (o tablas de acordes) y lo que es peor, al ensayar en otra tonalidad de la que luego vamos a interpretar, no nos sirve de mucho como práctica.
Pongamos un ejemplo: tenemos que interpretar la canción en DO mayor, sin embargo tenemos un MP3 de la canción en FA mayor. La opción que tenemos es cambiar nuestras partituras a FA mayor y acompañar así el MP3. Pero como hemos dicho, no nos vale de mucho tocar la canción en FA mayor si luego vamos a tocarla en DO mayor ¿verdad? Aparte de tener que reescribir todas las partituras en FA mayor.
Existe otra solución mucho más cómoda...

Cambiar el tono del MP3

Si no nos convence la solución anterior, tenemos otra, que aunque tiene alguna pega que luego comentaremos, cumple perfectamente su función, sobre todo para ensayo y preparación.
Esta solución consiste en cambiar la tonalidad del MP3.

Llevo varios meses buscando cómo cambiar el tono de un MP3 y no lo encontraba. He leído artículos sobre cómo hacer un paso al dominio de la frecuencia, trasponer y luego volver al dominio del tiempo. La idea es interesante, pero no quería ponerme a implementarla, porque me llevaría bastante tiempo. Así que me decidí a investigar los programas de procesamiento de audio que existen, sobre todo los gratuitos.
Al final dí con la solución: Audacity.
Audacity es un programa gratuito que se puede descargar bien en la versión portable (es la que yo prefiero), o en la versión instalable:


Una vez instalado el programa, lo arrancamos y cargamos el MP3 que queremos cambiarle el tono. Para ello vamos al menú File - Open, o bien,si se ha instalado en español, Archivo - Abrir. Buscamos en el disco duro el fichero MP3 que queremos transponer.

En primer lugar debemos detectar en qué tonalidad está el MP3 original.
Hay varias formas de saberlo. Quizás la más práctica, aunque no la más rápida, es reproducir la canción y con un teclado intentar pillar la tonalidad. Si tenemos la partitura de la canción es relativamente sencillo, ya que haciendo uso de un teclado, vamos intentando "pillar" las notas en el MP3 y luego comparamos con nuestra partitura para ver la diferencia de tonalidad.
Si sólo tenemos los acordes, es un poco más complicado, pero también se puede hacer. Buscamos el acorde principal e intentamos casarlo con la canción, subiendo o bajando de acorde. Por ejemplo, si en nuestra partitura tenemos la canción en DO mayor, reproduciremos el MP3 y probamos si el DO mayor encaja (normalmente no, porque en caso afirmativo, ya hemos acabado). Seguimos probando subiendo a RE mayor, MI mayor, DO# mayor, etc. Y luego vamos bajando: SI mayor, LA mayor etc. Cuando hayamos localizado la tonalidad principal, ya sabemos el tono de la canción MP3. Y por tanto, ya sabemos cuántos tonos tenemos que subir o bajar para conseguir el MP3 en el tono que queremos.

Otra opción sería utilizar algún programa que detecte el tono de una canción, pero eso lo considero mucho menos fiable. A mí por lo menos nunca me funcionan bien...

Después vamos al menú Effect - Change Pitch, o bien, Efecto - Cambiar tono.
En esta ventana le tenemos que decir cuántos semitonos queremos subir o bajar. Aplicamos el cambio y ya tenemos la canción en la tonalidad deseada.

Ahora sólo tenemos que exportar la canción a MP3 con File - Export o bien Archivo - Exportar.

Problemas de esta solución

En mi opinión, la solución que propongo tiene dos problemas:

  1. Encontrar la tonalidad del MP3 puede ser un poco complicado, pero es cuestión de práctica. Al final lo encuentras.
  2. El MP3 resultante no es perfecto, o sea, no suena como el original, sobre todo la voz humana. Sin embargo, mi opinión es que es perfectamente válido para ensayar, y para eso lo utilizo yo. No se te ocurra enviárselo a un amigo para que escuche una canción, ya que no le va a gustar mucho.





martes, 19 de febrero de 2013

Juego para Android: Retro Kong Jungle

El juego

Si tienes más de 30 años seguramente has conocido y has jugado con aquellas antiguas consolas "monojuego" que nos hacían pasar ratos extraordinarios.
Comparado con lo que tenemos ahora, se podría decir que: eran muy caras para lo que ofrecían (un solo juego), la calidad gráfica del juego era un poco pobre (habitualmente blanco y negro y muy poca resolución), no tenían muchas variantes (el juego siempre era lo mismo, aunque cada vez más difícil por la velocidad).
Sin embargo: eran juegos muy adictivos, nos hacían pasar horas maravillosas, habitualmente desarrollaban el sentido del ritmo en el jugador. Y muchas otras cosas buenas. Pero sobre todo: era lo que había en aquéllos tiempos (años 80).
Supongo que ya sabes a qué consolas me refiero. Aquí tienes algún ejemplo:

http://blog-mundoretro.blogspot.com.es/2012/04/game-watch-las-maquinitas-de-nintendo.html

Estas consolas son muy difíciles de conseguir hoy en día y además son muy caras (en caso de encontrarlas de segunda mano). Así que he decidido, junto a mis hijas Cristina y Patricia, hacer uno de estos juegos para Android.
Dicho y hecho. Utilizando AndEngine me puse a ello y en un par de días he conseguido algo que se parece bastante a uno de aquellos juegos:

https://play.google.com/store/apps/details?id=com.joseanquiles.android.retrokongjungle



Es un juego muy divertido que ya ha conseguido que mis hijas no puedan despegarse del móvil, intentando continuamente batir el record (actualmente lo tiene Patricia con 2800 puntos). Por supuesto, es un juego gratuito y sin publicidad de ningún tipo, para que pueda jugar el máximo número de video-juego-adictos y otros que simplemente quieren pasar un buen rato recordando viejos tiempos.
¡Qué lo disfrutéis!

La historia

La idea del juego es muy sencilla.
Se trata de King Kong y "la chica".
La chica se quiere bañar plácidamente bajo las cataratas del Niágara. Pero la cosa no es tan fácil como ella pensaba. Por la caída de agua caen troncos de madera de vez en cuando con el consiguiente riesgo de aplastarla. Además, por el río bajo la cascada circulan serpientes venenosas que van directamente a picarle.
Pero el galante King Kong no está dispuesto a que la chica muera, así que recogerá todos los troncos que caen por la cascada antes de aplastar a la chica, y pisará a cualquier serpiente que se acerque a ella.
Al principio, la tarea de King Kong es sencilla, porque los troncos caen muy despacio y las serpientes se acercan poco a poco a la chica. King Kong no tendrá problemas en los inicios del juego.
Sin embargo, conforme avanza el juego, la velocidad se incrementa y King Kong tendrá que ser muy rápido para poder parar todos los troncos y serpientes que se acercan a la chica.

Cómo se juega

Jugar a Retro Kong Jungle es muy sencillo.
Abajo tenemos dos botones (los de arriba sirven para ver los créditos y para resetear el juego y volver a empezar). Esos dos botones de abajo sirven para que King Kong vaya de un lado a otro de la cascada.
En el lado izquierdo puede coger troncos. Y en el lado derecho puede pisar serpientes.
Hay que estar muy atentos para estar en el momento adecuado y poder coger el tronco antes de que aplaste a la chica. Para ello, llevaremos a King Kong hacia la derecha, y cuando el tronco esté junto a la poderosa mano de King Kong, entonces volvemos a pulsar el botón derecho y cogeremos el tronco.
Igualmente, cuando una serpiente se acerque a la chica, tendremos que estar en el lado izquierdo y pulsar el botón izquierdo justo cuando la serpiente pase por debajo de los pies de King Kong.
¿Fácil? Sí, pero cuidado. Los troncos y las serpientes se van intercalando y tendremos que ir llevando a King Kong de un lado para otro, cogiendo troncos y pisando serpientes.
Cuando aumenta la velocidad podrás disfrutar de unos momentos realmente emocionantes.
Además, cada 250 puntos, la chica dará una recompensa sorpresa a King Kong.



lunes, 11 de febrero de 2013

Crear imagen del sistema con Windows 7

Introducción

Crear una imagen del disco es un proceso bastante sencillo de llevar a cabo y que puede resultar de mucha utilidad en el futuro.
Normalmente se recomienda hacer una imagen del disco tras instalar el sistema operativo y después de instalar los programas que utilizamos habitualmente. Pero yo recomiendo hacer la imagen de disco un poco antes, justo después de instalar el sistema operativo, actualizar todos los service packs, instalar todos los drivers de nuestro equipo, y quizás, algún programa muy básico pero que utilizamos muy frecuentemente.
¿Por qué? Por varias razones, pero una sobre todo: porque las aplicaciones se actualizan con frecuencia, entonces, cuando queramos recuperar, no nos valdrá de mucho tener una imagen de hace un año con las versiones de las aplicaciones hace un año. Además, instalar las aplicaciones no suele llevar mucho tiempo.
Pues dicho esto, voy a intentar explicar cómo hacer una imagen de nuestro disco en Windows 7 y luego cómo recuperarla en caso de fallo.

Crear una imagen

En primer lugar, introducimos un DVD-RW vacío en la unidad de DVD.
Abrimos el panel de control (Inicio > Panel de control)
Pulsamos en la sección "Sistema y Seguridad"
En la sección "Copias de seguridad y restauración", en el frame izquierdo de esta ventana, pulsamos sobre "Crear imagen de sistema".
Aparecerá una nueva ventana titulada "¿Dónde desea guardar la copia de seguridad?". Seleccionar la opción "En uno o más DVDs" y en el combobox, seleccionar la unidad de DVD donde hemos introducido el disco. Pulsar "Siguiente"
En la siguiente ventana se nos mostrará las unidades que componen el sistema. Pulsar "Siguiente".
En la siguiente ventana, pulsar en "Iniciar copia de seguridad".
A partir de aquí, nos irá pidiendo discos para la copia. Es conveniente etiquetarlos indicando al menos, un identificador del PC que estamos haciendo la imagen, versión de Windows, la fecha de hoy, y el número de disco.

Para poder recuperar esa imagen en caso de que Windows se dañara, tenemos que crear antes un disco de recuperación desde el que podamos arrancar Windows. Esto lo vemos en el siguiente apartado.

Crear un disco de recuperación

En primer lugar, introducimos un DVD-RW en la unidad de DVD.
Abrimos el panel de control (Inicio > Panel de control)
Pulsamos en la sección "Sistema y Seguridad"
En la sección "Copias de seguridad y restauración", en el frame izquierdo de esta ventana, pulsamos sobre "Crear un disco de reparación del sistema".
A continuación se formatea el disco y se escribe el disco de arranque.

Recuperar una imagen del sistema

Cuando Windows se daña y queremos sustituirlo por la imagen del sistema que hemos creado, tenemos que arrancar con el disco de reparación.
Para ello, tenemos que entrar en la configuración de la BIOS y poner como primer disco de arranque el DVD. Esto depende de cada ordenador y por tanto no se va a explicar aquí.

Cuando se arranca con el disco de reparación hay que seleccionar la opción de restaurar la computadora con una imagen del sistema que se ha creado anteriormente. Entonces hay que ir introduciendo los discos con la imagen del sistema.






viernes, 18 de enero de 2013

Splash screen con AndEngine

Cuando una aplicación Android consta de varias ventanas se suele implementar con varias Activity.
Sin embargo, esto no es lo aconsejable.
El caso típico de un juego son al menos cuatro ventanas:

  • Splash screen
  • Menú
  • Opciones
  • Ventana del juego
Y la navegación entre ambas sería la siguiente:

Comienza la splash, la cual desaparece al cabo de unos pocos segundos y aparece automáticamente el menú. Desde el menú se puede acceder a la ventana de opciones (donde se configura el juego) y desde ahí se puede volver otra vez al menú. Y por fin, desde el menú se accede a la ventana del juego.

Lo aconsejable con AndEngine es crear cuatro escenas y pasar de una a otra utilizando:

    engine.setScene(unaEscena);

En este artículo vamos a seguir este patrón y vamos a crear una splash screen. Crearemos una Activity heredando de SimpleBaseGameActivity, crearemos las EngineOptions y por último, crearemos dos escenas: splashScene y menuScene.

En primer lugar, creamos el proyecto Android de forma similar a como se hace en este artículo.

Método onCreateEngineOptions()

Este método es similar al seguido en el ejemplo del artículo anterior:
public static final int CAMERA_WIDTH = 800;
public static final int CAMERA_HEIGHT = 480;
private Camera camera;
@Override
public EngineOptions onCreateEngineOptions() {
this.camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(
true, 
ScreenOrientation.LANDSCAPE_FIXED,
new FillResolutionPolicy(),
this.camera);
return engineOptions;
}

Método onCreateResources()

En este método se cargan los recursos para el menú y para la splash screen:


@Override
protected void onCreateResources() {
// Background
this.backgroundTexture = new BitmapTextureAtlas(this.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
this.backgroundRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.backgroundTexture, this, "background.png", 0, 0);
this.backgroundTexture.load();
// Splash


this.splashTexture = new BitmapTextureAtlas(this.getTextureManager(), 1024, 500, TextureOptions.BILINEAR);
this.splashRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.splashTexture, this, "splash.jpg", 0, 0);
this.splashTexture.load();
       }

Método onCreateScene()

En este método se crean las dos escenas: la de la splash screen y la del menú. Inicialmente se activa la escena de splash, pero se pone un timeout, transcurrido el cuál, se activa la escena del menú.

@Override
protected Scene onCreateScene() {
// Escena del menú
menuScene = new Scene();

// Background de la escena
Sprite backgroundSprite = new Sprite(0, 0, this.backgroundRegion, getVertexBufferObjectManager());
menuScene.attachChild(backgroundSprite);

// Escena de splash
splashScene = new Scene();

// Background de la splash screen
Sprite splashSprite = new Sprite(0, 0, this.splashRegion, getVertexBufferObjectManager());
splashScene.attachChild(splashSprite);

mEngine.registerUpdateHandler(new TimerHandler(3f, new ITimerCallback() {
@Override
public void onTimePassed(TimerHandler handler) {
mEngine.unregisterUpdateHandler(handler);
splashScene.detachSelf();
mEngine.setScene(menuScene);
}
}));
return splashScene;
}









Hello World con AndEngine

Antes de empezar a hacer este ejemplo con AndEngine, es necesario tener instalado el motor.
Ver Instalación de AndEngine

1. Abrir Eclipse

2. Crear el proyecto Android

    * File > New > Android Application Project
    Name: HelloWorld
    Package: poner un package cualquiera, por ej com.minombre.android.andengine
    Minimum Required SDK: API 8
    Target SDK: API 15
    Compile With: API 15
    Theme: None
    * Pulsar "Next >"
    Desmarcar "Create custom launcher icon"
    Marcar "Create Activity"
    Desmarcar "Mark this project as a library"
    Desmarcar "Create project in workspace"
    Pulsar "Browse..." y elegir un directorio para el proyecto

    * Pulsar "Next >"
    Marcar "Create Activity"
    Seleccionar "BlankActivity"
    * Pulsar "Next >"
    Activity Name: MainActivity
    Layout name: activity_main
    Navigation type: None
    * Pulsar "Finish"

3. Referenciar la librería AndEngine

    Package Explorer
    Proyecto Hello World (botón dcho) > Properties > Android
    Sección Library: Pulsar "Add..." y añadir la librería AndEngine
    Pulsar "OK"

4. Heredar la Activity de SimpleBaseGameActivity

    Package Explorer
    Abrir MainActivity.java
    Extender SimpleBaseGameActivity
    Eliminar los métodos onCreate y otros que se hayan generado.
    Pulsar sobre la bombilla amarilla a la izda de class > Add unimplemented methods
    Se generarán automáticamente los siguientes métodos:
        onCreateEngineOptions()
        onCreateResources()
        onCreateScene()

5. Crear las variables de clase para la cámara:

private Camera camera;
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;

6. Implementar el método onCreateEngineOptions:

@Override
public EngineOptions onCreateEngineOptions() {
this.camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engOptions = new EngineOptions(
true,   // full screen 
ScreenOrientation.LANDSCAPE_FIXED, 
new FillResolutionPolicy(), 
this.camera);
                engOptions.getAudioOptions().setNeedsSound(true);

engOptions.getAudioOptions().setNeedsMusic(true);

return engOptions;
}

Los parámetros de EngineOptions son:
    true: indica que la Activity ocupará toda la pantalla, incluida la barra de estado.
    LANDSCAPE_FIXED: la pantalla se mostrará en horizontal aunque rote el dispositivo
    FillResolutionPolicy: el motor se adapta al tamaño físico de la pantalla. Esto puede suponer que las imágenes se deformen.

7. Implementar el método onCreateScene:

@Override
protected Scene onCreateScene() {
Scene scene = new Scene();
scene.setBackground(new Background(0.098f, 0.62f, 0.66f));
return scene;
}

Scene es una Entity que contiene otras entities como sprites, etc.

8. Implementar onCreateResources

@Override
protected void onCreateResources() {
loadGraphics();
loadFonts();
loadSounds();
  loadMusic();
}

private void loadGraphics() {
}
private void loadFonts() {
}
private void loadSounds() {
}


private void loadMusic() {
}

 9. Cargar los gráficos

Crear un folder en assets:
    Package Explorer
    Directorio "assets"
    New > Folder
    Folder name: gfx
    * Pulsar "Finish"
Copiar una imagen .png en assets/gfx con el explorador de Windows.
Situarse en el package explorer sobre assets y pulsar F5
Crear las variables de clase:
private BitmapTextureAtlas texture;
private ITextureRegion region;
Implementar el método loadGraphics:
private void loadGraphics() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
texture = new BitmapTextureAtlas(getTextureManager(), 128, 128, TextureOptions.DEFAULT);
region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(texture, this, "android.png", 0, 0);
texture.load();
// cuando la textura no sea necesaria: texture.unload();
}

10. Cargar las fuentes

Crear un folder en assets:
    Package Explorer
    Directorio "assets"
    New > Folder
    Folder name: font
    * Pulsar "Finish"
Copiar una fuente .ttf en assets/font con el explorador de Windows (en este enlace hay muchas fuentes ttf para descargar: fuentes )
Situarse en el package explorer sobre assets y pulsar F5
Crear la variables de clase:
private Font font;
Implementar el método loadFonts:
private void loadFonts() {
FontFactory.setAssetBasePath("font/");
final ITexture fTexture = new BitmapTextureAtlas(getTextureManager(), 32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
font = FontFactory.createFromAsset(getFontManager(), fTexture, getAssets(), "BaroqueScript.ttf", 40, true, Color.BLACK);
font.load();
}

11. Cargar los sonidos

Crear un folder en assets:
    Package Explorer
    Directorio "assets"
    New > Folder
    Folder name: mfx
    * Pulsar "Finish"
Copiar un sonido .ogg en assets/mfx con el explorador de Windows (se recomienda en formato .ogg porque ocupa mucho menos espacio que mp3 por ejemplo).
Situarse en el package explorer sobre assets y pulsar F5
Crear la variables de clase:
private Sound sound;
Implementar el método loadSounds:
 private void loadSounds() { SoundFactory.setAssetBasePath("mfx/"); try { this.sound = SoundFactory.createSoundFromAsset(getEngine().getSoundManager(), this, "risa.ogg"); } catch (IOException e) { Log.e(tag, "loadSounds() " + e.getMessage()); } }


12. Cargar la música

Copiar una cancion .ogg en assets/mfx con el explorador de Windows (se recomienda en formato .ogg porque ocupa mucho menos espacio que mp3 por ejemplo).
Situarse en el package explorer sobre assets y pulsar F5
Crear la variables de clase:
private Music music;
Implementar el método loadMusic:

private void loadMusic() {
MusicFactory.setAssetBasePath("mfx/");
try {
this.music = MusicFactory.createMusicFromAsset(getEngine().getMusicManager(), this, "pantera_rosa.ogg");
this.music.setLooping(true);
} catch (IOException e) {
Log.e(tag, "loadMusic() " + e.getMessage());
}
}






miércoles, 16 de enero de 2013

Ciclo de vida de una Activity en AndEngine

Una Activity que utilice el motor AndEngine derivará normalmente de la clase BaseGameActivity (o de otra clase de AndEngine). Por el hecho de derivar de esta clase, la Activity tiene un ciclo de vida que se describe en este artículo. El ciclo de vida incluye las necesidades típicas de la inicialización de un juego: crear el motor y configurarlo, cargar los recursos (imágenes, sonidos, fuentes), crear y rellenar la escena.

Este ciclo de vida nos obliga a implementar cuatro métodos que se invocan en el siguiente orden:

  1. onCreateEngineOptions()
  2. onCreateResources()
  3. onCreateScene()
  4. onPopulateScene()
Además de estos cuatro métodos, se pueden implementar otros métodos de AndEngine, pero no es obligatorio.

onCreateEngineOptions() : en este método se crea el objeto Camera que utilizará el motor para visualizar y el objeto EngineOptions. El objeto EngineOptions son las opciones que se aplicarán al objeto Engine que va a controlar el juego. Estas opciones incluyen (entre otras) activar/desactivar música y sonidos, opciones multitouch, opciones de rendering, modo de orientación de la pantalla, modo de resolución de la pantalla, etc.
onCreateResources() : en este método se cargan y se crean los recursos que necesita la Activity. Sonidos, texturas (imágenes), música, fuentes. Dentro de este método, es obligatorio invocar a pOnCreateResourcesCallback.onCreateResourcesFinished() para comunicar a AndEngine que hemos terminado de cargar los recursos.
onCreateScene() : en este método se crea el objeto Scene vacío. Además, en este método se configuran los listeners y handlers de Scene. Este método también debería configurar, si es necesario, los eventos y listeners relacionados con la escena. Cuando se ha configurado el objeto Scene, es obligatorio invocar a pOnCreateSceneCallback.onCreateSceneFinished(scene).
onPopulateScene() : en este método se añaden las entidades hijas a la Scene. Este método se introdujo para separar la creación de la escena de su rellenado con entidades. Como en los dos métodos anteriores, es obligatorio invocar a pOnPopulateSceneCallback.onPopulateSceneFinished() cuando se hayan añadido los hijos.

Ejemplo código completo:

package com.joseanquiles.testandengine;

import java.io.IOException;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.WakeLockOptions;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.ui.activity.BaseGameActivity;

public class MainActivity extends BaseGameActivity {

private static final int WIDTH = 800;
private static final int HEIGHT = 480;
private Scene mScene;
private Camera mCamera;
public EngineOptions onCreateEngineOptions() {
mCamera = new Camera(0,0,WIDTH,HEIGHT);
EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(), mCamera);
engineOptions.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
return engineOptions;
}

public void onCreateResources(
OnCreateResourcesCallback pOnCreateResourcesCallback)
throws IOException {
pOnCreateResourcesCallback.onCreateResourcesFinished();
}

public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
throws IOException {
mScene = new Scene();
mScene.setBackground(new Background(0.09804f, 0.6274f, 0));
pOnCreateSceneCallback.onCreateSceneFinished(mScene);
}

public void onPopulateScene(Scene pScene,
OnPopulateSceneCallback pOnPopulateSceneCallback)
throws IOException {
pOnPopulateSceneCallback.onPopulateSceneFinished();
}

}







martes, 15 de enero de 2013

Conceptos en AndEngine

BaseGameActivity

Es una clase derivada de la Activity de Android y que tiene un engine. Es la vista donde se va a dibujar el juego.

LayoutGameActivity

Es otra clase derivada de la Activity de Android. Se utiliza para definir layouts con objetos de IU tales como botones, textfields, etc. Recordemos que un juego puede tener también otras pantallas además de la pantalla propia del juego. También se utiliza esta clase para insertar anuncios de Google.

Engine

El engine es el motor que hace que el juego se ejecute en pequeños pasos (en el tiempo). Se encarga de ir dibujando en pantalla (según los fps) y de actualizar los objetos de la escena

ResolutionPolicy

Es un parámetro del engine. Le indica a AndEngine cómo debe tratar con diferentes tamaños y resoluciones de pantallas. Por ejemplo, RatioResolutionPolicy maximizará el tamaño a lo máximo que permita la pantalla, manteniendo una relación de aspecto concreta. FillResolutionPolicy ocupará toda la pantalla, pero puede distorsionar, ya que no mantendrá la relación de aspecto. Gracias al ResolutionPolicy el programador se olvida de la resolución del terminal. Se hace el programa para una resolución concreta y AndEngine se encarga de dibujar en la resolución del terminal.

Camera

Define el rectángulo de la escena que se dibuja en la pantalla, que no tiene por qué ser la escena completa. Lo normal es tener una Camera por cada Scene. Existen objetos derivados de Camera que permiten hacer zoom y moverse suavemente.

Scene

Es el contenedor de todos los objetos que se dibujan en la pantalla. Una Scene puede tener capas, las cuales pueden contener entidades (estáticas o dinámicas).

Entity

Es un objeto que puede dibujarse, como por ejemplo, sprites, rectángulos, texto, líneas, etc. Una Entity tiene una posición, una rotación, escala, color, etc.

Texture

Una textura es como un canvas gigante donde se pueden situar imágenes más pequeñas, llamadas TextureRegion (en versiones anteriores de AndEngine, el ancho y alto de una textura tenía que ser potencia de 2, pero esa limitación ya no existe). Se pueden situar TextureRegions en cualquier lugar de la textura y extraerlas después a partir de cualquier posición.
En teoría se pueden poner TextureRegions una junto a otra, aprovechando así el espacio al máximo. Sin embargo se recomienda dejar un pixel vacío entre TextureRegions porque en algunos casos se aprecian bordes raros en las imágenes.

TextureRegion

Define un rectángulo en una textura. Los objetos TextureRegion se utilizan en los sprites para manejar imágenes que contienen otras imágenes más pequeñas y que se visualiza una única de ellas en un momento determinado.

Cuestiones importantes

¿Por qué utilizar Textures y TextureRegions? Sería mucho más sencillo tener cada bitmap por separado. La respuesta es por un tema de rendimiento. OpenGL sólo puede tener una textura cargada en memoria en cada momento. Así, si ponemos las imágenes en distintas texturas, OpenGL tendrá que descargar y cargar continuamente de memoria. Sin embargo, teniendo todas las imágenes en una textura, OpenGL sólo tiene que visualizar una parte de esa textura, pero sin cargar otra.
¿Qué tamaña de textura es el máximo? OpenGL soporta texturas de hasta 2048 x 2048. Sin embargo, en algunos terminales, el límite está en 1024 x 1024, así que no se recomienda superar este último tamaño.

AndEngine: Instalación y creación de proyectos

AndEngine es una librería para el desarrollo de juegos para Android. Se trata de un motor OpenGL gratuito desarrollado por Nicolas Gramlich.
Es una plataforma muy potente, pero tiene el inconveniente de que no tiene prácticamente ninguna documentación, y esto hace que mucha gente la abandone a los pocos minutos de empezar. De hecho, es bastante complejo instalarla y empezar un proyecto desde cero.
En este artículo voy a intentar solventar esta dificultad de dar el primer paso con AndEngine, ya que estoy convencido que dar los demás pasos (o sea, desarrollar el juego en sí) ya no es tan complicado.

NOTA: Se explica aquí cómo poner en marcha AndEngine versión GLES2, o sea, la última versión. Nicolas Gramlich abandonó la versión GLES1 hace unos meses y sólo se está evolucionando la versión 2. Todo lo que se explica en este artículo NO es válido para GLES1.

1.Instalación de AndEngine

Requisitos previos:
  • Eclipse
  • Java JDK (mínimo 5)
  • Android SDK (al menos Android 4.0)
  • Plugin ADT para Eclipse
Existe una opción muy sencilla que es descargar e instalar ADT bundle (Android Development Tools) que contiene todo lo necesario (excepto el JDK). Lo tenemos en la siguiente URL de descarga:

http://developer.android.com/sdk/index.html#download

Descargamos el bundle y lo descomprimimos en cualquier directorio del disco duro.

Después vamos a la URL: https://github.com/RealMayo que contiene la versión estable de AndEngine.
Pulsamos sobre la pestaña "Repositories".
Hay que descargar todos los repositorios que aparecen en esta página.
Para ello, pulsamos sobre el primer repositorio. Pulsamos en el botón "ZIP" y descargamos el repositorio.
Volvemos a la página anterior y vamos descargando todos los repositorios.

Descomprimimos todos los ficheros ZIP descargados en el disco duro.

El siguiente paso es abrir Eclipse (que viene con el adt-bundle).

File > Import... > General > Existing Projects into Workspace
Next
Select root directory: elegir el directorio base donde se han instalado todos los repositorios
Finish
Aparecerá un error como este: Unable to resolve target 'android-15'
Para resolver este problema:

Window > Android SDK Manager

Seleccionar los siguientes elementos (algunos ya estarán instalados y no hay que seleccionarlos):

API 17: SDK Platform, ARM EABI v7a System Image, Google APIs

API 16: SDK Platform, ARM EABI v7a System Image, Intel x86 Atom System Image, Google APIs
API 15: SDK Platform, ARM EABI v7a System Image, Intel x86 Atom System Image, Google APIs
API 14: SDK Platform, ARM EABI v7a System Image, Google APIs
API 8: SDK Platform, Google APIs
API 7: SDK Platform, Google APIs

Volver a Eclipse.

Seleccionar con el botón derecho cada uno de los proyectos de AndEngine > Properties > Java Compiler
Marcar: Enable project specific settings
Compiler compliance level: 1.6

Ahora aparecerán otros errores en la pestaña "Problems" de Eclipse.
Hay que entrar en cada uno de los proyectos (excepto el proyecto AndEngine) y hacer lo siguiente:

Proyecto > Properties > Android
En las librerías, aparecerán algunas con una X roja. Hay que seleccionarlas, borrarlas con el botón "Remove", y luego añadir la misma con el botón "Add".

Salir de Eclipse y volver a entrar. Se recompilará todo.
Ya no debería salir ningún error.


2.Aplicación


Abrir Eclipse

File > New > Android Application Project

    Minimum required SDK = 2.2
    Target SDK = 16
    NO create custom launcher icon

Next

Create blank activity

Next

Finish

Package Explorer > proyecto > Android Tools Fix Project Properties

Package Explorer > proyecto > Properties > Java compiler >>> 1.6

Package Explorer > proyecto > Android

    Library
    Add
         AndEngine

OK

Abrir MainActivity.java

Vaciar la clase

Heredar de BaseGameActivity

Implementar los métodos:

    onCreateEngineOptions()
    onCreateResources()
    onCreateScene()
    onPopulateScene()

3. Publicación en el Market

Si se desea la aplicación en el Market de Android hay que realizar unos pocos pasos más:

Copiar el fichero andengine.jar al folder libs del proyecto. El fichero andengine.jar se encuentra en el directorio bin del proyecto AndEngine.

Proyecto > Properties > Android > Eliminar todas las librerías (AndEngine)

Project > Clean...

Project > Android Tools > Fix Project Properties

Y ahora ya se puede exportar la aplicación para el market.