Game with nokia lcd - collision detection problems

Hello!
I have a Nokia5110 screen and a two axis joystick hooked up to a Nano. I’m using AdafruitGFX library.
I’ve programmed a simple game a sidescroller of sorts, a little bit like FlappyBird. The player must avoid colliding with walls…

I’m having problems with detecting collisions. I have a two dimesional array for obstacles(for each obstacle it contains it’s X position and the position of the hole).

The problem is, it only detects the first obstacle, then the fourth and so on.

I tried to use while loops with the obstacle array, but I got strange behaviour and the graphics went crazy.

The whole code is too big, but I’ll post relevant parts.

//the obstacle array looks like this

signed int takistus[][2] = { {84.00, 0 },
                             {112.00, 10},
                             {140.00, 20 } }; //for every obstacele - x position and the position of a hole.

//playerPos[0] is player X and playerPos[1] is Y


boolean checkCollision()//check players collision with the moving bars.
{

//the problem is somewhere here

  for(int f=0; f<3; f++)
  {
    if((checkIndividualCollision(playerPos[0], playerPos[1], takistus[f][0], 0, 4, 4, 4, (takistus[f][1])) == HIGH) )
    {
      
      return HIGH;
    }
    if(checkIndividualCollision(playerPos[0], playerPos[1], takistus[f][0], ((takistus[f][1])+auk), 4, 4, 4, (47-(takistus[f][1]))) == HIGH) //auk is the size of the hole, predefiend 15
    {
      
      return HIGH;
    }
    else
    {
      return LOW;
    }
  }
  Serial.println("collision");
}

boolean checkIndividualCollision(int x1, int y1, int x2, int y2, int esimeneLaius, int esimeneKorgus, int teineLaius, int teineKorgus) 
//takes in position of object one x1, y1
//it's width and height esimeneLaius, esimeneKorgus
//same for the second object
{
  if (x1 < (x2 + teineLaius) &&  (x1 + esimeneLaius) > x2 && y1 < (y2 + teineKorgus) && (esimeneKorgus + y1) > y2) 
  {
    Serial.println("individual collision");
    return HIGH;// collision detected!
  }
  else
  {
    return LOW;
  }
}

Sorry, some of the variables are in estonian.

signed int takistus[][2] = { {84.00, 0 },
                             {112.00, 10},
                             {140.00, 20 } };

Why are you trying to store floats in an int array?

Why does checkIndividualCollision() return HIGH or LOW? booleans are to be assigned true or false.

Another approach here

Ray

Thank you for your replies!
Changed the array to float and now the boolean functions return true or false(as in mrburnette’s code).
Still only works on the first set of bars. The second and third bars don’t give out a collision signal.

Full code

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
float takistus[][2] = { {84.00, 0 },
                             {112.00, 10},
                             {140.00, 20 } }; //for every obstacele - x position and the position of a hole.

#define x_kang A5 //x axis joystick
#define y_kang A7 //y axis joystick
#define lyke 1 //how much to move the character
#define FPS 25 //how fast the game runs
int auk = 15; //size of the hole

signed int x_asi; //raw values for joystick
signed int y_asi; //raw values for joystick

int playerPos[] = {15, 23}; //initial position of the player

unsigned int score = 0; 
float postiKiirus = 0.5; //initial speed of posts


int interval = 1000/FPS; //interval in ms to refresh the screen
unsigned long previousMillis = 0;


Adafruit_PCD8544 display = Adafruit_PCD8544(5, 6, 7, 8, 9);

void setup() {
  
  Serial.begin(9600); //for debugging
  display.begin();
  display.setContrast(60);
  
  randomSeed(analogRead(A0));
  
  x_asi = analogRead(x_kang);
  y_asi = analogRead(y_kang);
  
  display.clearDisplay();
}


void obstacles() //draw the obstacles
{
  for(byte k=0; k<3; k++)
  {
    takistus[k][0] = takistus[k][0] - postiKiirus; //move the obstacle
    
    if(takistus[k][0] <= 0) //if the obstacle is off screen, move it to the beginning
    { 
      takistus[k][0] = 84;
      takistus[k][1] = random(0,30);
    }
  }
  for(byte k=0; k<3; k++)
  {    
    display.fillRect(takistus[k][0], 0, 4, 48, 1); //first draw a dark vertical bar
    display.fillRect(takistus[k][0], takistus[k][1], 4, auk, 0); //and then the hole
  }
}



