Android: comunicación de hijo a padre

Este es un tutorial de algo que acabo de aprender, así que si encuentran algún error, estaré muy agradecida si me lo hacen ver :)

Esto es básicamente lo que haremos:

pre preview

Ya existe un tutorial que indica cómo enviar información desde una actividad hacia una actividad invocada, es fácil, sólamente tienes que adjuntar los datos en el intent que inicia la actividad. En este tutorial explico cómo enviar información desde la actividad invocada hacia la actividad invocadora, esto es un poco más difícil (especialmente porque la documentación del método finishActivity(requestCode) está un poco desatinada, y el tutorial oficial está incompleto).

TL;DR: finishActivity(requestCode) no finaliza la actividad, sólamente setea el request code con el que la actividad finalizará. Para realmente finalizar la aplicación, debes usar finish() después de haber usado finishactivity(…).

Piensa en una actividad invocada como una función que retorna información al finalizar. En el código del invocador añadiremos el método invocar que será ejecutado al hacer clic en el botón Invocar del view.

    // el argumento View es necesario cuando el método es invocado desde el view.
    public void invocar (View view) {
        startActivityForResult(new Intent(this, Invocado.class), PEDIDO_DE_MENSAJE);
    }

Luego en el invocado vamos a escribir el código del botón Enviar.

     public void enviar (View view) {
        Intent intento = getIntent();
        EditText recipienteNombre = (EditText) findViewById(R.id.nombre);
        EditText recipienteMensaje = (EditText) findViewById(R.id.mensaje);

        intento.putExtra("mensaje", recipienteMensaje.getText().toString()); // ewww
        intento.putExtra("nombre", recipienteNombre.getText().toString()); // eeewwwwww D'X

        // identifica la respuesta como exitosa.
        setResult(RESULT_OK, intento);
        // identifica el tipo de respuesta como respuesta a pedido de mensaje del invocador.
        finishActivity(Invocador.PEDIDO_DE_MENSAJE);
        // finaliza la actividad devolviendo la respuesta en el callback de quien la invocó.
        finish();
    }

Esas dos líneas que provocan asco no me gustan porque hacen que el código sea un spagetti DX. Pese a que el método putExtra tiene sobrecarga para todos los tipos primitivos de Java, imagina que queremos enviar un montón de datos, por cada dato un putExtra… por cada putExtra un nombre… ewwwwww DX (y si lo dejaramos así, se pondría peor! luego, al querer recibir el mensaje en el Invocador, tendríamos que recibir cada dato por su nombre x__x)

En lo personal prefiero enviar un objeto mediante el putExtra, para ello necesitamos crear la clase del objeto que queremos serializar, y que implemente la interfaz Serializable

    public class Mensaje implements Serializable {
        public String contenido;
        public String remitente;

        public Mensaje (String contenido, String remitente) {
            this.contenido = contenido; this.remitente = remitente;
        }

        public String toString () {
            return "[" + remitente + "]: " + contenido;
        }
    }

Por lo que en vez de esas dos asquerosas líneas de código, tendremos esta apetitosa línea de código

    // apetitosa linea de código que envía elegantemente los datos XD
    intento.putExtra("mensaje", new Mensaje(recipienteMensaje.getText().toString(),
        recipienteNombre.getText().toString()));

Ahora recibiremos los datos desde el Invocador. Cuando una actividad finaliza con un código de request, dispara un evento que es recibido por el AppCompatActivity que lo invocó mediante el método onActivityResult.

Este evento es disparado independientemente del tipo de request, o de que el resultado de la actividad haya fracasado o tenido éxito. Por lo que debemos verificar nosotros mismos el éxito de la actividad, y verificar si el pedido del mensaje es el deseado.

    final static int PEDIDO_DE_MENSAJE = 1;

    // ...

    @Override
    public void onActivityResult (int pedido, int resultado, Intent datos) {
        if (pedido == PEDIDO_DE_MENSAJE) { // tanto pedido como PEDIDO_DE_MENSAJE son numeritos
            // pero es buena práctica ponerle nombre a estos numeritos en vez de llamarlos
            // por su numerito XD
            if (resultado == RESULT_OK) {
                TextView recipiente = (TextView) findViewById(R.id.recibido);

                // apetitosa linea de código que recibe elegantemente los datos XD
                Mensaje recibido = (Mensaje) datos.getSerializableExtra("mensaje"); 

                recipiente.setText("[" + recibido.remitente + "]: " + recibido.contenido);
            }
        }
    }

 

