3

I have collisions but I'd like my code to work so that when the bird touches the blocks, it print('x'). It is doing that but not in the right place of the bird. Apologies for the long code but it is needed for it to run.

import random
import pygame

vec = pygame.math.Vector2

BLACK = (0,0,0)
RED = (255,0,0)

WIDTH = 500
HEIGHT = 400

pygame.init()
window = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Flappy Bird')
clock = pygame.time.Clock()

class Bird():

    def __init__(self):
        self.skin = pygame.image.load('bird2.png')
        self.rect = self.skin.get_rect()
        self.rect.center = (WIDTH / 2, HEIGHT / 2)

        self.vx = 0
        self.vy = 0

        self.pos = vec(WIDTH / 2, HEIGHT / 2)
        self.vel = vec(0, 0)
        self.acc = vec(0, 0)

    def update(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        window.fill(BLACK)
        self.acc = vec(0, 0.7) #having 0.5 adds gravity

        self.vy = 0

        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE]:
            self.vel.y = -7

        if keys[pygame.K_LEFT]:
            self.acc.x = -0.5  #change to y to add vertical motion

        if keys[pygame.K_RIGHT]:
            self.acc.x = 0.5   #change to y to add vertical motion

        #applys friction
        self.acc.x += self.vel.x * -0.08 #FRICTION
        #motion equations
        self.vel += self.acc
        self.pos += self.vel + 0.5 * self.acc

        self.rect.center = self.pos

        window.blit(self.skin, self.pos)

class Pipe():

    def __init__(self,x,y):

        self.image = pygame.Surface((50,60))
        self.image.fill(RED)
        self.rect = self.image.get_rect(topleft=(x,y))

        self.pos = vec(x,y)

    def blit_pipe(self):
        window.blit(self.image, self.pos)

def border_check():
    if (flappy.pos.y)+32 > HEIGHT: #this is the very top of the flappy
        print("You are under\n")
        pygame.quit()
        quit()

    if flappy.pos.y < 0:
        print("You are over\n") #this is the very top of the flappy
        pygame.quit()
        quit()


pipey = Pipe(300,200)
pipey.blit_pipe()

pipey2 = Pipe(100,200)
pipey2.blit_pipe()

flappy = Bird()

window.blit(flappy.skin, flappy.pos)

while True:
    border_check()
    flappy.update()
    pipey.blit_pipe()
    pipey2.blit_pipe()

    if flappy.rect.colliderect(pipey.rect):
        print('x')

    clock.tick(30)
    pygame.display.update()

The bird looks like enter image description here, and I would like the rect to be enter image description here but in the game it works more likeenter image description here. I think the problem is that the rect has its center in the topleft but I don't know how to change it

Crawley
  • 600
  • 2
  • 8
  • 15

2 Answers2

4

You need to blit the image at the top left coords of the rect. You can either set the center to self.pos and pass the rect as the blit position (then pygame uses the top left coords),

self.rect.center = self.pos
window.blit(self.skin, self.rect)

or set the topleft attribute to self.pos, then you can still blit the image at the self.pos:

self.rect.topleft = self.pos
window.blit(self.skin, self.pos)
skrx
  • 19,980
  • 5
  • 34
  • 48
1

When drawing rectangles in pygame, the first 2 parameters are X and Y starting point, then the next 2 parameters are width and height. This will draw the rectangle form the top left corner. What you need to do, is have an image where the edge if the bird is the edge of the image. You can then do something like:

pygame.draw.rect(screen, red, [topLeftX, topLeftY, birdWidth, birdHeight])

An alternative, if you can't edit the picture, just use a + sign for slight adjustment.

George_E -old
  • 188
  • 1
  • 3
  • 17