Guía definitiva para el lenguaje de procesamiento Parte I: los fundamentos

Publicado: 2022-03-11

Estás luchando contra el aburrimiento y ansioso por usar tu creatividad. Quieres construir algo, algo visualmente impresionante, algo artístico. O tal vez quieras aprender a programar y hacer algo impresionante lo antes posible. Si es así, entonces el lenguaje de procesamiento es el camino a seguir.

Entre todos los lenguajes de programación con los que he trabajado hasta ahora, Processing fue sin duda uno de los más divertidos. Es un lenguaje directo, fácil de aprender, entender y usar, pero es muy poderoso. Es casi como si estuvieras pintando en un lienzo vacío con líneas de código. No existen reglas rígidas ni pautas que limiten tu creatividad, el único límite es tu imaginación.

Guía definitiva para el lenguaje de procesamiento Parte I: Los fundamentos

En la universidad fui asistente de enseñanza de un programa que reunía a estudiantes de secundaria y les enseñaba Processing. La mayoría de ellos no tenían una sólida formación en programación, algunos ni siquiera habían escrito una sola línea de código antes. En solo cinco días, se esperaba que aprendieran el idioma y crearan sus propios juegos simples. La tasa de éxito fue casi del cien por cien, rara vez nos enfrentamos al fracaso. En este artículo, esto es exactamente lo que haremos. Reduje todo el programa en dos partes. Primera parte, estaré hablando del lenguaje. Daré una descripción general básica, un recorrido por el procesamiento y daré algunos consejos y trucos. Luego, en la siguiente parte, construiremos un juego simple paso a paso, cada paso se explicará en detalle. También convertiré el código del juego a JavaScript usando p5js, para que nuestro juego pueda ejecutarse en un navegador web.

Lo que ya deberías saber

Para comprender y seguir fácilmente estos artículos, debe tener un conocimiento básico de programación, ya que no hablaré sobre los fundamentos de la programación. Sin embargo, en su mayoría no tocaré ningún concepto de programación avanzada, por lo que una comprensión superficial será suficiente. Hay algunas partes en las que hablo sobre algunas ideas y conceptos de bajo nivel, como la programación orientada a objetos (POO), pero no son cruciales. Esos son para lectores curiosos que estén interesados ​​en la estructura del idioma. Si no quieres saberlo, puedes omitir esas partes. Aparte de eso, ¡lo único que deberías tener es la ambición de aprender este increíble idioma y el entusiasmo por crear tu propio juego!

Cómo seguir

Siempre estoy a favor de aprender a programar probando y experimentando. Cuanto antes te sumerjas en tu propio juego, más rápido te sentirás cómodo con Processing. Así que esa será mi primera sugerencia, pruebe todos y cada uno de los pasos en su propio entorno. Processing tiene un IDE simple y fácil de usar (es decir, un editor de código), es lo único que necesitará descargar e instalar para seguir. Puedes descargarlo desde aquí.

¡Entonces empecemos!

¿Qué es el lenguaje de procesamiento?

Esta sección incluye una breve descripción técnica del lenguaje, su estructura y algunas notas sobre el proceso de compilación y ejecución. Los detalles incluirán algunos conocimientos avanzados sobre programación y el entorno Java. Si no te importan los detalles por ahora y no puedes esperar para aprender y programar tu propio juego, puedes saltar a la sección "Fundamentos del procesamiento".

