Reputation: 165
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
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
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