Desarrollo de juegos en Procesamiento con control a través del tablero Arduino Uno, parte 2

Introducción


En un artículo anterior , examinamos un ejemplo de cómo crear el juego unidimensional más simple: "evitar colisiones". Con tal conjunto de habilidades, ShG claramente no justifica su nombre. De hecho, resulta ser una bola de evasión, que no suena orgullosa. Entonces, ¿por qué no expandir las capacidades del "juego" y agregar un elemento de interactividad al juego?
Para empezar, se propone transferir la acción del juego al avión. Introduzca la condición de victoria en el juego: una cuenta, al llegar a la cual, aparecerá el apreciado jugador "Ganaste". Emitir un arma pacifista al ShG para un conjunto más rápido de puntos e interacción con el ShP , si es posible, cambiar el diseño visual del proyecto a uno más atractivo.
En realidad, tomé la solución de estos problemas como parte de mi próximo proyecto de "fin de semana". Lo que pasó, sigue leyendo.

Paso 1 "Tarea de desarrollo"


-ShG debe tener 2 grados de libertad.
-SHG tiene la capacidad de sumar puntos rápidamente y ralentizar la velocidad de movimiento de los silos al golpear el último haz especial.
-Implemente nuevas reglas: el juego se juega hasta 1000 puntos. Para evitar una colisión, se otorga 1 punto. Para la retención del haz en la bola +1 punto por cada 50 * 10 ^ -3 s (se establece un retraso de 50 ms en el programa Arduino)

Paso 2 "Descripción de la conexión de un dispositivo analógico"


El stick tiene 5 pines para la conexión: el pin VCC se conecta a + 5V de alimentación, GND - a tierra en la placa Arduino Uno, X - a la entrada analógica A0, Y - a A1, D - a la entrada digital D2.

Paso 3 "Transferencia de múltiples coordenadas a través de una conexión en serie"


Los datos sobre la posición del stick se transmiten juntos para garantizar su procesamiento lo más rápido posible sin demora. Para describir la posición actual del stick analógico, 7 bits XXXYYYB son suficientes: 3 para la coordenada X, 3 más para la coordenada Y, 1 bit para controlar el botón del stick. Adjunto el código a continuación:
Código para la placa Arduino Uno
#include <stdio.h>
int xPin = A0, yPin = A1, buttonPin = 2;
int xPosition = 0, yPosition = 0, buttonState = 0;
char strbuf[20]; //
void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
  //activate pull-up resistor on the push-button pin
  pinMode(buttonPin, INPUT_PULLUP);   }
void loop() {
  xPosition = map(analogRead(xPin),0,1023,0,639);
  yPosition = map(analogRead(yPin),0,1023,0,639);
  buttonState = digitalRead(buttonPin);
  sprintf(strbuf,"%03d%03d%1d",xPosition,yPosition,buttonState);
  Serial.println(strbuf); 
  delay(50); }// add some delay between reads

Después de conectar el stick y el firmware Arduino Uno, puede ver algo como lo siguiente en el monitor del puerto serie.

Este es el vector de estado de palo en el formato que definimos. Por cierto, a veces los artefactos se “deslizan”: vectores degenerados de 2 3 bits. Fenómeno extremadamente desagradable. Debido a ellos, el juego en Processing se bloquea. Quizás esto se deba a un defecto en mi pizarra, quizás no. En cualquier caso, no traté de tratar con artefactos en el nivel Arduino. Para esto, se proporciona una condición especial en el código del juego para Procesar (ver Paso 4). Su tarea es verificar la integridad de los datos transmitidos a través de la conexión en serie.

Paso 4 "Codificar el juego"


