Multiplayer Gameshow Buzzer - Teil 2 - Spielererweiterung und Updates

En los comentarios de la primera publicación sobre el Zumbador de programa para Juegos Multijugador, los usuarios preguntaron cómo expandir la configuración de 4 a 8 jugadores. Esta pregunta y algunas otras sugerencias de pequeñas actualizaciones me han hecho escribir una segunda parte. Utilizo la gestión de memoria dinámica, de modo que la cantidad de jugadores se puede elegir libremente entre 1 y (inclusive) 12. También expongo que no necesariamente se debe inicializar los pines de entrada en la rutina  setup() y también agrego algunos trucos que requieren de mayor esfuerzo por parte del jugador. Comencemos.

Lo que necesitamos

número

Componente

1

Nano V3.0 Atmega328 o Tablero de Microcontrolador con ATmega328P

hasta 12

Botón

1

RGB LED Ring WS2812B con 12 bits

1

Módulo de Alarma de Buzzer Pasivo KY-006

varios

Cables de puente

2

Breadboard o Kit de Breadboard


Diagrama de circuito

diagrama de circuito

Diagrama del circuito para hacer clic

Microcontrolador

RGB LED Ring

D2

IN

+ 5V

VCC

GND

GND


Zumbador

D3

(S)ignal

GND

-


Botón 1-12

D4 - D12

A0 - A2

Pin 1 cada uno

GND

Pin 2 cada uno


El lector atento observará ahora que no utilizamos D13. Este pin no se debe usar como un pin de entrada en el Nano V3.0 con Atmega328 porque el LED integrado con la resistencia se encuentra allí. Para las versiones más grandes del Atmega328 esto debería funcionar. Sin embargo, como me gustan los desafíos, nos quedamos con la versión pequeña y el pin número 13 pierde una vuelta. Dado que tenemos un total de 12 LEDs completos disponibles en el RGB LED Ring, pero los pines digitales oficiales se están agotando, utilizaremos los pines analógicos como entradas digitales para fines distintos a los previstos.

Por lo demás, la configuración es la misma que en la Parte 1. Solo expandimos los botones de 5 a 12.

Exponer

Mi nuevo objetivo es ampliar los botones de forma dinámica. Por supuesto, esto está limitado, ya que los pines se tienen que inicializar como salidas o entradas en el código fuente. Esta tarea no se puede subcontratar al usuario. Así que nos limitamos a un máximo de 12 jugadores. Al encender el microcontrolador, primero quiero establecer cuántos jugadores participarán. El primer botón es obligatorio. Lo necesitamos para el modo de configuración del jugador. Al principio, se pulsa este botón tantas veces como jugadores haya. Para cada jugador, se ilumina otro LED en el Ring. Cuando llegue al último jugador que desea, se tiene que mantener pulsado el botón para finalizar la configuración de los jugadores. Si desea utilizar los 12 botones, se tiene que mantener pulsado hasta que todos los LED se iluminen. A continuación, la configuración se detiene automáticamente y puede comenzar.

En la primera versión, hice que el LED del reproductor se iluminara durante unos segundos después de presionar un botón. Pensé que esto podría utilizarse para limitar el tiempo de respuesta de un jugador después de que suena. Para poner un poco más de "presión" sobre el jugador, ahora he agregado un pitido que se escucha cada segundo. Cuando el tiempo de respuesta se agota, se escucha un pitido largo.

El código fuente

En el sketch he ampliado el máximo los botones a 12 y he definido el pin 4 del microcontrolador como DEFAULTBUTTONPIN. He ampliado la matriz uint32_t color [MAX_BUTTONS], que contiene los valores de los colores, a 12. En este punto es difícil crear la memoria de forma dinámica. Podría tener los valores de color generados al azar y luego expandidos dinámicamente, como mostraré con las otras matrices en un momento. Lo he guardado y he arreglado los colores.

