Search code examples
pythonpygame

Why blocks don't collide with ball


I want ball to collide with blocks but ball don't. plane is name about bar which player can move (70,10) block(brick)is brick that player must break(80,40) game size is (480*640) here is create block

if block is less than 30 block create by randomly in random space

    while len(wblock) <= 30:
        down = random.randint(0, 9)
        right = random.randint(0, 6)
        wb = random.randint(1,42)
        wblock.append([right*80, down*40, wb])

when down and right is point block size is 80*40

    if wball[0] >= 460:
        bx = bx*(-1)
    if wball[0] == 0:
        bx = bx*(-1)
    if wball[1] >= 640:
        running = False
    if wball[1] == 0:
        by = by*(-1)
    wball[0] += bx*2
    wball[1] += by*2
    screen.blit(ball, (wball[0],wball[1]))
    ballrect = pygame.Rect(ball.get_rect())
    ballrect.left = wball[0]
    ballrect.right = wball[1]

here is ball and bar collide also , boll go through of bar... why

    position = pygame.mouse.get_pos()
    planepos = (position[0], 600)
    position[0]
    screen.blit(plane, planepos)
    planerect = pygame.Rect(plane.get_rect())
    planerect.left = planepos[0]
    planerect.top = planepos[1]
    if planerect.colliderect(ballrect):
       by = by*(-1)
       print(by)

now this code is collide of ball and block

    index = 0
    for brick in wblock:
        index += 1
        brickrect = pygame.Rect(blocks[brick[2]].get_rect())
        brickrect.left=brick[0]
        brickrect.top=brick[1]
        if brickrect.colliderect(ballrect):
            wblock.pop(index)
            by = by*(-1)
            index -= 1
        screen.blit(blocks[brick[2]], (brick[0],brick[1]))



    fpsClock.tick(FPS)
    pygame.display.flip()

screen.blit(gameover, (10,100))
pygame.display.flip()

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit(0)
    pygame.display.flip()

is my code. could get my question?

when ball move he move through blocks and stuck in sky


Solution

  • The mjaor issue is when you set up the ballrect. You have to set ballrect.top rather than ballrect.right:

    ballrect = pygame.Rect(ball.get_rect())
    ballrect.left = wball[0]
    ballrect.top = wball[1] # <---- `top` instead of `right`
    

    Note, you can set the position of the rectangle by an keyword argument, when you retrieve the rectangle from the pygame.Surface (see pygame.Surface.get_rect):

    ballrect = ball.get_rect(topleft = wball)
    

    Furthermore the rectangular area which is covered by the Surface is returned by pygame.Surface.blit:

    ballrect = screen.blit(ball, wball)
    

    If you want to evaluate, if the ball is in bounds, then you have to evaluate if the right of the ball does not exceed the right of the screen, the left does not exceed the left, the top does not exceed the top and the bottom does not exceed the bottom.
    Create pygame.Rect object for the ball and compare the left, right, top an bottom of the rectangle to bounds. Invert bx respectively by if the ball is out of bounds:

    screerect = screen.get_rect()
    ballrect = ball.get_rect(topleft = wball)
    
    if ballrect.left <= 0 or ballrect.right >= screerect.right:
        bx = -bx
    if ballrect.top <= 0 or ballrect.bottom >= screerect.bottom:
        by = -by
    
    wball[0] += bx*2
    wball[1] += by*2
    
    ballrect = screen.blit(ball, wball)