No comentaré en detalle sobre el código. Traté de hacerlo comprensible. Evalúa si puedes o no bajo el spoiler. Por si acaso, doy una tabla de variables:
radiusOfHero-radius de la SH;
radiusOfEnemy - radio del silo;
radiusOfBullet - radio de bala; SHG producido;
Contador - contador de puntos;
speedOfEnemy - coeficiente directamente proporcional a la velocidad de caída de los silos;
DeltaPositionOfHeroX: incremento de la posición del SH a lo largo del eje X, obtenido del stick;
positionOfHeroX1: la coordenada final del movimiento del SH a lo largo del eje X (al final del reloj de lectura);
positionOfHeroX0: la coordenada inicial a lo largo del eje X (al comienzo de la medida);
DeltapositionOfHeroY, positionOfHeroY1, positionOfHeroY0: lo mismo a lo largo del eje Y;
strbuf es la línea en la que se leen las indicaciones de estado del stick analógico transmitido desde el Arduino Uno.
Procesando código de juego
import processing.serial.*;//I/O library
Serial port;
PShape bot;
PFont font;
PImage img;
int radiusOfHero=100, radiusOfEnemy, radiusOfBullet=5, Counter=0, Fire;
float speedOfEnemy=1, DeltaPositionOfHeroX, positionOfHeroX1, positionOfHeroX0=640.0,
DeltapositionOfHeroY, positionOfHeroY1, positionOfHeroY0=640.0,
positionOfEnemyY = 0.0 ,positionOfEnemyX=0.0, positionOfBulletX=0.0,positionOfBulletY=0.0;
String strbuf="3223220";
void setup()
{
  size(640, 640);
  port = new Serial(this, "COM4", 9600);
  port.bufferUntil('\n');
  bot = loadShape("2.svg");
  font = loadFont("AgencyFB-Bold-200.vlw");
  img = loadImage("img.png");  // Load the image into the program  
  textFont(font,200);
}
void draw() {
    background(0);
    image(img, 0, 0);
    fill(255);
    text(Counter, 400,170);
//==========definiton of hero==========
fill(0, 200, 102);
positionOfHeroX1=positionOfHeroX0+(0.05*(DeltaPositionOfHeroX-width/2));
if (positionOfHeroX1<0){positionOfHeroX1=0.0;}
if (positionOfHeroX1>width){positionOfHeroX1=width;}
positionOfHeroY1=positionOfHeroY0+(0.05*(DeltapositionOfHeroY-height/2));
if (positionOfHeroY1<0){positionOfHeroY1=0.0;}
if (positionOfHeroY1>height){positionOfHeroY1=height;}
ellipse(positionOfHeroX1, positionOfHeroY1, radiusOfHero, radiusOfHero);
positionOfHeroX0=positionOfHeroX1;
positionOfHeroY0=positionOfHeroY1;
fill(244);
       positionOfBulletY= positionOfHeroY1-radiusOfHero/2;
      if (Fire==0){
            for(int i = 0; i < (positionOfHeroY1); i++){
                      positionOfBulletX = positionOfHeroX1; 
                      positionOfBulletY= positionOfBulletY-height/100;
                      ellipse(positionOfBulletX, positionOfBulletY, radiusOfBullet, radiusOfBullet);           }
                       }
//===============definition of enemy===============
fill(255,0,0);
radiusOfEnemy=round(random(60));{
   for(int i = 0; i < height; i++) 
     positionOfEnemyY=positionOfEnemyY+0.02*speedOfEnemy;
     ellipse(positionOfEnemyX, positionOfEnemyY, radiusOfEnemy*2, radiusOfEnemy*2); }
        if (positionOfEnemyY>height) {
        positionOfEnemyY=0.0;
        positionOfEnemyX = round(random(width)); 
        Counter++;}
//==========definition of counter==========        
        if (Counter>1000){
        text("YOU WON!", 50,height/2);
}
//==========clash==========
if (abs(positionOfHeroX1-positionOfEnemyX) < (radiusOfHero+radiusOfEnemy)/2 & 
   (abs(positionOfHeroY1-positionOfEnemyY) < (radiusOfHero+radiusOfEnemy)/2)){
background(255,0,0);
shape(bot, positionOfHeroX1-radiusOfHero/2,positionOfHeroY1-radiusOfHero, 100, 100);  
Counter=-1;
fill(255);
textFont(font,150);
text("TURN AWAY!", 0,height/2);}
//==========Checking of target hit==========
    if (((abs(positionOfBulletX-positionOfEnemyX) < (radiusOfBullet+radiusOfEnemy)/2))& (Fire==0))
      {speedOfEnemy=0.05;// decreasing of enemy speed
      Counter++;}
    else speedOfEnemy=0.2;}
   
void serialEvent (Serial port) {
  if(port.available()>0){
   strbuf=port.readStringUntil('\n'); 
if (strbuf.length()<7) {//condition to prevent artefacts
strbuf="3223220";
  }
DeltaPositionOfHeroX=float(strbuf.substring(0, 3)); 
DeltapositionOfHeroY=float(strbuf.substring(3, 6)); 
Fire=int(strbuf.substring(6, 7));
}
}

Paso 5 "Demostración"



Source: https://habr.com/ru/post/es384689/


All Articles