Advertisements

qeqe’s development story

First of all, english is not my main language, so if you are a spanish speaker, you might rather read this spanish version, if you are not a spanish speaker… well… i am really sorry about the grammatical-heresy you are about to read ^^’

I am sleepy.. it’s 1:25 am. 16 hours ago I started to develop the undo and the reset of the levels. 12 hours ago, I decided to make a teaser, and started to design the levels. 1 hour ago I finished recording the teaser’s gameplay. 31 minutes ago i finished doing the last modifications to the executable. 20 minutes ago, i created the qeqe’s itch.io page, and finished uploading the youtube video. 3 minutes ago, i decided to write this blog entry, and not to go to sleep until it is done XD

The year was 2014, I was offered to be part of a gamedev team on the GGJ2014 as an artist. We developed “Dónde estás Pepe?”, and our team was elected as the local winner, besides of that, i was not happy with the result. I am a programmer, not an artist… I love to code! but the times i can be a programmer on a gamedeving team are really scarce .__. so, after the GGJ2014, i decided it: “I am going to learn to be a programmer of videogames”.

I already knew how to code, but I only coded algorithms, printing and reading from the console. By then, i didn’t know to code on javascript. When i was a kid, i used to play games from newgrounds all the time, so I decided to develop games for web with phaser.

I spent a whole year spanking my head on the desk, trying to learn phaser, and every time I found a problem, i didn’t know if the problem was because of my lack of knowledge on javascript, or because of my noobness on phaser, or because of a bug on phaser, or because of a bug on my logic D’: those were harsh months.

Three months remaining for the GGJ2015 I decided to make my first game: a global warming game as a global game jam warming, which is a game about global warming that i made as a warming for the global game jam XD

but.. what about qeqe? well…

The original game of qeqe was SpiderDog. I created qeqe, because i wanted to learn to play with gravity in platform games. So i decided to make a game about a dog that could climb the walls and the roofs, just like a spider! but in order to achieve that, i needed to learn to use tilemaps.

As it was only a game created with the objective of teaching myself to play with gravity in games, i really didn’t focused much on the art… I made a dog with sticks lol.

I had a really good time learning to use tilemaps… so i decided to let qeqe dig holes on the tilemaps, so he could modify it’s environment.

I developed an algorithm that made the borders of the dirt to smartly fit depending on it’s neighbors, so that the dirt doesn’t looked like overlapped every time qeqe made a hole. And that was it! qeqe was able to make holes on the tilemap.

It was kind of boring though. Qeqe needed a motivation for making holes… is there a better motivation for a dog to make holes than finding bones? well… that’s how the bones were born.

But… if the bones are hidden, then qeqe is gonna have a hard time finding them… and that’s how the bone tracking was born XD

I think it took me 3 or 2 weeks to develop qeqe. I really didn’t put a lot of effort on him, but every time i make my friends play my games, qeqe is the game they like the most!

and that’s why i decided to continue it’s development, so more people can enjoy it :D

so, if you want to play the teaser, plase, download it from here: https://vengadoravg.itch.io/qeqe

And if you get stuck on the teaser, there is a little walkthrough i made: https://youtu.be/W1NdabKynNY

aaaand if you want to play SpiderDog, (the original version of qeqe) you can do so right here: http://vengadoravg.github.io/qeqe/index.html

as qeqe is released under the GPLv3.0, you can also explore it’s source code and clone the project! https://github.com/VengadoraVG/qeqe

Well… it is already 2:30 am, and i am really, really sleepy now… so… good nights~!

La historia de qeqe

Estoy con algo de sueño… es la 1:25 am. Hace 16 horas comencé a programar el undo y reset de niveles. Hace 12 horas me decidí a hacer un teaser y comencé a diseñar los niveles. Hace 1 hora terminé de grabar el gameplay del teaser de qeqe, hace 31 minutos terminé de hacer las últimas modificaciones al ejecutable. Hace 20 minutos creé su página en itch.io y subí el video a youtube. Hace 3 minutos, me decidí a escribir esta entrada de blog, y no irme a dormir hasta que esté terminada XD

