Geordyd
Geordyd

Reputation: 165

Wall collision in pygame

I am trying to get collision to work but when the two rectangles collide they go a little bit into each other but I want the second rectangle to act like a wall. Does someone have any idea how I could fix this? Or is there maybe a better way to add collision to my game? This is what I have right now.

import pygame

pygame.init()
screen = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Squarey")
done = False
is_red = True
x = 30
y = 30
x2 = 100
y2 = 30
clock = pygame.time.Clock()
WHITE = (255,255,255)
RED = (255,0,0)

charImg = pygame.image.load('character.png')



rect1 = pygame.Rect(30, 30, 60, 60)

rect2 = pygame.Rect(100, 100, 60, 60)

x_change = 0
y_change = 0

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True


#movement
      #left
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_LEFT:
        x_change = -5
        y_change = 0

        #right
      elif event.key == pygame.K_RIGHT:
        x_change = 5
        y_change = 0
      #key release left and right
    if event.type == pygame.KEYUP:
      if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
        x_change = 0
        y_change = 0


      #up    
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_UP:
        y_change = -5
        x_change = 0


        #down
      elif event.key == pygame.K_DOWN:
        y_change = 5
        x_change = 0


      #key release up and down
    if event.type == pygame.KEYUP:
      if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
        y_change = 0
        x_change = 0 
    rect1.x = rect1.x + x_change
    rect1.y = rect1.y + y_change

    screen.fill((0, 0, 0))

    pygame.draw.rect(screen, WHITE, rect1)
    pygame.draw.rect(screen, RED, rect2)

    if rect1.bottom > screen.get_rect().bottom:
      rect1.center = screen.get_rect().center

    #if rect1.colliderect(rect2):
    if rect1.colliderect(rect2):
      #print("Collision !!")

      rect1.x = rect1.x - x_change
      rect1.y = rect1.y - y_change

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Upvotes: 4

Views: 1875

Answers (2)

Art
Art

Reputation: 3089

The only problem with your program is that you are drawing rect before checking for collision.

Since, there aren't many answers I am writing one for others. You would require two variables x and y to store the previous position i.e. position before the collision. Then you would need to check if the two rectangles have collided using Rect.colliderect. If they have collided reset the current position to the previous position, then draw the wall.

import pygame

pygame.init()
screen = pygame.display.set_mode((1000, 800))

done = False

clock = pygame.time.Clock()

WHITE = (255,255,255)
RED = (255,0,0)

rect1 = pygame.Rect(30, 30, 60, 60)
rect2 = pygame.Rect(100, 100, 60, 60)

previous_x, previous_y = 0, 0
x_change, y_change = 0, 0

speed = 5

while not done:

    screen.fill((0, 0, 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_LEFT:
                x_change = -speed
                y_change = 0

            if event.key == pygame.K_RIGHT:
                x_change = speed
                y_change = 0

            if event.key == pygame.K_UP:
                y_change = -speed
                x_change = 0

            if event.key == pygame.K_DOWN:
                y_change = speed
                x_change = 0

        if event.type == pygame.KEYUP:
            x_change = 0
            y_change = 0

    previous_x = rect1.x
    previous_y = rect1.y

    rect1.x = rect1.x + x_change
    rect1.y = rect1.y + y_change

    if rect1.colliderect(rect2):
        print("Collision")
        rect1.x = previous_x
        rect1.y = previous_y

    pygame.draw.rect(screen, WHITE, rect1)
    pygame.draw.rect(screen, RED, rect2)

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

If you have many walls store all of their rect in a list. Then use pygame's Rect.collidelist to check if there is any collision.(note: collidelist returns -1 if there is no collision). If there are any then reset to the previous position.

Upvotes: 1

Shark Coding
Shark Coding

Reputation: 143

you are drawing the rectangles before setting them back when they hit each other so they move into each other for a moment. Make sure to do all drawing after calculations have been made.

Upvotes: 1

Related Questions