He cambiado las matrices para los pines de entrada y los estados de los botones de la siguiente manera:

 En t *Button_Pins = CERO;
 En t *Button_Pins_Temp = CERO;
 booleano *Antiguo = CERO;
 booleano *oldstate_temp = CERO;
 booleano *Estancamiento = CERO;
 booleano *newstate_temp = CERO;

Tal vez ahora se pregunte: ¿Qué está haciendo ?

Para muchos, los punteros son un libro con siete sellos. Una matriz se puede programar en notación de matriz. Eso se ve así:

 En t Button_Pins[1] = 0;

Como puede observar, el número de elementos se determina cuando se declaran. Sin embargo, no sabemos durante la programación cuántos botones se utilizarán más adelante y una matriz no se puede ampliar en tiempo de ejecución. Sólo podemos establecer el número máximo. Por supuesto, también podríamos crear una matriz con 12 campos. Pero queremos hacerlo un poco más emocionante, ahorrar memoria y trabajar de forma dinámica. Así que utilizamos la notación de puntero. La definición con CERO (que no corresponde a 0, sino a un un puntero CERO) debe realizarse para que el puntero no apunte a nada y se produzca un estado indefinido. Puede imaginar que es como un enchufe ciego en el mundo real. Se coloca una tubería vacía, pero aun no se utiliza y se asegura con un tapón ciego por el momento. Además de malloc (), también existe calloc (), donde todos los valores se definen con 0 y realloc (), que necesitamos más tarde para ampliar la matriz.

A continuación, agregué otro tono C6 a la matriz de tonos. En la sección que llamé CONFIGURACIÓN DEL JUEGO, se puede cambiar el tiempo de respuesta (ahora 5 segundos / 5000 ms), el intervalo de pitidos del tiempo de respuesta (ahora 1 segundo / 1000 ms) y el mantenimiento del botón durante la configuración (ahora 2 segundos / 2000 ms).

En setup(), las matrices reciben memoria y se conectan a los punteros que he declarado anteriormente:

   Button_Pins = (En t *)malloc(Player_Count*(tamaño de(En t)));
   Antiguo = (booleano*)malloc(Player_Count*(tamaño de(booleano)));
   Estancamiento = (booleano*)malloc(Player_Count*(tamaño de(booleano)));
   Button_Pins[0] = DefaultButtonpin;

La función malloc () reserva memoria del tamaño especificado y devuelve un puntero a esta ubicación de memoria. Con la asignación BUTTON_PINS, nuestra matriz está vinculada a esta ubicación de memoria. La variable player_count contiene el valor 1 cuando se inicia el programa. La función sizeof (int) devuelve el tamaño de un entero, por lo que reservamos 1 x 2 bytes. Si hubiéramos dejado que player_count comenzara con 0 como es habitual, no se podría reservar memoria, porque 0 x algo sigue siendo 0. Podemos entonces usar este contador varias veces, pero tenemos que tener cuidado después cuando usemos la variable como índice para la matriz, porque ahí empezamos a contar con 0.

La matriz BUTTON_PINS es la lista que contiene el pin de entrada para cada jugador. Así puede asignar los pines a todos los jugadores de 0 a 11 y luego iterar sobre esta lista más tarde. El jugador 0 contiene el DEFAULTBUTTONPIN 4.

Después de la animación de inicio, que no he cambiado, se enciende el LED del primer jugador:

   banda.Setpixelcolor(Player_Count - 1, color[Player_Count - 1]);
   banda.show();

Esta vez me he abstenido de configurar el desplazamiento para que el LED superior se asigne al primer jugador. Eso llevaría un poco más de tiempo.

En el loop (), ahora se debe distinguir entre la configuración del jugador y el modo de juego normal. Esto se hace mediante la variable setupMode. Cuando se inicia el programa, estamos en la configuración del reproductor, el primer LED se ilumina y el primer botón ya está inicializado como entrada. Si se presiona el botón, las matrices se expanden con realloc.