Era el 2014, y me ofrecieron participar como artista en un equipo de gamedevs para el GGJ2014. Fue allí cuando nació “Dónde estás Pepe”, en esa ocasión nuestro equipo resultó ganador! pero yo no estaba conforme, yo soy una programadora, no una artista… me encanta programar! pero las ocasiones en las que realmente puedo desempeñar ese rol son muy contadas .__. así que, después del GGJ2014 lo decidí: “voy a aprender a programar videojuegos”.

Por entonces, yo ya sabía programar, pero solo algoritmos, imprimiendo y leyendo datos de la consola, no sabía nada de javascript. Grandemente influenciada por los juegos que jugaba día tarde y noche en newgrounds, decidí desarrollar juegos para el navegador, y fue allí cuando conocí a phaser :D

pasé todo un año rompiéndome la cabeza, intentando aprender phaser, y cada vez que me topaba con un problema, no sabía si el problema era a causa de mi ignorancia de javascript, o a causa de mi ignorancia de phaser, o un bug de phaser, o un bug en mi código D’: fueron meses difíciles.

No fue hasta que faltaran tres meses para el GGJ2015 que me decidí a hacer mi primer juego: a global warming game as a global game jam warming, es un juego que hice como calentamiento para el global game jam del 2015.

pero… “dónde está qeqe?” XD bueno… aquí es donde entra qeqe:

El primer nombre de qeqe fue SpiderDog, y nació porque, yo quería jugar con la gravedad en phaser XD, quería hacer el juego de un perrito que pudiera trepar por las paredes como si fuera una araña… pero para lograr desarrollar eso, tenía que aprender a usar tilemaps!

Como sólamente era un juego, cuyo objetivo era que yo aprendiera a jugar con la física, no me enfoqué mucho en el arte… hice un perro de palitos jajaja.

Aprendiendo a usar tilemaps, vi que era super divertido… y pensé que sería muy divertido hacer que qeqe (por entonces spiderdog) pudiera hacer agujeros y modificar el tilemap.

Desarrollé un algoritmo, un tanto rudimentairo, para que los bordes de los tiles se acomodaran inteligentemente, y no se viera “feo” o “sobrepuesto” cada vez que hicieras un agujero en el tilemap, y listo! qeqe ya podía hacer agujeros.

Pero era medio aburrido, qeqe necesitaba un propósito para hacer agujeros… ¿y qué mejor motivación necesita un perro para hacer agujeros que encontrar huesos? bueno… así nacieron los huesos.

Pero si los huesos están ocultos, a qeqe le va a costar mucho encontrarlos… y así nació el rastreo de huesos XD

Si no recuerdo mal, desarrollar a qeqe me tomó 3 ó 2 semanas. Fue un juego rápido. Pero, siempre que le hago jugar a mis amigos mis juegos, qeqe es el juego que más les gusta!

Recientemente, en este año (2017), fuimos invitados como Ancestral Gods por Rodrigo Goyzueta a Proyecciones Animé, organizado por Anime Kai para que pudieramos mostrar nuestro trabajo :O así que decidimos preparar dos juegos para mostrarlos en exclusiva allí.

Uno de los juegos fue qeqe. Decidí hacer el port a Unity, estuve unos 3 ó 4 días peléandome con unity para que el juego se “sintiera” tal y como se sentía en su versión de phaser. Al final, lo tenía! una versión de qeqe en unity :D

Y ahora, he implementado una nueva característica: la capacidad de resetear niveles, y de deshacer tus cambios en niveles que hayas destruido.

Si quieres probar el teaser que hice, puedes descargarlo gratis de aquí: https://vengadoravg.itch.io/qeqe (aún no hay versión para mac, ni para linux… no tengo las herramientas para hacer el build, ni megas para descargar esas herramientas DX)

Si te quedas trabado, puedes ver el walkthrough aquí https://youtu.be/W1NdabKynNY

y si quieres jugar SpiderDog (la versión original de qeqe), puedes hacerlo desde aquí: http://vengadoravg.github.io/qeqe/index.html

qeqe ha sido liberado mediante la GPLv3.0 :D así que puedes explorar su código y clonar el proyecto de aquí: https://github.com/VengadoraVG/qeqe

