I just want this code optimized to the max and I don't mind knowing if the optimization is pretty much at the max already or if I am doing movement and collision wrong. My game is a 2d Minecraft style game so it will have a lot of other_rects
. Hopefully my code is easy to read.
Code:
def move(rect, movement, other_rects): # move one axis at a time, returns moved rect and info on collisions
collisions = [0, 0, 0, 0] # left, right, up, down
if movement.x:
rect.x += movement.x
if movement.x < 0:
for tile in [tile for tile in other_rects if rect.colliderect(tile)]:
rect.left = tile.right
collisions[0] = 1
else:
for tile in [tile for tile in other_rects if rect.colliderect(tile)]:
rect.right = tile.left
collisions[1] = 1
if movement.y:
rect.y += movement.y
if movement.y < 0:
for tile in [tile for tile in other_rects if rect.colliderect(tile)]:
rect.top = tile.bottom
collisions[2] = 1
else:
for tile in [tile for tile in other_rects if rect.colliderect(tile)]:
rect.bottom = tile.top
collisions[3] = 1
return rect, collisions
Code for testing:
import pygame
import pygame.math
pygame.init()
pygame.display.set_caption('Physics')
screen = pygame.display.set_mode((500,500),0,32)
clock = pygame.time.Clock()
player = pygame.Rect(100,100,40,80)
tiles = [pygame.Rect(200,350,50,50),pygame.Rect(260,320,50,50)] # could be made bigger
speed = 5
def move(rect, movement, other_rects):
... # put move function here
while 1:
movement = pygame.math.Vector2(0)
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit()
exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and not keys[pygame.K_d]:
movement.x -= speed
if keys[pygame.K_d] and not keys[pygame.K_a]:
movement.x += speed
if keys[pygame.K_w] and not keys[pygame.K_s]:
movement.y -= speed
if keys[pygame.K_s] and not keys[pygame.K_w]:
movement.y += speed
player = move(player,movement,tiles)[0]
screen.fill((0,0,0))
pygame.draw.rect(screen,(255,255,255),player)
for tile in tiles:
pygame.draw.rect(screen,(255,0,0),tile)
pygame.display.update()
clock.tick(60)
for tile in filter(rect.colliderect, other_rects):
\$\endgroup\$if movement.x < 0:
statement are reversed. The way all thefor tile...
loops are coded, the rect sides are set based on the last colliding tile, rather than the closest tile in that direction. \$\endgroup\$