void player() //move and draw the player
{
   
    x_asi = analogRead(x_kang);
    y_asi = analogRead(y_kang);

    if(x_asi < 600 &&  playerPos[0] <= 80)
    {
      playerPos[0] = playerPos[0] + lyke;
    }
    if(x_asi > 400 && playerPos[0] >= 0)
    {
      playerPos[0] = playerPos[0] - lyke;
    }
    
    if(y_asi > 600 && playerPos[1]  <= 44)
    {
      playerPos[1] = playerPos[1] + lyke;
    }
    if(y_asi < 400 && playerPos[1]  >= 0)
    {
      playerPos[1] = playerPos[1] - lyke;
    }

    
    display.fillRect(playerPos[0], playerPos[1], 4, 4, 1);
}



void setTempo() //every 1000 points, add tempo
{
  if((score % 1000) == 0)
  {
    postiKiirus = postiKiirus + 0.2;
  }
}



boolean checkCollision()//check players collision with the moving bars.
{
  boolean result = false;
  for(int f=0; f<3; f++)
  {
    if((checkIndividualCollision(playerPos[0], playerPos[1], takistus[f][0], 0, 4, 4, 4, (takistus[f][1])) == HIGH) )
    {
      result = true;
      return result;
    }
    if(checkIndividualCollision(playerPos[0], playerPos[1], takistus[f][0], ((takistus[f][1])+auk), 4, 4, 4, (47-(takistus[f][1]))) == HIGH)
    {
      
      result = true;
      return result;
    }
    else
    { 
      return result;

    }
  }
  Serial.println("porge");
}

boolean checkIndividualCollision(int x1, int y1, int x2, int y2, int esimeneLaius, int esimeneKorgus, int teineLaius, int teineKorgus) 
//takes in position of object one x1, y1
//it's width and height esimeneLaius, esimeneKorgus
//same for the second object

{
  boolean result2 = false;
  if (x1 < (x2 + teineLaius) &&  (x1 + esimeneLaius) > x2 && y1 < (y2 + teineKorgus) && (esimeneKorgus + y1) > y2) 
  {
    Serial.println("individual collision");
    result2 = true;
    return result2;
    // collision detected!
  }
  else
  {
    return result2;
  }
}

void EndGame() //if dead, reset the game variables
{
  
  playerPos[0] = 15; 
  playerPos[1] = 23;
  postiKiirus = 0.5;
  
  takistus[0][0] = 84.00;
  takistus[1][0] = 112.00;
  takistus[2][0] = 140.00;
  
  display.clearDisplay();
  display.setCursor(20, 0);
  display.print("Surnud!");
  display.setCursor(20, 15);
  display.print("Punktid");
  display.setCursor(20, 30);
  display.print(score);
  
  display.display();
    
  delay(2000);
  display.clearDisplay();
  score = 0;
  
  
}

void loop() {

  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    display.clearDisplay();
 
    setTempo(); //how fast obstacles move 
    obstacles(); //draw the obstacles
    player(); //draw the player
    
    if(checkCollision() == HIGH) //check if game is over
    {
     EndGame(); //show the score and reset game variables
    } 
    
    score++;
    
    display.setCursor(0, 0);
    display.print(score); //print the score
    
    display.display();//show everything

  }
}

desmond3: Thank you for your replies! Changed the array to float and now the boolean functions return true or false(as in mrburnette's code). Still only works on the first set of bars. The second and third bars don't give out a collision signal.

In function boolean checkCollision()//check players collision with the moving bars. Stop the game, print the array to serial, restart the game. The answer should be in the printout. Most monitor programs like TeraTermPro can spool to a disk file so you can examine it easier without fear of terminal buffer overload, a situation that is not know to be treatable by any drug therapy - often referred to in knowledgeable circles as TBO :fearful:

Ray

You are still comparing the boolean value to HIGH or LOW.