El procesamiento es un lenguaje de programación visual que le permite dibujar con códigos, por así decirlo. Sin embargo, no es exactamente un lenguaje de programación en sí mismo, es lo que ellos llaman un lenguaje de programación "Java-esque", lo que significa que el lenguaje está construido sobre la plataforma Java, pero no es exactamente Java per se. Se basa en Java y todo su código se procesa previamente y se convierte directamente en código Java cuando presiona el botón Ejecutar. La clase PApplet de Java es la clase base para todos los bocetos de Processing. Para dar un ejemplo, tomemos un par de bloques de código de procesamiento básico:

 public void setup() { // setup codes goes here } public void draw() { // draw codes goes here }

Estos bloques de código se convertirán en algo como esto:

 public class ExampleFrame extends Frame { public ExampleFrame() { super("Embedded PApplet"); setLayout(new BorderLayout()); PApplet embed = new Embedded(); add(embed, BorderLayout.CENTER); embed.init(); } } public class Embedded extends PApplet { public void setup() { // setup codes goes here } public void draw() { // draw codes goes here } }

Puede ver que el bloque de código de procesamiento se envolvió con una clase que se extiende desde el PApplet de Java. Por lo tanto, todas las clases que defina en su código de procesamiento, si las hay, serán tratadas como clases internas.

El hecho de que Processing esté basado en Java nos da muchas ventajas, especialmente si eres un desarrollador de Java. La sintaxis no solo es familiar, sino que también le brinda la capacidad de hacer cosas como incrustar código Java, bibliotecas, archivos JAR en sus bocetos, usar sus subprogramas de procesamiento directamente en sus aplicaciones Java, definir clases y usar tipos de datos estándar como int , flotar, char y así sucesivamente. Incluso puede escribir su código Pocessing directamente desde Eclipse, si desea dedicar algo de tiempo a configurarlo. Una cosa que no puede hacer es usar componentes AWT o Swing en sus bocetos de Processing, porque entran en conflicto con la naturaleza de bucle de Processing. Pero no se preocupe, no haremos nada de eso en este artículo.

Fundamentos del Procesamiento

El código de procesamiento consta de dos partes principales, configuración y bloques de dibujo . El bloque de configuración se ejecuta una vez cuando se ejecuta el código, y los bloques de dibujo se ejecutan continuamente. La idea principal detrás de Processing es que lo que escriba dentro del bloque de dibujo se ejecutará 60 veces por segundo de arriba a abajo, hasta que su programa finalice . Construiremos todo aprovechando esta esta misma idea. Haremos que nuestros objetos se muevan, mantendremos nuestras puntuaciones, detectaremos colisiones, implementaremos la gravedad y haremos casi todo lo demás con esta función. Este ciclo de actualización es el latido del corazón de nuestro proyecto . Explicaré cómo usar este latido para dar vida a su código en secciones posteriores. Primero, déjame presentarte el IDE de procesamiento.

IDE de procesamiento

Si ha leído hasta este punto y aún no ha descargado el IDE de procesamiento, continúe y hágalo. A lo largo del artículo, describiré algunas tareas sencillas para que pruebe por su cuenta, solo puede practicar si tiene el IDE en funcionamiento. Aquí hay una breve introducción del IDE de procesamiento. Es muy simple y se explica por sí mismo, así que seré breve.

Como era de esperar, los botones ejecutar y detener hacen lo que sugieren. Cuando hace clic en el botón ejecutar , su código se compilará y ejecutará. Por naturaleza, los programas de procesamiento nunca terminan, se ejecutan eternamente hasta que se interrumpen. Puede finalizarlo mediante programación; sin embargo, si no lo hace, puede usar el botón de detención .

El botón que parece una mariposa a la derecha de ejecutar y detener es el depurador . El uso del depurador necesita otro artículo completo dedicado a él. Está fuera del alcance de este artículo, por lo que puede ignorarlo por ahora. El menú desplegable al lado del botón del depurador es donde agrega/establece mods. Los mods le brindan cierta funcionalidad, le permiten escribir código para Android, le permiten escribir código en Python, y así sucesivamente. Los mods también están fuera del alcance, por lo que puede mantenerlo en el modo Java predeterminado e ignorarlo también.

La ventana del editor de código es donde normalmente se ejecutan los bocetos. En la imagen está en blanco, porque no hemos puesto ninguna propiedad como tamaño o color de fondo, o no hemos dibujado nada.

No hay mucho que hablar sobre el editor de código, es simplemente donde escribes tu código. Hay números de línea (!) Las versiones anteriores de Processing no tenían eso y no puedes imaginar lo feliz que estaba cuando los vi por primera vez.

El recuadro negro de abajo es la consola . Lo usaremos para imprimir cosas con fines de depuración rápida. La pestaña de errores al lado de la consola es donde aparecerán sus errores. Esta es también una nueva característica útil que viene con Processing 3.0. En las versiones anteriores, los errores se imprimían en la consola y era difícil hacer un seguimiento de ellos.

Bloque de configuración

Como se indicó anteriormente, los bloques de configuración se ejecutan una vez cuando se inicia el programa. Puedes usarlo para hacer configuraciones y para cosas que te gustaría ejecutar solo una vez, por ejemplo, cargar imágenes o sonidos. Aquí hay un bloque de configuración de ejemplo. Ejecute este código en su propio entorno y vea los resultados por sí mismo.

 public void setup() { // Size of our sketch will be 800x600, // and use the P2D rendering engine. size(800, 600, P2D); // We could have used this function instead of size() // fullScreen(P2D); // The background color of our sketch will be black // by default, unless specified otherwise background(0); // We could have used this to set a background image. // Note that size of our sketch should be the same as the image. // background(loadImage("test.jpg")); // Shapes and objects will be filled with red by default, // unless specified otherwise. fill(255,0,0); // Shaped and objects will have a white border by default, // unless specified otherwise. stroke(255); }

Los métodos relacionados con el estilo (fondo, relleno, trazo) se explicarán en las secciones de propiedades y configuración. Por ahora, lo que necesita saber es cómo los ajustes y configuraciones que establecemos aquí afectan todo nuestro boceto. Los códigos escritos aquí se utilizan para establecer algunos conjuntos de reglas básicos aplicables a lo largo del boceto. Lo que también debe comprender en esta sección son los métodos que se enumeran a continuación:

size() - Como su nombre indica, esta función se utiliza para configurar el tamaño de nuestro boceto. Tiene que estar en la primera línea del bloque de código de configuración. Podría ser utilizado en las siguientes formas:

  • tamaño (ancho, alto);
  • tamaño (ancho, alto, renderizador);

Los valores de ancho y alto se pueden dar en píxeles. La función de tamaño acepta un tercer parámetro, el renderizador, que se usa para establecer qué motor de renderizado usará nuestro boceto. De forma predeterminada, el renderizador está configurado en P2D. Los renderizadores disponibles son P2D (Procesamiento 2D), P3D (Procesamiento 3D, debe usarse si sus bocetos incluirán gráficos 3D) y PDF (los gráficos 2D se dibujan directamente en un archivo PDF de Acrobat. Puede encontrar más información aquí). Los renderizadores P2D y P3D utilizan hardware de gráficos compatible con OpenGL.

fullScreen() : a partir de Processing 3.0, ahora se puede usar la función fullScreen en lugar de la función size(). Al igual que la función size(), también debería estar en la primera línea del bloque de configuración. El uso es el siguiente:

  • pantalla completa();
  • pantalla completa (pantalla);
  • pantalla completa (procesador);
  • pantalla completa (pantalla, renderizador);

Si lo usa sin ningún parámetro, su boceto de procesamiento simplemente se ejecutará en pantalla completa y se ejecutará en su pantalla principal. El parámetro 'display' se usa para establecer en qué pantalla se ejecutará su boceto. Por ejemplo, si conecta monitores externos a su computadora, puede establecer la variable de visualización en 2 (o 3, 4, etc.) y su boceto se ejecutará allí. El parámetro 'renderer' es como se explica en la parte size() anterior.

Bloque de configuración

Esta es otra característica que se presenta con la nueva versión de Processing. Es un bloque de código, al igual que configurar y dibujar. Es útil cuando desea definir métodos size() o fullScreen() con parámetros variables. También es necesario definir size() y otras propiedades de estilo como smooth() en este bloque de código si está utilizando cualquier entorno que no sea el propio IDE de Processing, como Eclipse. Pero no lo necesitará en la mayoría de los casos, definitivamente no en este artículo.

Dibujar bloque

No hay nada especial que hablar sobre el bloque de dibujo, sin embargo, todo es especial al respecto. Draw block es donde ocurre toda la magia. Es el corazón de su programa, latiendo 60 veces por segundo. Este bloque de código alberga toda la lógica de su código. Todas sus formas, objetos, etc. se escribirán aquí.

La mayor parte del código del que hablaremos en este artículo será del bloque de dibujo, por lo que es importante que comprenda claramente cómo funciona este bloque de código. Para darle una demostración, aquí hay algo que puede probar. Primero tenga en cuenta que podemos imprimir cualquier cosa en la consola usando los métodos print() o println() . Los métodos de impresión solo imprimen en la consola, sin embargo, println imprime y agrega una nueva línea al final, por lo que cada println() se imprimirá en filas separadas.

Entonces, eche un vistazo al siguiente bloque de código. Primero, intente adivinar qué imprimirá en la consola. Entonces, adelante, pruébalo:

 void setup(){ } void draw(){ int x = 0; x += 1; print(x+" "); }

Si adivinaste “1 2 3 4…”, ¡te entendí! Esta es una de las confusiones en Processing. ¿Recuerdas que este bloque se ejecuta repetidamente? Cuando define una variable aquí, se define en cada bucle una y otra vez. En cada iteración, x se establece en 0, se incrementa en 1 y se imprime en la consola. Por lo tanto obtenemos el resultado “1 1 1 1…”. Este ejemplo era algo obvio, pero puede resultar confuso cuando las cosas se complican un poco.

No queremos que x se sobrescriba, entonces, ¿cómo podemos lograr esto y obtener el resultado "1 2 3 4..."? Mediante el uso de variables globales . Esto no es nada sofisticado, solo definimos la variable fuera del bloque de dibujo para que no se vuelva a definir en cada iteración. Además, el alcance de la variable será accesible a lo largo del boceto. Vea el código a continuación:

 int x = 0; void setup(){ } void draw(){ x += 1; print(x+" "); }

Quizás te estés preguntando, ¿cómo puede funcionar una variable definida fuera de nuestros bloques? ¿Y por qué no usamos el bloque setup() ya que se ejecuta una vez al principio? La respuesta está relacionada con la programación y los alcances orientados a objetos, si no está familiarizado, puede omitir este párrafo. Consulte la parte donde expliqué cómo el código de procesamiento se convierte en Java. ¿Recuerdas cómo se envuelven con una clase de Java? Las variables que escribimos fuera del bloque setup() y draw() también se envuelven, por lo tanto, se tratan como campos de la clase externa que envuelve nuestro código. Usar x+=1 es lo mismo que usar this.x+=1. También funciona igual en nuestro caso, no se define ninguna variable llamada x en el alcance de draw() y se busca un alcance externo, que es el alcance de this . ¿Y por qué no definimos nuestra variable x en la sección setup()? Si lo hiciéramos, el alcance del cual se define x sería el alcance de la función de configuración y no sería accesible desde el bloque dibujar().

Dibujar formas y textos

Ahora sabemos cómo configurar nuestro boceto usando el bloque de configuración y sabemos qué hace el bloque de dibujo. Así que es hora de volverse un poco visual y aprender sobre las partes divertidas del procesamiento: cómo dibujar formas.

Antes de comenzar, debe comprender el sistema de coordenadas . En Procesamiento, determina las coordenadas de cada objeto que dibuja en la pantalla. El sistema de coordenadas está en píxeles. El origen (es decir, el punto de partida) es la esquina superior izquierda, debe dar sus coordenadas relativas a ese punto. Otra cosa que debes saber es que cada forma tiene un punto de referencia diferente. Por ejemplo, rect() tiene su esquina superior izquierda como punto de referencia. Para elipse(), es el centro. Estos puntos de referencia se pueden cambiar con métodos como rectMode() y ellipseMode(), que explicaré en la sección de propiedades y configuraciones. Se proporciona una figura de ejemplo para ayudarlo a comprender mejor.

Este artículo es una descripción general básica del procesamiento, por lo que no tocaremos formas complejas como vértices o formas 3D. Las formas 2D básicas en realidad serán más que suficientes para que podamos crear nuestro propio juego. En la figura, puede ver ejemplos de cómo se dibujan las formas. Cada forma tiene su propia sintaxis para ser creada, pero la idea básica es dar sus coordenadas o sus tamaños o ambos. Aquí hay algunas formas con las que debería estar familiarizado (para todos los valores dados a continuación, 'x' e 'y' significan coordenadas x e y en píxeles, 'w' y 'h' significan valores de ancho y alto también en píxeles):

point () - Punto simple, solo necesita una sola coordenada. Uso:

  • punto (x, y)
  • punto (x, y, z) - En caso de que esté utilizando 3 dimensiones.

line() - Para crear una línea. Puede crear una línea con solo un punto inicial y final. Uso:

  • línea (x1, y1, x2, y2)
  • línea (x1, y1, z1, x2, y2, z2) - En caso de que esté usando 3 dimensiones.

triangulo() - Para crear un triangulo. Uso: triángulo (x1, y1, x2, y2, x3, y3)

quad() - Para crear un cuadrilátero. Uso: cuádruple (x1, y1, x2, y2, x3, y3, x4, y4)

rect() - Para crear un rectángulo. El punto de referencia es la esquina superior izquierda por defecto (consulte la figura). Aquí está el uso:

  • rect(x, y, w, h)
  • rect(x, y, w, h, r) - 'r' significa el radio en píxeles para redondear las esquinas.
  • rect(x, y, w, h, tl, tr, br, bl) - Radio para las esquinas superior izquierda, superior derecha, inferior derecha, inferior izquierda respectivamente. Esto también está en píxeles.

ellipse() - Para crear una forma de elipse. Esto también se usa para crear un círculo, se deben dar los mismos valores de ancho y alto. El punto de referencia para esta forma es el centro por defecto (consulte la figura). Aquí está el uso:

  • elipse(x, y, w, h)

arc() - Dibujar un arco. Uso:

  • arc(x, y, w, h, start, stop) - 'start' y 'stop' se usan para determinar el ángulo para comenzar y detener el dibujo del arco. Los valores están en radianes. Se pueden utilizar constantes como “PI, HALF_PI, QUARTER_PI y TWO_PI”.
  • arc(x, y, w, h, start, stop, mode) - La variable 'mode' es para determinar el estilo de representación del arco (cadena). Las opciones disponibles son “OPEN, CHORD, PIE”. ABIERTO dejará las partes no dibujadas sin bordes. CHORD completará las partes no dibujadas con un borde. PIE hará que su arco se vea como un gráfico circular.

Mostrar textos en la pantalla es similar a mostrar formas, la idea básica es que usted determina una coordenada en la que desea que se muestre su texto. Sin embargo, hay más en el manejo de textos. Tendrá más control sobre sus textos después de la sección de propiedades y configuraciones, donde aprenderá cómo aplicar configuraciones y propiedades a los objetos. Por ahora, mostraré los conceptos básicos de visualización de textos. Hay muchas formas de hacerlo, solo mostraré las esenciales.

text() - Mostrar textos. Uso:

  • text(c, x, y) - 'c' significa carácter, se mostrará cualquier carácter alfanumérico.
  • text(c, x, y, z) - En caso de que esté trabajando con 3 dimensiones.
  • text(str, x, y) - 'str' es la cadena que se mostrará.
  • text(str, x, y, z) - En caso de que esté trabajando con 3 dimensiones.
  • text(num, x, y) - 'num' es el valor numérico que se mostrará.
  • text(num, x, y, z) - En caso de que esté trabajando con 3 dimensiones.

Propiedades y configuración

Lo primero que debe explicarse en esta sección sería la lógica detrás de la configuración de las propiedades de los objetos. El color de relleno, el color de fondo, el borde, el ancho del borde, el color del borde, la alineación de las formas, los estilos de borde, etc. podrían ser algunos ejemplos de estas propiedades.

Cuando establece una propiedad, debe recordar que el código se ejecutará de arriba a abajo . Digamos que establece la propiedad de "relleno" en rojo, todos los objetos dibujados debajo de esa línea se rellenarán con rojo hasta que se sobrescriba con otra propiedad de relleno. Lo mismo se aplica a otras propiedades, sin embargo, tenga en cuenta que no todas las propiedades se sobrescribirán entre sí. Por ejemplo, la propiedad "trazo" no sobrescribe la propiedad "relleno", sino que funcionan juntas. Aquí hay una representación visual para que comprendas la lógica:

Como puede ver en la imagen, la primera línea establece el color de relleno en rojo y la segunda línea establece el color del trazo en azul. Ahora tenemos dos configuraciones activas: rellenar trazos rojos y azules. Como era de esperar, cualquiera que sea nuestro objeto en la siguiente línea, se llenará de rojo y tendrá trazos azules (si corresponde). Puedes seguir examinando la imagen de esta manera y captarás la lógica.

Aquí hay algunas propiedades y configuraciones esenciales que se usan comúnmente:

Ajustes de estilo

fill() - Establece el color de relleno de los objetos. Esta configuración también se utiliza para colorear textos. Por ahora, solo necesitamos saber el siguiente uso:

  • fill(r, g, b) - Valores de rojo, verde y azul como enteros
  • fill(r, g, b, a) - Valor alfa adicional, el máximo es 255

noFill() - Establece el color de relleno en transparente.

stroke() - Establece el color del trazo a los objetos. La propiedad de trazo se aplica a líneas y bordes alrededor de objetos. Por ahora, solo necesitamos saber el siguiente uso:

  • stroke(r, g, b) - Valores de rojo, verde y azul como enteros.
  • carrera (r, g, b, a) - Valor alfa adicional, el máximo es 255

noStroke() - Elimina el trazo.

strokeWeight() - Establece el ancho del trazo. Uso:

  • strokeWeight(x) - x es un número entero y representa el ancho del trazo en píxeles.

background() - Establece el color de fondo. Por ahora, solo necesitamos saber el siguiente uso:

  • background(r, g, b) - Valores de rojo, verde y azul como enteros.
  • background(r, g, b, a) - Valor alfa adicional, el máximo es 255

Configuración de alineación

ellipseMode() - Establece dónde tomar como punto de referencia alineando elipses. Uso:

  • ellipseMode(modo) - 'modo' es el parámetro, aquí están los parámetros disponibles:
    • CENTRO (predeterminado): Toma el centro como punto de referencia.
    • RADIO: Esto también toma el centro como punto de referencia, pero en este modo, los valores de w y h que especifique se tratan como la mitad (es decir, radio en lugar de diámetro)
    • ESQUINA: Toma la esquina superior izquierda como punto de referencia.
    • ESQUINAS: Establece los dos primeros parámetros (x e y) como la ubicación de la esquina superior izquierda y los últimos dos parámetros (w y h) como la ubicación de la esquina inferior izquierda de la elipse. Entonces este modo, "ancho" y "alto" es irrelevante. Pensarlo como una elipse (x_tl, y_tl, x_br, y_br) tiene más sentido en este caso.

rectMode() - Establece dónde tomar como punto de referencia los rectángulos de alineación. Uso:

  • rectMode(modo) - 'modo' es el parámetro, aquí están los parámetros disponibles:
    • CENTRO: Toma el centro como punto de referencia.
    • RADIO: Esto también toma el centro como punto de referencia, pero en este modo, los valores de w y h que especifique se tratan como la mitad
    • ESQUINA (predeterminado): toma la esquina superior izquierda como punto de referencia.
    • ESQUINAS: Establece los dos primeros parámetros (x e y) como la ubicación de la esquina superior izquierda y los últimos dos parámetros (w y h) como la ubicación de la esquina inferior izquierda de la elipse. Entonces este modo, "ancho" y "alto" es irrelevante. Pensarlo como rect(x_tl,y_tl,x_br,y_br) tiene más sentido en este caso.

Ajustes relacionados con el texto

textSize() - Establece el tamaño de fuente del texto. Uso:

  • textSize(tamaño) - Valor entero del tamaño deseado.

textLeading() - Establece la altura de línea de sus textos. Uso:

  • textLeading(lineheight) - Valor de píxel del espacio entre líneas.

textAlign() - Establece dónde tomar como punto de referencia los textos alineados. Uso.

  • textAlign(alignX) - 'alignX' es para la alineación horizontal. Disponible: IZQUIERDA, CENTRO, DERECHA
  • textAlign(alignX, alignY) - 'alignY' es para la alineación vertical. Disponible: ARRIBA, ABAJO, CENTRO, LÍNEA DE BASE.

animaciones

Hasta ahora, hemos aprendido a dibujar objetos y textos. Pero el problema con ellos es que son estáticos. Ahora, ¿cómo hacemos que se muevan? Simple, en lugar de dar las coordenadas como números enteros, usamos variables para que podamos incrementarlas/decrementarlas . ¿Tener sentido? Echa un vistazo al siguiente código:

 // initialize x and y as 0 int x=0; int y=0; void setup(){ size(800,600); background(255); // set background color to white } void draw(){ fill(255,0,0); // fill color red stroke(0,0,255); // stroke color blue ellipseMode(CENTER); // ref. point to ellipse is its center ellipse(x, y, 20, 20); // draw the ellipse // increment x and y x+=5; y+=5; }

¿Ves cómo manejamos la animación? Establecemos x e y como variables globales y su valor inicial en 0. En nuestro bucle de dibujo, creamos nuestra elipse, configuramos el color de relleno en rojo, el color del trazo en azul y las coordenadas en x e y. Cuando incrementamos x e y, la pelota simplemente cambia su ubicación. Pero hay un problema con este código, ¿puedes notarlo? Como un desafío fácil para usted, trate de averiguar cuál es el problema y pruébelo. Aquí está el resultado:

Mi intención al permitir que esto sucediera era que se dieran cuenta de cómo funciona la naturaleza cíclica de Processing. Consulte el ejemplo en la sección "Dibujar bloque", ¿recuerda por qué obtuvimos "1 1 1 ..." en lugar de "1 2 3 ..."? La misma razón por la que la pelota va dejando marcas atrás. Cada vez que el bloque de dibujo itera, x e y se incrementan en 5 y, por lo tanto, la bola se vuelve a dibujar a 5 píxeles hacia abajo y hacia la derecha. Sin embargo, la bola extraída de las iteraciones anteriores permanece en la vista. ¿Cómo hacemos para que desaparezcan? ¿Alguna suposición?

Para deshacernos de las marcas que deja la bola, simplemente eliminamos el fondo (255) del bloque de configuración y lo pegamos para que sea la primera línea del bloque de dibujo. Cuando nuestro código de fondo estaba en el bloque de configuración, se ejecutó una vez al principio, haciendo que nuestro fondo fuera blanco. Pero eso no es suficiente, lo necesitamos para establecer nuestro fondo en blanco en cada bucle para cubrir las bolas extraídas de los bucles anteriores. El fondo siendo la primera línea significa que se ejecuta primero, se convierte en la capa base. En cada bucle, nuestro lienzo se pinta de blanco y se dibujan nuevos elementos sobre el fondo blanco. Así que no tenemos marcas.

Esa es la idea detrás de animar cosas en Processing, manipular las coordenadas de los objetos mediante programación para cambiar su ubicación. Pero, ¿cómo haremos cosas sofisticadas, como mantener la pelota en la pantalla? ¿O tal vez implementar la gravedad? Enseñaré cómo hacer esto en la siguiente parte de este artículo. Aprenderemos probando y construyendo. Aprenderemos cómo hacerlo y aplicarlos a nuestro juego de inmediato. Al final, tendremos un juego completo, jugable y, con suerte, divertido.

Interacciones de teclado y mouse

Las interacciones del teclado y el mouse en Processing son muy fáciles y directas. Hay métodos a los que puede llamar para cada evento, y lo que escriba dentro se ejecutará una vez que ocurra el evento. También hay variables globales como mousePressed y keyPressed que puede usar en su bloque de dibujo para aprovechar el bucle. Estos son algunos de los métodos con explicaciones:

 void setup() { size(500, 500); } void draw() { if (mousePressed) { // Codes here will be executed as long as the mouse // button is pressed if (mouseButton == LEFT){ // This lines will be executed as long as // the clicked mouse button is the left mouse // button. } } if (keyPressed) { // Codes here will be executed as long as a key // on the keyboard is pressed if (key == CODED) { // This if statement checks if the pressed key // is recognised by Processing. if (keyCode == ENTER) { // This lines will be executed if the pressed key // is the enter key. } } else{ // This lines will be executed if the pressed key // is not recognised by processing. } } } void mousePressed() { // These codes will be executed once, when mouse // is clicked. Note that mouseButton variable is // also be used here. } void keyPressed() { // These codes will be executed once, when a key // is pressed. Note that key and keyCode variables // are also usable here. }

Como puede ver, es bastante fácil verificar si se hace clic con el mouse o qué tecla se presiona. Sin embargo, hay más opciones disponibles para las variables mousePressed y keyCode. Las opciones disponibles para mousePressed son IZQUIERDA, DERECHA y CENTRO. Hay muchos más disponibles para keyCode ; ARRIBA, ABAJO, IZQUIERDA, DERECHA, ALT, CONTROL, MAYÚS, RETROCESO, TAB, ENTRAR, VOLVER, ESC y ELIMINAR.

Una cosa que debe saber acerca de las variables del mouse, y que usaremos mucho, es cómo obtener las coordenadas del mouse. Para obtener las coordenadas exactas del cursor, podemos usar las variables mouseX y mouseY directamente en el bloque draw(). Por último, pero no menos importante, hay muchos otros métodos útiles que deberías echar un vistazo. Todos ellos están documentados en la Referencia de procesamiento.

Conclusión

Ya debería estar familiarizado con el procesamiento. Sin embargo, si te detienes aquí, todo este conocimiento se irá volando . Te recomiendo encarecidamente que sigas practicando, jugando con lo que has aprendido. Para ayudarte a practicar, te proporcionaré dos ejercicios. Debe hacer todo lo posible para hacerlo por su cuenta. Si te quedas atascado, Google y Processing Reference deberían ser tus mejores amigos. Proporcionaré el código para el primero, pero mirarlos debería ser lo último que haga.

Ejercicio recomendado 1

Debes hacer 4 bolas con diferentes colores , comenzando desde las 4 esquinas de la pantalla viajando por el centro con diferentes velocidades . Cuando hace clic y mantiene presionado el botón del mouse, las bolas deben congelarse . Y al soltar el ratón, las bolas podrían volver a su posición inicial y seguir moviéndose. Entonces, estoy buscando algo como esto.

Después de probar el ejercicio usted mismo, puede consultar el código aquí.

Ejercicio recomendado 2

¿Recuerdas el famoso salvapantallas de DVD en el que el logotipo del DVD rebota por la pantalla y todos esperábamos desesperadamente que llegara a la esquina? Quiero que repliques ese protector de pantalla, pero solo usando un rectángulo en lugar del logotipo del DVD. Cuando inicia la aplicación, la pantalla debe estar en negro y el rectángulo debe comenzar en una ubicación aleatoria. Cada vez que el rectángulo toca la esquina, debe cambiar de color (y obviamente de dirección). Cuando mueva el mouse, el rectángulo debería desaparecer y el color de fondo debería volverse blanco (es un protector de pantalla, ¿no?). No daré el código para este ejercicio en este artículo. Debe hacer todo lo posible para implementarlo, y el código se proporcionará en la segunda parte de este artículo.

Se ha publicado la segunda parte de la guía definitiva de procesamiento, un tutorial paso a paso para crear un juego sencillo.


Lecturas adicionales en el blog de ingeniería de Toptal:

  • Cómo abordar la escritura de un intérprete desde cero