Videospiel Pong Bug

ES gibt in dem Spiel einen Bug den ich nicht verstehe. Der Ball geht manchmal nähmlich einfach durch den Schläger hindurch. Hat jemand Ahnung woran das liegen könnte?

#include <splash.h>

#include <Adafruit_GFX.h>
#include <Adafruit_GrayOLED.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>



#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

float ball_x = 63;   //Position des Balls auf der X-Achse
float ball_y = 31;   //Position des Balls auf der Y-Achse
float ball_vy = 0;   //Geschwindigkeit und Richtung des Balls auf der Y-Achse
float ball_vx = 0;   //Geschwindigkeit und Richtung des Balls auf der X-Achse
int Spieler_V = 3;   //Geschwindigkeit der Schläger
int Spieler1_1 = 24;    //Spieler 1 oberer Punkt der Linie
int Spieler1_2 = 36;    //Spieler 1 unterer Punkt der Linie
int Spieler2_1 = 24;    //Spieler 2 oberer Punkt der Linie
int Spieler2_2 = 36;    //Spieler 2 unterer Punkt der Linie
const int X_Pin = A0;   //analoger Pin von Spieler 1 Joystick
const int X2_Pin = A2;  //analoger Pin von Spieler 2 Joystick
float Abweichung = 0;   //Variable für minimale Abweichungen beim abprallen vom Ball
int Punktestand_1 = 0;   //Punktestand von Spieler 1
int Punktestand_2 = 0;   //Punktestand von Spieler 2
int Reset = 12;  //Schläger zurücksetzen
int ball_v = 1;  //Geschwindigkeit des Balls





void setup() {
  // put your setup code here, to run once:
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  randomSeed(analogRead(A5));
  ball_vx = random(1, 3);
  ball_vy = random(1, 3);
    if (ball_vx == 2) {
    ball_vx = -1;
    }
    if (ball_vy == 2) {
    ball_vy = -1;
    }
}

