Entradas

Unity: Generación procedural de niveles para juego de plataformas (2D)

Estoy iniciándome en el desarrollo de videojuegos, de momento 2D, en Unity; siguiendo algunos tutoriales en YouTube he creado el principio de un juego básico de plataformas. Una vez lo tenía todo listo me asaltó la duda, ¿ Diseño de niveles o niveles procedurales ? Como la segunda opción parecía mas interesante a modo de reto, he estado viendo como podría hacer esto y al final la solución ha sido bastante sencilla; obviamente habrán mejores formas de generarlos pero para hacer algo tipo Mario Bross queda bastante resultón. La solución se basa en tener un objeto (GameObject) que recorre el mapa desde un punto y va instanciando objetos. Tiene una lista de plataformas diferentes, va avanzando como máximo lo mismo que puede avanzar el jugador que son 5 espacios, y dependiendo de unos valores generados aleatoriamente dibujan suelo o añaden enemigos. Este es el script resultante. public   class   LevelCreator   :   MonoBehaviour   {      public   GameObject   ground ;      publi

Qt cross platform UI scaling ( Android / Windows / Linux )

Sé que Qt tiene otros métodos para disfrutar de una escala apropiada en cualquier plataforma, pero es bastante común el trabajar sobre un proyecto en el cual no puedes hacer uso de esos métodos y necesitas al final usar un factor común de escala para todos los elementos. Tras mucho investigar y hacer pruebas empíricas he conseguido tener un factor de escala que realmente funcione en todas las plataformas ( he probado en Android, Windows y linux ) resultando en un mismo aspecto en cualquier dispositivo sin importar de su resolución o densidad.   Aquí os cuento como hacerlo.   1.- El primer paso es obtener los dpi en los que el dispositivo está funcionando realmente   - Android - // Android tiene density baseline de 160dpi ( mdpi )  QAndroidJniObject qtActivity =  QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");  QAndroidJniObject resources = qtActivity.callObjectMethod(&q

Convertir una cadena que contiene un valor hexa a entero, util para convertir luego a carácter imprimible.

Si alguna vez habéis trabajado directamente con carácteres para hacer conversiones de Unicode y demás ( por ejemplo el típico caso de un parser de emoji ) os habréis dado con la puerta en las narices a la hora de convertir de String a entero y luego poder guardar este formato, tras mucho divagar conseguí la solución y os la expongo aqui. Integer.decode("0x"+cadena); // Convertir a entero. String.format("%C",Integer.decode("0x"+cadena))// Convertir al carácter correspondiente. En cuanto tenga otro rato pondré como pasar una cadena URLEncoded que contiene el valor de un carácter en hexa octal a un valor guardable como cadena para después ser usado con el snippet de arriba. Happy coding!.

Recorrer drawables obteniendo su id y su nombre, solución a "code too large"

Con el siguiente snippet de código podéis recorrer todos los recursos de la aplicación e ir uno a uno obteniendo su nombre y su identificador de recurso. Puede parecer una tontería pero es especialmente útil para por ejemplo cargar un array con los recursos que empiezan llamándose de una forma. Por ejemplo es común utilizar esto cuando se necesita un array con imaginad 800 recursos cargados en un cuerpo static. ( de otra forma obtendríais el poco conocido error de compilación "Code too large"). Field[] drawables = R.drawable.class.getFields(); R.drawable drawableResources = new R.drawable(); for (Field f : drawables) { try { if(f.getName().startsWith("ejemplo_")) { arrayRecursos.put(f.getName(),f.getInt(drawableResources)); } } catch (Exception e) { e.printStackTrace(); } } Happy coding!.

Android: Optimización de accesos en SQLite

Os regalo un snippet que os va a volver locos a todos los que desarrolléis una aplicación que tenga un acceso intenso a datos en SQL. Está sacado de un bugfix incluido en Mozilla Firefox para Android y yo he comprobado en mis carnes el sustancial aumento de rendimiento, en vuestro SQLiteOpenHelper, añadir: @Override public void onOpen(SQLiteDatabase db) { // From Honeycomb on, it's possible to run several db // commands in parallel using multiple connections. if (Build.VERSION.SDK_INT >= 11) { db.enableWriteAheadLogging(); } else { // Pre-Honeycomb, we can do some lesser optimizations. Cursor cursor = null; try { cursor = db.rawQuery("PRAGMA synchronous=NORMAL", null); } finally { if (cursor != null) cursor.close(); } cursor = null; try { cursor = db.rawQuery("PRAGMA journal_mode=PERSIST", null); } finally { if (cursor != null) cursor.close(); } } super.onOpen(db); } Según las pruebas de aumento de rendimiento de la gente de

SQLException: SQL logic error or missing database

Estas usando tu content provider y alegremente recibes esta excepción "SQLException: SQL logic error or missing database" por supuesto no te cuadra de donde puede venir. Pues bien, ojo que los de sqlite han escrito esa excepción con un mensaje algo extraño o quizá es muy genérica. Cuando a mi me ha ocurido es por: - Estas ejecutando una instrucción SQL con un "?" que no se está reemplazando por nada ( ejemplo un WHERE ? que no intercambia el ? por la selección ). - Se está intentando introducir NULL en una columna que es non-NULL Humor: lo cojonudo es que te diga que a lo mejor no existe la base de datos.

Android Tip: "No me funciona el Log Cat"

Voy a comentar un problema que he tenido hoy con un terminal HUAWEI U8650 el cual me ha chocado bastante, tanto el problema como la solución. El caso es que estaba yo intentando depurar el teléfono y no me aparecía el logcat en IntelliJ Idea.. y digo.. raro. Como es normal voy a la consola corriendo y pongo adb logcat. A lo que me responde: “Unable to open log device '/dev/log/main': No such file or directory” Entonces ya me interesa el problema, me digo, va a ser de traca; pues tras mucho divagar, ojo a la solución.. 1.- Marcas en el teclado de llamada: *#*#2846579#*#* 2.- Esto abrirá un menú oculto de servicio, en el vamos a: "ProjectMenu" -> "Background Setting" -> "Log Setting" 3.- Configuramos el logcat. "Log switch" para activarlo o desactivarlo. "Log level setting" para seleccionar el nivel de log. 4.- Importante, reiniciar el teléfono al terminar. Nota: Probablemente en este menú se pueda hac