0

I am learning to make 2d games with c++ using the SFML libraries. I am currently working on a flappy bird clone. Most of the functionality works (the pipes move and the bird jumps/falls); however, the collision detection is unacceptably inaccurate. The bird dies when it is exactly between the two pipes, where it should not. Here is the collision detection code:

  bool checkCollision(int x, int y, int w, int h, int xTwo, int yTwo, int wTwo, int hTwo){
    IntRect birdRect(x,y,w,h);
    IntRect pipeRect(xTwo,yTwo,wTwo,hTwo);

    return birdRect.intersects(pipeRect);
  }

  void logic(){
    if(bird->getY() + 45 > h-150){
      gameover = true;
    }

    int birdX = bird->getX();
    int birdY = bird->getY();
    int birdW = bird->getW();
    int birdH = bird->getH();

    for(int i=0;i<pipes.size();i++){
      int pipeX = pipes[i]->getX();
      int pipeY = pipes[i]->getY();
      int pipeW = 150;
      int pipeH = pipes[i]->getH();

      if(checkCollision(birdX,birdY,birdW,birdH,pipeX,pipeY,pipeW,pipeH)){
        cout<<i<<endl;
        gameover = true;
      }

    }

  } 

And if you need it, here are the bird and pipe functions:

class Bird{
private:
  //global variables
  int y;
  int originalY;
  int x;
  float velocityY;
  const float thrust = 30;
  float gravity;
  int screenH, screenW;
  const float w = 110.0;const float h = 80.0;
  Texture birdTexture;
private:
  //private functions

public:
  //public functions
  Bird(int grav, int width, int height){
    screenH = height;screenW = width;

    y = height/2; x = width/4;
    originalY = y;

    gravity = grav;

    velocityY = 0;

    birdTexture.loadFromFile("art/bird.png");

  }

  //inline functions
  inline int getY(){return y;}
  inline int getX(){return x;}
  inline int getW(){return w;}
  inline int getH(){return h;}

  void Update(){

    if(y+40 < screenH){//above ground
      velocityY += gravity;
    }else if(y+40 < screenH){//below ground
      y = screenH-40;
    }else{//on ground
      if (velocityY > 0 ){
        velocityY = 0;
      }
    }



    y += velocityY;

  }

  void Jump(){
    velocityY -= thrust;
    velocityY += pow(velocityY,2)*.015;

  }

  void Draw(RenderWindow& window){
    RectangleShape birdShape(Vector2f(w,h));
    birdShape.setPosition(x+w/2,y+h/2);
    birdShape.setTexture(&birdTexture);

    birdShape.setOutlineColor(Color::Black);
    birdShape.setOutlineThickness(2.0f);

    window.draw(birdShape);
  }
};

class Pipe{
private:
  //global variables
  int x,y;
  const float w = 150;
  float h;
  bool top;

  Texture topPipeTexture;
  Texture bottomPipeTexture;

private:
//private functions

public:
//public functions
  Pipe(int height, int screenW, int screenH, bool isTop){
    h = height;
    x  = screenW;
    top = isTop;
    topPipeTexture.loadFromFile("art/top pipe.png");
    bottomPipeTexture.loadFromFile("art/bottom pipe.png");
    if (top){
      y = h/2;
    }else{
      y = screenH - (h/2)-150;
    }
  }

  //inline functions
  inline int getX(){return x;}
  inline int getY(){return y;}
  inline int getH(){return h;}
  inline int getW(){return w;}
  inline bool isTop(){return top;}

  void Update(float speed){
    x -= speed;
  }

  void Draw(RenderWindow& window){
    RectangleShape pipeShape(Vector2f(w,h));

    if(top){
      pipeShape.setTexture(&topPipeTexture);
    }else{
      pipeShape.setTexture(&bottomPipeTexture);
    }

    pipeShape.setPosition(x,y-h/2);

    pipeShape.setOutlineColor(Color::Black);
    pipeShape.setOutlineThickness(2.0f);

    window.draw(pipeShape);
  }
};
  • 1
    How do you know it fails? Are you just looking at your game and seeing "game over", what if it were one of the other ways it could cause gameover? If you haven't already you should put a breakpoint after `if (checkCollision(...))` and then inspect the variables, or at least `cout` them when they fail. Your `checkCollision` function could be perfect, but perhaps one of the variables in set erroneously. – Tas Jul 15 '19 at 01:46
  • I tried that, I am pretty sure that my collision detection is the problem. The only other way to trigger game over is by hitting the ground, and when I commented that part out, it still had the same problem. –  Jul 15 '19 at 01:54
  • 1
    Are bird.x and bird.y the top left corner or the center of the bird? – Michael Mahn Jul 15 '19 at 02:17
  • 1
    I think that might have been the problem: the x and y were in the center, but I was doing the collision detection with them at the corners. –  Jul 15 '19 at 02:23

0 Answers0