void loop() {
  // put your main code here, to run repeatedly:
  
  display.setTextColor(BLACK);
  display.setCursor(54, 0);
  display.print(Punktestand_1-1);
  display.setCursor(72, 0);
  display.print(Punktestand_2-1);

  display.setTextColor(WHITE);
  display.setCursor(54, 0);
  display.print(Punktestand_1);
  display.setCursor(72, 0);
  display.print(Punktestand_2);

  //SPIELER 1
  display.drawLine(0, Spieler1_1, 0, Spieler1_2, WHITE);

  if (analogRead(X_Pin) > 1000) {
    display.drawLine(0,Spieler1_1 - Spieler_V,0,Spieler1_2 - Spieler_V,BLACK);
    Spieler1_1 = Spieler1_1 + Spieler_V;
    Spieler1_2 = Spieler1_2 + Spieler_V;
    display.drawLine(0, Spieler1_1, 0, Spieler1_2, WHITE);
    display.display();
  }
  if (analogRead(X_Pin) < 500) {
    display.drawLine(0, Spieler1_1 + Spieler_V, 0, Spieler1_2 + Spieler_V, BLACK);
    Spieler1_1 = Spieler1_1 - Spieler_V;
    Spieler1_2 = Spieler1_2 - Spieler_V;
    display.drawLine(0, Spieler1_1, 0, Spieler1_2, WHITE);
    display.display();
  }
  display.drawLine(0, Spieler1_1, 0, Spieler1_2, WHITE);
  if (Spieler1_1 < 1) {
    Spieler1_1 = 1;
    Spieler1_2 = Spieler1_1 + Reset;
  }
  if (Spieler1_2 > 62) {
    Spieler1_2 = 62;
    Spieler1_1 = Spieler1_2 - Reset;
  }

  display.display();



  //SPIELER 2

  display.drawLine(127, Spieler2_1, 127, Spieler2_2, WHITE);

  if (analogRead(X2_Pin) > 1000) {
    display.drawLine(127, Spieler2_1 - Spieler_V, 127, Spieler2_2 - Spieler_V, BLACK);
    Spieler2_1 = Spieler2_1 + Spieler_V;
    Spieler2_2 = Spieler2_2 + Spieler_V;
    display.drawLine(127, Spieler2_1, 127, Spieler2_2, WHITE);
    display.display();
  }
  if (analogRead(X2_Pin) < 500) {
    display.drawLine(127, Spieler2_1 + Spieler_V, 127, Spieler2_2 + Spieler_V, BLACK);
    Spieler2_1 = Spieler2_1 - Spieler_V;
    Spieler2_2 = Spieler2_2 - Spieler_V;
    display.drawLine(127, Spieler2_1, 127, Spieler2_2, WHITE);
    display.display();
  }
  display.drawLine(127, Spieler2_1, 127, Spieler2_2, WHITE);

  if (Spieler2_1 < 1) {
    Spieler2_1 = 1;
    Spieler2_2 = Spieler2_1 + Reset;
  }
  if (Spieler2_2 > 62) {
    Spieler2_1 = Spieler2_2 - Reset;
    Spieler2_2 = 62;
  }

  display.display();



  //BALL
  display.drawPixel(ball_x, ball_y, BLACK);

    ball_x = ball_x + ball_vx * ball_v;
    ball_y = ball_y + ball_vy * ball_v;
  


  display.drawPixel(ball_x, ball_y, WHITE);
   Abweichung=random(0,10000) ;
  if (ball_y > 62) {
    ball_vy = -ball_vy;
    ball_vx = ball_vx + (Abweichung /100000);
  }
  if (ball_y < 1) {
    ball_vy = -ball_vy;
    ball_vx = ball_vx + (Abweichung /100000);
  }




  if (ball_x > 125) {
    if (Spieler2_1 <= ball_y && Spieler2_2 >= ball_y) {
      ball_vx = -ball_vx;
      ball_vy = ball_vy + (Abweichung / 100000);
    }
  }

  if (ball_x < 2) {
    if (Spieler1_1 <= ball_y && Spieler1_2 >= ball_y) {
      ball_vx = -ball_vx;
       ball_vy = ball_vy + (Abweichung / 100000);
    }}
    display.drawPixel(ball_x,ball_y,BLACK);
  ball_x=ball_x+ball_vx*ball_v;
  ball_y=ball_y+ball_vy*ball_v;
  display.drawPixel(ball_x,ball_y,WHITE);

  if (ball_x < 1) {
    display.drawPixel(ball_x,ball_y,BLACK);
    ball_x = 63;
    ball_y = 31;
    display.drawPixel(ball_x, ball_y, WHITE);
    Punktestand_2 = Punktestand_2 + 1;
    delay(500);
  }
  if (ball_x > 125) {
    display.drawPixel(ball_x,ball_y,BLACK);
    ball_x = 63;
    ball_y = 31;
    display.drawPixel(ball_x, ball_y, WHITE);
    Punktestand_1 = Punktestand_1 + 1;
    delay(500);
  }
   




       //Punktestand
  if (Punktestand_1 == 11) {
    delay(500);
    display.clearDisplay();
    delay(100);
    display.setCursor(40, 26);
    display.print("Spieler 1");
    display.setCursor(30, 38);
    display.print("hat gewonnen!");
    Punktestand_1 = 0;
    Punktestand_2 = 0;
    display.display();
    delay(5000);
    display.clearDisplay();
  }


  if (Punktestand_2 == 11) {
    delay(500);
    display.clearDisplay();
    display.setCursor(40, 26);
    display.print("Spieler 2");
    display.setCursor(30, 38);
    display.print("hat gewonnen!");
    Punktestand_1 = 0;
    Punktestand_2 = 0;
    display.display();
    delay(5000);
    display.clearDisplay();
  }
}

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

1 Like

Warum mehrfach lesen? Was ist mit dem Bereich 500 bis 1000?

Reply #2....

Hast du geprüft, ob der Ball durch Rundungsungenauigkeiten vielleicht zu viele Schritte in im Bereich des Schlägers macht?

.

warum hast du hier ein delay nach dem clearDisplay?

geht auch so:

  //Punktestand
  if ((Punktestand_1 == 11) || (Punktestand_2 == 11)) {
    display.clearDisplay();
    display.setCursor(40, 26);
	if (Punktestand_1 == 11)
	  display.print("Spieler 1")
	else  
	  display.print("Spieler 2");
    display.setCursor(30, 38);
    display.print("hat gewonnen!");
    Punktestand_1 = 0;
    Punktestand_2 = 0;
    display.display();
    delay(5000);
    display.clearDisplay();
  }

In loop rechnest du zweimal die neue Ballposition aus, das ist mindestens unnötig kompliziert.

Auf der einen Seite ist Schläger/Wand bei (2 .. 1) Auf der anderen (125 .. 125)
warum?

Vorschlag: entweder getroffen oder Punkt, aber bei der gleichen ball-Position.