Nota: malloc (), calloc () y realloc () sólo se deben utilizar de forma limitada en estos microcontroladores, ya que la memoria del programa está fragmentada y eventualmente se agota. Dado que nos limitamos a 12 jugadores, esto no debería ser un problema.

Con la ampliación de la matriz de pines, el pin respectivo se inicializa como entrada. Esto puede hacerse no sólo en setup(), sino también en cualquier momento posterior del programa. Ahora es un poco complicado cuando se usa el pequeño Nano V3 Atmega328, ya que el pin 13 no debe ser inicializado como una entrada y usado con los botones. Con el siguiente truco y otra variable, podemos introducir los pines en la matriz de pines, según lo necesitamos:

 // Pin 13 Oropring
 SI (Player_Count < 10) {
     número de PIN = DefaultButtonpin + (Player_Count - 1);
 }
 Demás {
     número de PIN = DefaultButtonpin + (Player_Count);
 }

El jugador No. 9 tiene el pin D12. Hasta entonces, permanece en el orden calculado con la ayuda de DEFAULTBUTTON y el número de jugador. El pin 4 ya está disponible en la matriz en la posición 0. Los pines 5 a 12 se introducen aquí uno tras otro. Luego continúe con el pin 14 (A0). Si se introduce el número máximo de jugadores, la matriz presenta el siguiente aspecto:

Campo

0

1

2

3

4

5

6

7

8

9

10

11

Pin

4

5

6

7

8

9

10

11

12

14

15

16

Si ahora iteramos sobre el número de campo, siempre obtendremos el pin de entrada correspondiente, que necesitamos para digitalRead() en el bucle principal. Las matrices oldState y newState se amplían de la misma manera. Si utiliza un microcontrolador diferente, puede comentar o ajustar este pequeño algoritmo.

Una vez que se ha alcanzado el número máximo de jugadores, se termina la configuración de los jugadores, se apagan los LEDs y puede comenzar el espectáculo del juego.

Si quiere mantener la cantidad de jugadores baja, el botón debe permanecer presionado y la configuración de los jugadores debe terminar después del tiempo preseleccionado. Por esto utilizamos buttonPress_time = millis (); para tomar el tiempo de inicio cuando se pulsa el botón. La consulta para esto sigue así:

   // mantenga presionado para terminar la configuración del jugador
   SI (configuración && (Estancamiento[Recuento de botón] == Bajo) && (Antiguo[Recuento de botón] == Bajo)) {
     SI (milis() - ButtonPress_Time >= ButtonLongress_Time) {
       configuración = falso;
       por (En t I = 0; I < Pixel_Count; I++) {
         banda.Setpixelcolor(I, banda.Color(  0,   0,   0));
         banda.show();
      }
    }
  }

En este punto comprobamos si el pin de entrada estaba LOW, está LOW y si el programa todavía está en setupMode. Si es así, se comprueba si se ha alcanzado el tiempo de mantenimiento del botón. Si es así, la configuración del jugador también se termina aquí.

Puede descargar el código fuente completo aquí como descarga.

Conclusión

La verdadera dinámica (es decir, la flexible en la cantidad de jugadores) sólo es posible hasta cierto punto. La matriz para los colores podría seguir llenándose automáticamente. Por lo demás, depende del microcontrolador que se utilice y del número de pines de entrada disponibles. Con algunos ajustes, puede ampliar el número según lo deseado. Sin embargo, con 12 jugadores, ya está bien encaminado. En ese caso, también tendría que reemplazar el  RGB Ring, para que estén disponibles más LEDs.

Diviértase con la reconstrucción

Andreas Wolter

Para AZ-Delivery Blog

Para arduinoProyectos para principiantes

Deja un comentario

Todos los comentarios son moderados antes de ser publicados

Artículos de blog

  1. Ahora instalamos el esp32 a través de la administración.
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. Transporte Aéreo - programación de ESP mediante redes locales inalámbricas