Espero que te guste! :D y recuerda: es solo un teaser, voy a sacar nuevas versiones, y cuando lo haga, voy avisarte, escribiendo una entrada de blog ^__^

Bueno, son las 2:03 am, y me voy a dormir XD

Spritesheets con inkscape mediante layers

Cómo extrañaba programar!!! y cómo extrañaba usar linux!!!!! y ahora que tengo linux y quiero acelarar mi proceso de producción de spritesheets, encuentro la escusa perfecta para programar y usar linux XD

Este pequeño script genera un spritesheet a partir de un archivo svg que tenga los sprites tirados por todas partes en capas!

demo.png

#!/bin/bash

filename="$(echo "$1" | awk -F. '{print $1}')"
h="+"

# ¯\_(ツ)_/¯
if [[ $* == *-v* ]]
then
  h="-"
fi

# readibility counts -python zen
layerList="$(inkscape --query-all $1 | grep layer | awk -F, '{print $1}')"

echo "$layerList" |
  awk -v file="$filename" -v h="$h" '
    {system("inkscape " file ".svg -i " $1 " -j -C --export-png /tmp/" file "-" $1 ".png")} 

    END{system("convert " h "append /tmp/" file "-*.png " file ".png")}

    END{system("rm /tmp/" file "-*.png")}'

Primero, consigue el id de los layers de inkscape,  y los pone en una lista. Itera sobre esta lista, para generar imágenes temporales de cada una de las capas, y luego, usando imagemagick, las concatena, horizontal o verticalmente.

Hice un repo donde voy a ir colando scripts de bash para game development… tal vez lo abandone igual que el resto de mis proyectos lol XD pero… tal vez no o__O igual, si alguien quiere descargar el código, pueden clonarlo desde aquí: https://github.com/VengadoraVG/bash-for-gamedevs

me lo lees?

El español tiene muchas variantes. Considerando que, tal y como descubrió Chomsky, el idioma es el primer puzzle que resolvemos, la forma en la que hablamos el español da muchas pistas sobre la forma en la que pensamos.

El español boliviano es muy diferente al español que hablamos allá en Guatemala, y no solo es por el acento, existen muchas diferencias sintácticas! Consideremos, por ejemplo, la palabra “pero”: en Guatemala, se usa sólamente como conector y al principio de la oración que está conectando:

– Levántate! es hora de ir al colegio
-> pero no quiero ir :'(

En cambio, un boliviano hablaría este diálogo así:

– Levántate! es hora de ir al colegio
-> pero! :'(
o también: no quiero ir, pero :'(

En bolivia la palabra “pero” es como una queja, como una palabra que puede ser usada de manera aislada de la escusa.

Encuentro estas diferencias muy interesantes, porque el español boliviano está fuertemente influenciado por sus ancestros nativos. Entendiendo estas diferencias, podemos darnos cuenta de cosas que nuestros ancestros consideraban tan importantes, usuales y naturales, como para necesitar crear un sonido para expresarlas con frecuencia.

Nosotros heredamos estos modos de hablar, tal y como se hereda una herramienta, y estas ideas ancestrales persisten en nosotros y nos permiten transmitir sentimientos complejos que, de no ser por la “corrupción” del lenguaje original, se habrían perdido para siempre.

Pero mi “corrupción del lenguaje” favorita, es la anteposición de “me” a ciertas oraciones imperativas. Por ejemplo: “me lo vas a cuidar”, “me lo vas a llevar”, “me lo vas a dar comida”.

En las oraciones imperativas, observamos a tres actores principales: el que recibe la orden “el oyente”, el que da la orden “el autor” y la acción que se comanda, le llamaremos “la orden”.

Yo veo a esta corrupción del lenguaje, sintácticamente hablando, como si la orden fuera propiedad del autor, y da a conocer un lazo afectivo entre el autor y la orden, que hacen que el oyente transfiera un poco del aprecio que siente por el autor hacia la orden.

Es como decirle, de una forma corta: “es mío, así que cuídalo”, o “hazlo por mi”, o “ya sea que decidas obedecer o desobedecer mi orden, también me va a afectar a mi, de una forma personal.”.

Podría nombrar otra gran cantidad de diferencias sintácticas entre el español que yo hablaba en Guatemala, y el español que hablamos aquí, pero sólamente quería compartir mis experiencias con esta última corrupción del lenguaje, así que… es todo… Chau, se me van a cuidar!