"Manchmal" kann auch am Abschneiden bei der Wandlung float/int liegen.

Ich hab mich nebenbei auch drüber gemacht.
Langsamer als die anderen, aber hier wird deutlich, dass da noch ganz viel gekürzt werden kann.

#include <splash.h>

#include <Adafruit_GFX.h>
#include <Adafruit_GrayOLED.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

float ball_x = 63;   //Position des Balls auf der X-Achse
float ball_y = 31;   //Position des Balls auf der Y-Achse
float ball_vy = 0;   //Geschwindigkeit und Richtung des Balls auf der Y-Achse
float ball_vx = 0;   //Geschwindigkeit und Richtung des Balls auf der X-Achse
int Spieler_V = 3;   //Geschwindigkeit der Schläger
int Spieler1_1 = 24;    //Spieler 1 oberer Punkt der Linie
int Spieler1_2 = 36;    //Spieler 1 unterer Punkt der Linie
int Spieler2_1 = 24;    //Spieler 2 oberer Punkt der Linie
int Spieler2_2 = 36;    //Spieler 2 unterer Punkt der Linie
const int X_Pin = A0;   //analoger Pin von Spieler 1 Joystick
const int X2_Pin = A2;  //analoger Pin von Spieler 2 Joystick
float Abweichung = 0;   //Variable für minimale Abweichungen beim abprallen vom Ball
int Punktestand_1 = 0;   //Punktestand von Spieler 1
int Punktestand_2 = 0;   //Punktestand von Spieler 2
int Reset = 12;  //Schläger zurücksetzen
int ball_v = 1;  //Geschwindigkeit des Balls

void setup()
{
  // put your setup code here, to run once:
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  randomSeed(analogRead(A5));
  ball_vx = random(1, 3);
  ball_vy = random(1, 3);

  if (ball_vx == 2)
  {
    ball_vx = -1;
  }

  if (ball_vy == 2)
  {
    ball_vy = -1;
  }
}

void loop()
{
  // put your main code here, to run repeatedly:
  displayPoints();
  //SPIELER 1
  checkPotiX();
  //SPIELER 2
  checkPotiX2();
  //BALL
  display.drawPixel(ball_x, ball_y, BLACK);
  ball_x = ball_x + ball_vx * ball_v;
  ball_y = ball_y + ball_vy * ball_v;
  display.drawPixel(ball_x, ball_y, WHITE);
  Abweichung = random(0, 10000) ;

  if ((ball_y > 62) || (ball_y < 1))
  {
    ball_vy = -ball_vy;
    ball_vx = ball_vx + (Abweichung / 100000);
  }

  if (ball_x > 125)
  {
    if (Spieler2_1 <= ball_y && Spieler2_2 >= ball_y)
    {
      ball_vx = -ball_vx;
      ball_vy = ball_vy + (Abweichung / 100000);
    }
  }

  if (ball_x < 2)
  {
    if (Spieler1_1 <= ball_y && Spieler1_2 >= ball_y)
    {
      ball_vx = -ball_vx;
      ball_vy = ball_vy + (Abweichung / 100000);
    }
  }

  display.drawPixel(ball_x, ball_y, BLACK);
  ball_x = ball_x + ball_vx * ball_v;
  ball_y = ball_y + ball_vy * ball_v;
  display.drawPixel(ball_x, ball_y, WHITE);

  if (ball_x < 1 || ball_x > 125)
  {
    if (ball_x < 1)
    { Punktestand_2++; }
    else if (ball_x > 125)
    { Punktestand_1++; }

    display.drawPixel(ball_x, ball_y, BLACK);
    ball_x = 63;
    ball_y = 31;
    display.drawPixel(ball_x, ball_y, WHITE);
    delay(500);
  }

  checkPoints();
  display.display();
}

void checkPoints()
{
  //Punktestand
  if (Punktestand_1 == 11 || Punktestand_2 == 11)
  {
    delay(500);
    display.clearDisplay();
    display.setCursor(40, 26);
    display.print(F("Spieler "));

    if (Punktestand_1 == 11)
    { display.print(1); }
    else if (Punktestand_2 == 11)
    { display.print(2); }

    display.setCursor(30, 38);
    display.print("hat gewonnen!");
    Punktestand_1 = 0;
    Punktestand_2 = 0;
    display.display();
    delay(5000);
    display.clearDisplay();
  }
}

