Desenvolvimento de jogos em Processamento com controle via placa Arduino Uno, parte 2

Introdução


Em um artigo anterior , examinamos um exemplo de criação do jogo unidimensional mais simples - “a la evitar colisões”. Com esse conjunto de habilidades, ShG claramente não faz jus ao seu nome. Na verdade, acaba sendo uma bola de evasão, que não soa orgulhosa. Então, por que não expandir os recursos da "jogabilidade" e adicionar um elemento de interatividade ao jogo?
Para começar, propõe-se transferir a ação do jogo para o avião. Introduzir a condição de vitória no jogo - uma conta, ao atingir a qual, a estimada mensagem "Você venceu" será exibida. Emita uma arma pacifista ao ShG para obter um conjunto mais rápido de pontos e interação com o ShP , se possível altere o design visual do projeto para um mais atraente.
Na verdade, peguei a solução desses problemas como parte do meu próximo projeto de "final de semana". O que aconteceu, continue lendo.

Etapa 1 "Tarefa de desenvolvimento"


-ShG deve ter 2 graus de liberdade.
-SHG tem a capacidade de marcar pontos rapidamente e diminuir a velocidade de movimento dos silos, atingindo o último feixe especial.
- Implementar novas regras - o jogo é jogado até 1000 pontos. Para evitar uma colisão simples, é concedido 1 ponto. Para retenção do feixe na bola, um ponto a cada 50 * 10 ^ -3 s (um atraso de 50 ms é definido no programa Arduino)

Etapa 2 "Descrição da conexão de um stick analógico"


O stick possui 5 pinos para conexão: o pino VCC se conecta à energia de + 5V, GND - ao terra na placa Arduino Uno, X - à entrada analógica A0, Y - a A1, D - à entrada digital D2.

Etapa 3 "Transferindo várias coordenadas por uma conexão serial"


Os dados na posição do stick são transmitidos juntos para garantir o processamento o mais rápido possível, sem demora. Para descrever a posição atual do stick analógico, 7 bits XXXYYYB são suficientes - 3 para a coordenada X, mais 3 para a coordenada Y, 1 bit para controlar o botão no stick. Anexo o código abaixo:
Código para o 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

Após conectar o stick e o firmware do Arduino Uno, você pode ver algo como o seguinte no monitor da porta serial.

Este é o vetor do estado do stick no formato que definimos. A propósito, às vezes os artefatos “escorregam” - vetores degenerados de 2 3 bits. Fenômeno extremamente desagradável. Por causa deles, o jogo no Processing falha. Talvez isso se deva a um defeito no meu quadro, talvez não. De qualquer forma, não tentei lidar com artefatos no nível do Arduino. Para isso, é fornecida uma condição especial no código do jogo para Processamento (consulte a Etapa 4). Sua tarefa é verificar a integridade dos dados transmitidos pela conexão serial.

Etapa 4 "Codificando o jogo"


Não comentarei em detalhes o código. Eu tentei torná-lo compreensível. Avalie se você pode ou não usar o spoiler. Apenas no caso, dou uma tabela de variáveis:
radiusOfHero-radius do SH;
radiusOfEnemy - raio do silo;
radiusOfBullet - raio do marcador; SHG produzido;
Contador de contra-ponto;
speedOfEnemy - coeficiente diretamente proporcional à velocidade de queda dos silos;
DeltaPositionOfHeroX - incremento da posição do SH ao longo do eixo X, obtido a partir do stick;
positionOfHeroX1 - a coordenada final do movimento do SH ao longo do eixo X (no final do relógio lido);
positionOfHeroX0 - a coordenada inicial ao longo do eixo X (no início da medida);
DeltapositionOfHeroY, positionOfHeroY1, positionOfHeroY0 - o mesmo no eixo Y;
strbuf é a linha na qual as indicações de status do stick analógico transmitido pelo Arduino Uno são lidas.
Processando código do jogo
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));
}
}

Etapa 5 "Demonstração"



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


All Articles