Instalación de Dios al 89%

Podías encontrar en el ciberespacio infinidad de ofertas laborales, y entre los requerimientos siempre estaría la instalación de neurosoftware de control laboral, y con letras pequeñas, la afiliación de más de 1 año a alguna religión.

El ciberministerio de credos y dogmas, realiza constantemente un control estricto sobre cualquier neurosoftware, penalizando severamente a todo aquel que fabrique uno que rompa las reglas. Sus reglas eran muy severas con el neurosoftware de control laboral. Pero ambiguas y escuetas con frameworks de creencias religiosas. La religión era un área difícil de regular, debido a la libertad de culto que figuraba en la DUDH.

Y es por eso que actualmente, la única forma de conseguir trabajo, es afiliándose a una secta religiosa, ya que solo así los empleadores podrán sacar el máximo provecho de la mente de sus trabajadores, y pese a que el ciberministerio de credos y dogmas conoce este problema, no hay nada que pueda hacer al respecto, debido al neoliberalismo del mercado moderno, si el gobierno insinuara la regulación de ofertas laborales, el país entero perdería la cabeza, con ataques DDoS que paralizarían toda la producción.

– Fragmento de un libro que tal vez exista en el futuro

Sobre la censura gubernamental

colegial.png

Un gobierno que censura información con la escusa de proteger a sus ciudadanos de información falsa es, por definición, un gobierno deficiente.

Por un lado, si la información censurada fuera verdadera, quiere decir que el gobierno miente. Por lo tanto, el gobierno es corrupto y descarado, dispuesto a atropellar las libertades individuales de sus ciudadanos con fines egoístas.

Por otro lado, si la información censurada es realmente falsa, quiere decir que el gobierno no confía en que sus ciudadanos tengan la madurez intelectual como para discernir entre lo verdadero y lo falso.

Este último escenario es también aterrador, ya que da indicios de que el gobierno no se preocupa por que sus ciudadanos tengan acceso a educación de calidad, ya sea por descuido, o porque es más fácil gobernar a ciudadanos iletrados.

Cuando el internet no era real

Yo soy de esa generación en la que el internet era un club secreto, protegido por un aura friki y escondido por el temor al rechazo, alimentado por la soledad y fortificado por el anonimato.

En aquellos tiempos, si amenazabas a alguien con matarlo argumentando que sabías en dónde vive por algún artilugio informático, él se reiría en tu cara con un estruendoso LOL seguido de “se nota que estamos en verano”, y si alguien decía que cometería un atentado terrorista, su comentario se perdería entre otros tantos comentarios incentivando actos de odio, mismos que nunca serían materializados, pero aliviarían la ira de sus autores.

Yo pertenezco a un lugar en el que todos hablábamos tonterías, y nos reiríamos de las tonterías que los demás decían. Pertenezco a una familia intangible, inestable, virtual. Pertenezco a una comunidad de inadaptados, marginados por su timidez. Pertenezco a una hermandad que, pese a su aparente intolerancia, recibía con calidez a los newbies, una calidez que solo personas de nuestra calaña podría comprender.

Vengo de un internet en el que lo que decíamos nunca se materializaría en acciones, solamente en pensamientos, un internet en el que lo que decíamos era un reflejo real de nuestros pensamientos más profundos, y hablábamos sin miedo, porque entre frikis nos entendíamos, y nadie perdería su tiempo leyendo nuestras conversaciones. A quién le importaba por entonces lo que pensaran un montón de inadaptados?

En el mundo real, nos entristecíamos de que nadie nos entendiera, pero cuando nos juntabamos, nos enorgullecíamos de que así fuera. Entre nosotros, no existía el miedo a ser tachado de machista, racista o psicópata, porque, en el fondo, sabíamos que solo bromeábamos, pero a veces hablábamos en serio, cuestionando todos nuestros dogmas. Si alguna vez metías la pata, solamente te creabas otra identidad y comenzabas de nuevo, re-integrarse nunca era difícil.

Yo soy de esos tiempos… esos tiempos en los que el internet no era real. Pero ahora, en dónde está ese lugar? en dónde está esa gente y sus retorcidos pensamientos? en dónde quedó nuestro búnker secreto?