Développement de jeux sur Traitement avec contrôle via la carte Arduino Uno, partie 2

introduction


Dans un article précédent , nous avons examiné un exemple de création du jeu unidimensionnel le plus simple - «a la éviter les collisions». Avec un tel ensemble de capacités, ShG n'est clairement pas à la hauteur de son nom. En fait, il s'avère que c'est une balle d'évasion, qui ne semble pas fière. Alors pourquoi ne pas étendre les capacités du "gameplay" et ajouter un élément d'interactivité au jeu?
Pour commencer, il est proposé de transférer l'action du jeu dans l'avion. Introduisez la condition de victoire dans le jeu - un compte, lorsque vous atteignez lequel, le cher joueur «Vous avez gagné» apparaîtra. Emettez un pistolet pacifiste au ShG pour un ensemble de points plus rapide et une interaction avec le ShP , si possible, changez la conception visuelle du projet en un modèle plus attrayant.
En fait, j'ai repris la solution de ces problèmes dans le cadre de mon prochain projet «week-end». Qu'est-il arrivé, lisez la suite.

Étape 1 «Tâche de développement»


-ShG doit avoir 2 degrés de liberté.
-SHG a la capacité de marquer rapidement des points et de ralentir la vitesse de déplacement des silos en frappant le dernier faisceau spécial.
-Implémenter de nouvelles règles - le jeu se joue jusqu'à 1000 points. Pour éviter simplement une collision, 1 point est accordé. Pour la rétention du faisceau sur la balle +1 point pour chaque 50 * 10 ^ -3 s (un retard de 50 ms est défini dans le programme Arduino)

Étape 2 «Description de la connexion d'une clé analogique»


La clé a 5 broches pour la connexion: la broche VCC se connecte à une alimentation + 5V, GND - à la terre sur la carte Arduino Uno, X - à l'entrée analogique A0, Y - à A1, D - à l'entrée numérique D2.

Étape 3 «Transfert de plusieurs coordonnées sur une connexion série»


Les données sur la position du stick sont transmises ensemble afin d'assurer leur traitement le plus rapidement possible sans délai. Pour décrire la position actuelle du stick analogique, 7 bits XXXYYYB suffisent - 3 pour la coordonnée X, 3 de plus pour la coordonnée Y, 1 bit pour contrôler le bouton du stick. Je joins le code ci-dessous:
Code pour Arduino Uno Board
#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

Après avoir connecté la clé et le firmware Arduino Uno, vous pouvez voir quelque chose comme ce qui suit dans le moniteur du port série.

Il s'agit du vecteur d'état de stick dans le format que nous avons défini. Soit dit en passant, parfois des artefacts «glissent» - des vecteurs dégénérés de 2 à 3 bits. Phénomène extrêmement désagréable. À cause d'eux, le jeu de Processing plante. Peut-être que cela est dû à un défaut sur mon bâton, peut-être pas. En tout cas, je n'ai pas essayé de traiter les artefacts au niveau Arduino. Pour cela, une condition spéciale est fournie dans le code de jeu pour le traitement (voir l'étape 4). Sa tâche consiste à vérifier l'intégrité des données transmises via la connexion série.

Étape 4 «Encodage du jeu»


Je ne commenterai pas en détail le code. J'ai essayé de le rendre compréhensible. Évaluez si vous pouvez ou non sous le spoiler. Juste au cas où, je donne un tableau de variables:
radiusOfHero-radius du SH;
radiusOfEnemy - rayon du silo;
radiusOfBullet - rayon de balle; produit SHG;
Compteur de contre - point;
speedOfEnemy - coefficient directement proportionnel à la vitesse de chute des silos;
DeltaPositionOfHeroX - incrément de la position du SH le long de l'axe X, obtenu à partir du bâton;
positionOfHeroX1 - la coordonnée finale du mouvement du SH le long de l'axe X (à la fin de l'horloge de lecture);
positionOfHeroX0 - la coordonnée initiale le long de l'axe X (au début de la mesure);
DeltapositionOfHeroY, positionOfHeroY1, positionOfHeroY0 - les mêmes le long de l'axe Y;
strbuf est la ligne dans laquelle les indications d'état du stick analogique transmises par l'Arduino Uno sont lues.
Traitement du code de jeu
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));
}
}

Étape 5 «Démonstration»



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


All Articles