Colliderect seems to get triggered based on height

Question:

Currently I am trying to make flappy bird in pygame, but I have stumbled upon an issue where if the bird goes lower than the top of the lower pipe, it detects it as a collision. I also used collidelist as my pipe objects are stored in a list, to no avail. Heres the collision code:

    def collide(self):
        for pipe_rect in pipes:
            if self.rect.colliderect(pipe_rect):
                pipe.set_scroll(0)
                pipe2.set_scroll(0)
                print("You are dead, no big suprise")
                self.death = True

Here is all the code too if that helps:

import pygame, sys
from pygame.locals import QUIT
import random
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
GREY = (100, 100, 100)
CLOCK = pygame.time.Clock()

class Bird:
    def __init__(self):
        self.__x = 20
        self.__y = screen_y / 2
        self.__vel = 16
        self.death = False
    
    def flap(self):
        self.__vel = 16

    def gravity(self):
        self.__y -= self.__vel
        self.__vel -= 2
        if self.__vel > 15:
            self.__vel = 15
        if self.__y > (screen_y - 50):
            self.__y = screen_y - 50

    def draw(self):
        self.rect = pygame.draw.rect(DISPLAYWINDOW, YELLOW, (self.__x, self.__y, 50, 50))

    def collide(self):
        for pipe_rect in pipes:
            if self.rect.colliderect(pipe_rect):
                pipe.set_scroll(0)
                pipe2.set_scroll(0)
                print("damn you collision")
                self.death = True


class Pipe:
    def __init__(self, x):
        self.__x = x
        self.__y = 300
        self.__w = 70
        self.__h = 700
        self.__scroll = 7.5       #world scroll

    def get_w(self):
        return self.__w

    def set_scroll(self, x):
        self.__scroll = x

    def move(self):
        self.__x -= self.__scroll

    def draw(self):
        pipes.append(pygame.draw.rect(DISPLAYWINDOW, WHITE, (self.__x, self.__y, self.__w, self.__h))) #bottom
        #pipes.append(pygame.draw.rect(DISPLAYWINDOW, WHITE, (self.__x, ((self.__y - self.__h) - 250), self.__w, self.__h))) #top 150 is 3x bird height

    def generation(self):
        if self.__x < 0 - self.__w:
            self.__y = random.randint(275, 450)
            self.__x = screen_x + self.__w



pipes = []
pygame.init()
screen_x = 500
screen_y = 700
DISPLAYWINDOW = pygame.display.set_mode((screen_x, screen_y))
bird = Bird()
pipe = Pipe(screen_x)
pipe2 = Pipe((screen_x * 1.5) + pipe.get_w())

while True:
  for event in pygame.event.get():
    if event.type == QUIT:
      pygame.quit()
      sys.exit()
    if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and bird.death == False:
      bird.flap()
        
  DISPLAYWINDOW.fill(GREY)
  bird.draw()
  bird.gravity()
  bird.collide()
  pipe.draw()
  pipe2.draw()
  pipe.move()
  pipe2.move()
  pipe.generation()
  pipe2.generation()
  pygame.display.update()
  CLOCK.tick(30)

Asked By: Apple_Retainer

||

Answers:

The problem is that the pipes list is filled with pipes that are never removed. You can easily test this by inserting print(len(pipe)) into the application loop.
You must create or delete the pipe list in the application loop before adding the new pipes:

while True:
  for event in pygame.event.get():
    if event.type == QUIT:
      pygame.quit()
      sys.exit()
    if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and bird.death == False:
      bird.flap()

  # clear screen
  DISPLAYWINDOW.fill(GREY)

  # clear pipes
  pipes.clear()
  # draw pipes and add new pipes to list
  pipe.draw()
  pipe2.draw()
  print(len(pipes))

  # draw bird and collision detection
  bird.draw()
  bird.collide()

  # move objects
  bird.gravity()
  pipe.move()
  pipe2.move()

  # generate new objects
  pipe.generation()
  pipe2.generation()

  pygame.display.update()
  CLOCK.tick(30)
Answered By: Rabbid76
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.