Попробуйте добавить print(lastmove) перед движением пуль.
Добавлю пару непрошенных советов:
if right == True: #заменить на if right:
if по определению срабатывает если условие равно True. Сравнение избыточно.
if keys[pygame.K_a] and x>5:
x -= speed
left = True
right = False
up = False
down = False
Очень много кода, и как следствие легко допустить ошибку. Используйте векторное представление направления. x и y будут иметь значения -1, 0 или 1.
https://www.pygame.org/docs/ref/math.html вам поможет удобно работать с такими векторами.
direction = Vector2(0, 0)
if keys[pygame.K_s] and y<1920 - tall -5:
direction.y = 1
if keys[pygame.K_w] and y>5:
direction.y = -1
if keys[pygame.K_a] and x>5:
direction.x = -1
if keys[pygame.K_d] and x<1920 - wide -5:
direction.x = 1
if direction.length() != 0:
last_direction = direction
pos += direction * speed;
if keys[pygame.K_f]:
if len(bullets) <= 100:
bullets.append(Bullet(pos + gun_offset, (255, 0, 0), last_direction ))
for bullet in bullets:
bullet.pos += bullet.speed
window_rect = pygame.Rect(0, 0, 1920, 1080) #можно определить глобально 1 раз
if not window_rect.collidepoint(bullet.pos):
bullets.pop(bullets.index(bullet))
if keys[pygame.K_s] and y<1920 - tall -5:
Может быть чуть удобнее не смешивать регистрацию нажатий и контроля позиции. используйте window_rect.contains для этого непосредственно перед тем как изменить позицию игрока.
P.S.
Раньше pygame хотел обязательно int координаты при рисовании, поэтому Vector2 приходилось преобразовывать в пару int:
def vec_to_int(vec):
return (int(vec.x), int(vec.y))
pygame.draw.circle(screen, self.color, vec_to_int(self.pos), self.radius)
Но вроде как они это поправили, так что может это и не понадобится.