Spieleentwicklung zur Verarbeitung mit Kontrolle über das Arduino Uno Board, Teil 2

Einführung


In einem früheren Artikel haben wir ein Beispiel für die Erstellung des einfachsten eindimensionalen Spiels untersucht - „Kollisionen vermeiden“. Mit solchen Fähigkeiten wird ShG seinem Namen eindeutig nicht gerecht. Tatsächlich stellt sich heraus, dass es sich um einen Ausweichball handelt, der nicht stolz klingt. Warum also nicht die Fähigkeiten des "Gameplays" erweitern und dem Spiel ein Element der Interaktivität hinzufügen?
Zunächst wird vorgeschlagen, die Aktion des Spiels auf das Flugzeug zu übertragen. Führen Sie die Siegbedingung in das Spiel ein - ein Konto, bei dessen Erreichen die geschätzte Nachricht „Sie haben gewonnen“ angezeigt wird. Stellen Sie der ShG eine pazifistische Waffe aus, um schneller Punkte zu sammeln und mit der ShP zu interagieren. Ändern Sie nach Möglichkeit das visuelle Design des Projekts in ein attraktiveres.
Eigentlich habe ich die Lösung dieser Probleme im Rahmen meines nächsten „Wochenend“ -Projekts aufgegriffen. Was passiert ist, lesen Sie weiter.

Schritt 1 "Entwicklungsaufgabe"


-ShG muss 2 Freiheitsgrade haben.
-SHG hat die Fähigkeit, schnell Punkte zu sammeln und die Bewegungsgeschwindigkeit der Silos zu verlangsamen, indem der letzte Spezialstrahl getroffen wird.
-Umsetzen Sie neue Regeln - das Spiel wird mit bis zu 1000 Punkten gespielt. Zur einfachen Vermeidung einer Kollision wird 1 Punkt vergeben. Für die Strahlretention auf dem Ball +1 Punkt alle 50 * 10 ^ -3 s (im Arduino-Programm ist eine Verzögerung von 50 ms eingestellt)

Schritt 2 „Beschreibung des Anschlusses eines Analogsticks“


Der Stick verfügt über 5 Pins für den Anschluss: Der VCC-Pin wird an + 5V angeschlossen, GND - an Masse auf der Arduino Uno-Karte, X - an Analogeingang A0, Y - an A1, D - an Digitaleingang D2.

Schritt 3 „Übertragen mehrerer Koordinaten über eine serielle Verbindung“


Die Positionsdaten des Sticks werden zusammen übertragen, um eine zeitverzögerte Bearbeitung so schnell wie möglich zu gewährleisten. Um die aktuelle Position des Analogsticks zu beschreiben, reichen 7 Bit XXXYYYB aus - 3 für die X-Koordinate, 3 weitere für die Y-Koordinate, 1 Bit für die Steuerung der Taste am Stick. Ich füge den folgenden Code bei:
Code für 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

Nach dem Anschließen des Sticks und der Arduino Uno-Firmware wird auf dem Serial Port-Monitor Folgendes angezeigt.

Dies ist der Stick-Statusvektor in dem von uns definierten Format. Übrigens "rutschen" manchmal Artefakte - entartete Vektoren von 2 bis 3 Bits. Extrem unangenehmes Phänomen. Aufgrund dessen stürzt das Spiel bei Processing ab. Vielleicht liegt das an einem Defekt an meinem Stick Board, vielleicht auch nicht. Auf jeden Fall habe ich nicht versucht, mit Artefakten auf Arduino-Ebene umzugehen. Hierzu ist im Spielcode für die Verarbeitung eine besondere Bedingung vorgesehen (siehe Schritt 4). Seine Aufgabe ist es, die Integrität der über die serielle Verbindung übertragenen Daten zu überprüfen.

Schritt 4 "Codierung des Spiels"


Ich werde den Code nicht im Detail kommentieren. Ich habe versucht, es verständlich zu machen. Bewerten Sie, ob Sie unter dem Spoiler können oder nicht. Für alle Fälle gebe ich eine Tabelle mit Variablen an:
radiusOfHero-radius des SH;
radiusOfEnemy - Radius des Silos;
radiusOfBullet - Kugelradius; produzierte SHG;
Gegenpunktzähler;
speedOfEnemy - Koeffizient direkt proportional zur Fallgeschwindigkeit der Silos;
DeltaPositionOfHeroX - Inkrement der Position des SH entlang der X-Achse, erhalten vom Stick;
positionOfHeroX1 - die endgültige Koordinate der Bewegung des SH entlang der X-Achse (am Ende der Lesetaktung);
positionOfHeroX0 - die Anfangskoordinate entlang der X-Achse (zu Beginn der Messung);
DeltapositionOfHeroY, PositionOfHeroY1, PositionOfHeroY0 - das gleiche entlang der Y-Achse;
strbuf ist die Zeile, in die die Statusanzeigen des vom Arduino Uno übertragenen Analogsticks gelesen werden.
Spielcode verarbeiten
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));
}
}

Schritt 5 "Demonstration"



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


All Articles