void checkPotiX()
{
  uint16_t readPin = analogRead(X_Pin);

  if ( readPin > 1000)
  {
    display.drawLine(0, Spieler1_1 - Spieler_V, 0, Spieler1_2 - Spieler_V, BLACK);
    Spieler1_1 = Spieler1_1 + Spieler_V;
    Spieler1_2 = Spieler1_2 + Spieler_V;
  }
  else if (analogRead(X_Pin) < 500)
  {
    display.drawLine(0, Spieler1_1 + Spieler_V, 0, Spieler1_2 + Spieler_V, BLACK);
    Spieler1_1 = Spieler1_1 - Spieler_V;
    Spieler1_2 = Spieler1_2 - Spieler_V;
  }

  display.drawLine(0, Spieler1_1, 0, Spieler1_2, WHITE);

  if (Spieler1_1 < 1)
  {
    Spieler1_1 = 1;
    Spieler1_2 = Spieler1_1 + Reset;
  }

  if (Spieler1_2 > 62)
  {
    Spieler1_2 = 62;
    Spieler1_1 = Spieler1_2 - Reset;
  }
}

void checkPotiX2()
{
  uint16_t readPin = analogRead(X2_Pin);

  if (readPin > 1000)
  {
    display.drawLine(127, Spieler2_1 - Spieler_V, 127, Spieler2_2 - Spieler_V, BLACK);
    Spieler2_1 = Spieler2_1 + Spieler_V;
    Spieler2_2 = Spieler2_2 + Spieler_V;
  }
  else if (readPin < 500)
  {
    display.drawLine(127, Spieler2_1 + Spieler_V, 127, Spieler2_2 + Spieler_V, BLACK);
    Spieler2_1 = Spieler2_1 - Spieler_V;
    Spieler2_2 = Spieler2_2 - Spieler_V;
  }

  display.drawLine(127, Spieler2_1, 127, Spieler2_2, WHITE);

  if (Spieler2_1 < 1)
  {
    Spieler2_1 = 1;
    Spieler2_2 = Spieler2_1 + Reset;
  }

  if (Spieler2_2 > 62)
  {
    Spieler2_2 = 62;
    Spieler2_1 = Spieler2_2 - Reset;
  }
}

void displayPoints()
{
  display.setTextColor(BLACK);
  display.setCursor(54, 0);
  display.print(Punktestand_1 - 1);
  display.setCursor(72, 0);
  display.print(Punktestand_2 - 1);
  display.setTextColor(WHITE);
  display.setCursor(54, 0);
  display.print(Punktestand_1);
  display.setCursor(72, 0);
  display.print(Punktestand_2);
}
Irgendwie fehlte mir zum kompilieren das passende include für den ssd_1306, warum weiss ich nicht, habe ich mal nachgetragen.

Du wiederholst immer wieder Dinge mit magischen Zahlen und mir ist noch nicht ganz klar, warum Du bei ball_x am oberen Ende immer mit 125, aber unten mal mit 1 und mal mit 2 arbeitest.

  if (ball_x > 125)
  {
    if (Spieler2_1 <= ball_y && Spieler2_2 >= ball_y)
    {
      ball_vx = -ball_vx;
      ball_vy = ball_vy + (Abweichung / 100000);
    }
  }

  if (ball_x < 2)  // <<<<<
  {
    if (Spieler1_1 <= ball_y && Spieler1_2 >= ball_y)
    {
      ball_vx = -ball_vx;
      ball_vy = ball_vy + (Abweichung / 100000);
    }
  }

  display.drawPixel(ball_x, ball_y, BLACK);
  ball_x = ball_x + ball_vx * ball_v;
  ball_y = ball_y + ball_vy * ball_v;
  display.drawPixel(ball_x, ball_y, WHITE);

  if (ball_x < 1)   // <<<<<<
  {
    display.drawPixel(ball_x, ball_y, BLACK);
    ball_x = 63;
    ball_y = 31;
    display.drawPixel(ball_x, ball_y, WHITE);
    Punktestand_2 = Punktestand_2 + 1;
    delay(500);
  }

  if (ball_x > 125)
  {
    display.drawPixel(ball_x, ball_y, BLACK);
    ball_x = 63;
    ball_y = 31;
    display.drawPixel(ball_x, ball_y, WHITE);
    Punktestand_1 = Punktestand_1 + 1;
    delay(500);
  }

Wenn ich das erklärt bekomme, dann kürze ich meinen Ansatz weiter runter und löse Dir die beiden potis noch auf.

Vielleicht wäre es auch hilfreich einige Kommentare einzufügen...