Shorter way to make colliderect in if statement work?
Question:
I have two objects:
#Object1
enemigo=pygame.image.load("enemigo.png").convert_alpha()
enemigo=pygame.transform.scale(enemigo, (100, 100))
enemigo_rectangulo=enemigo.get_rect(center=(1000, 100))
#Object2
enemigo2=pygame.image.load("enemigo2.png").convert_alpha()
enemigo2=pygame.transform.scale(enemigo2, (140, 140))
enemigo_rectangulo2=enemigo2.get_rect(center=(1400, 50))
And I want to make an if
statement if they collide with a third object. This code actually works but is too long:
if personaje_rectangulo.colliderect(enemigo_rectangulo) or personaje_rectangulo.colliderect(enemigo_rectangulo2):
And there’s an error when I try to write:
if personaje_rectangulo.colliderect(enemigo_rectangulo, enemigo_rectangulo2):
So, what is wrong? Is there a shorter way to write it?
Answers:
The first thing you can do is use shorter variable names, such as personaje
and enemigo
.
Additionally, break the statement into smaller pieces by using variables:
hit_enemy1 = personaje_rectangulo.colliderect(enemigo_rectangulo)
hit_enemy2 = personaje_rectangulo.colliderect(enemigo_rectangulo2)
if hit_enemy1 or hit_enemy2:
pass
Alternatively, if you store all of the enemies in a list, you can use any()
:
if any(personaje_rectangulo.colliderect(enemigo_rectangulo) for enemigo_rectangulo in todos_enemigos):
pass
Now this is also getting long so creating a function to help can shorten the line of code:
def collision(person, enemy):
return person.colliderect(enemy)
if any(collision(person, enemy) in todos_enemigos):
pass
Another solution is to create a Enemy
class which encapsulates the data and behavior of an enemy. This is a bit more advanced, but definitely a good exercise to learn what classes are and how to use them.
Use collidelist()
:
Test whether the rectangle collides with any in a sequence of rectangles. The index of the first collision found is returned. If no collisions are found an index of -1 is returned.
if personaje_rectangulo.collidelist([enemigo_rectangulo, enemigo_rectangulo2]) >= 0:
I have two objects:
#Object1
enemigo=pygame.image.load("enemigo.png").convert_alpha()
enemigo=pygame.transform.scale(enemigo, (100, 100))
enemigo_rectangulo=enemigo.get_rect(center=(1000, 100))
#Object2
enemigo2=pygame.image.load("enemigo2.png").convert_alpha()
enemigo2=pygame.transform.scale(enemigo2, (140, 140))
enemigo_rectangulo2=enemigo2.get_rect(center=(1400, 50))
And I want to make an if
statement if they collide with a third object. This code actually works but is too long:
if personaje_rectangulo.colliderect(enemigo_rectangulo) or personaje_rectangulo.colliderect(enemigo_rectangulo2):
And there’s an error when I try to write:
if personaje_rectangulo.colliderect(enemigo_rectangulo, enemigo_rectangulo2):
So, what is wrong? Is there a shorter way to write it?
The first thing you can do is use shorter variable names, such as personaje
and enemigo
.
Additionally, break the statement into smaller pieces by using variables:
hit_enemy1 = personaje_rectangulo.colliderect(enemigo_rectangulo)
hit_enemy2 = personaje_rectangulo.colliderect(enemigo_rectangulo2)
if hit_enemy1 or hit_enemy2:
pass
Alternatively, if you store all of the enemies in a list, you can use any()
:
if any(personaje_rectangulo.colliderect(enemigo_rectangulo) for enemigo_rectangulo in todos_enemigos):
pass
Now this is also getting long so creating a function to help can shorten the line of code:
def collision(person, enemy):
return person.colliderect(enemy)
if any(collision(person, enemy) in todos_enemigos):
pass
Another solution is to create a Enemy
class which encapsulates the data and behavior of an enemy. This is a bit more advanced, but definitely a good exercise to learn what classes are and how to use them.
Use collidelist()
:
Test whether the rectangle collides with any in a sequence of rectangles. The index of the first collision found is returned. If no collisions are found an index of -1 is returned.
if personaje_rectangulo.collidelist([enemigo_rectangulo, enemigo_rectangulo2]) >= 0: