Reputation: 33
In a group called powerUpGroup
, there are two objects: speedUp
and jumpUP
. The following code checks if the player
object has collided with any objects in the group:
for eachPowerUp in powerUpGroup:
if pygame.sprite.spritecollide(eachPowerUp, playerGroup, False) :
eachPowerUp.kill()
Let's say I only want the program to print "Speed increased" when the player collides with speedUp
object. Based on the code above, it will print the message if it either speedUp
or jumpUP
since they are in the same group. Without creating a new group, is there a way for python to identify that they are different objects run certain code?
Upvotes: 3
Views: 47
Reputation: 33
The previous code was an equality test between two sprites, not a type of sprite. The variable speedUp
is one of your powerUpGroup
sprites. The if statement will only be true if the particular speedUp
that the player is colliding with is the particular speedUp
in that variable.
So I added a property.
In the constructor(That was not added in the OP), I have self.type = "multiShot"
or self.type = "speed"
, depending on which type it is. Then, an if statement would now be something like:
for eachPowerUp in powerUpGroup:
if pygame.sprite.spritecollide(eachPowerUp, playerGroup, False) :
if eachPowerUp.type == "multiShot" :
...
elif eachPowerUp.type == "speed" :
...
Upvotes: 0
Reputation: 458
Use an if statement to check if the power-up is speedUp
for eachPowerUp in powerUpGroup:
if pygame.sprite.spritecollide(eachPowerUp, playerGroup, False):
if eachPowerUp == speedUp:
print("Speed increased")
eachPowerUp.kill()
Edit for second part of question:
Instead of checking if the power up is a certain object, you can check if it is a certain class.
Say you have a class called SpeedUp
. You can check to see if eachPowerUp
is a SpeedUp
object and then print the message you wanted.
for eachPowerUp in powerUpGroup:
if pygame.sprite.spritecollide(eachPowerUp, playerGroup, False):
if type(eachPowerUp) == SpeedUp:
print("Speed increased")
eachPowerUp.kill()
Upvotes: 0
Reputation: 101122
If speedUp
and jumpUp
are different classes, you should implement their behaviour in their very classes (something something polymorphism):
The speepUp
class should contain the code for speeding up (or whatever it does) and trigger secondary effects (like displaying stuff to the player and removing itself from the game), and the jumpUp
class should do the same. Of course you could go down the abstraction rabbit hole but let's keep it simple.
Here's a litte example:
import pygame
from random import choice
class Actor(pygame.sprite.Sprite):
def __init__(self, color, pos, *grps):
super().__init__(*grps)
self.image = pygame.Surface((64, 64))
self.image.fill(color)
self.rect = self.image.get_rect(topleft=pos)
def update(self, events, dt):
pass
class Player(Actor):
def __init__(self, *grps):
super().__init__('dodgerblue', (400, 300), *grps)
self.pos = pygame.Vector2(self.rect.topleft)
self.dir = pygame.Vector2((0, 0))
self.speed = 300
def update(self, events, dt):
pressed = pygame.key.get_pressed()
self.dir.x, self.dir.y = (0, 0)
if pressed[pygame.K_d]: self.dir += ( 1, 0)
if pressed[pygame.K_a]: self.dir += (-1, 0)
if pressed[pygame.K_s]: self.dir += ( 0, 1)
if pressed[pygame.K_w]: self.dir += ( 0, -1)
if self.dir.length() > 0:
self.dir.normalize()
self.pos += self.dir * self.speed * dt
self.rect.topleft = self.pos
class PowerUp(Actor):
def __init__(self, color, pos, player, *grps):
super().__init__(color, pos, *grps)
self.player = player
def apply(self):
pass
def update(self, events, dt):
if pygame.sprite.collide_rect(self, self.player):
self.apply()
self.kill()
class SpeedUp(PowerUp):
def __init__(self, player, *grps):
super().__init__('yellow', (100, 100), player, *grps)
def apply(self):
print('Speed Up')
self.player.speed += 200
class ColorChange(PowerUp):
def __init__(self, player, *grps):
super().__init__('purple', (600, 300), player, *grps)
def apply(self):
print('ColorChange!')
self.player.image.fill(choice(['green', 'blue', 'yellow', 'grey']))
def main():
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock, dt = pygame.time.Clock(), 0
sprites = pygame.sprite.Group()
player = Player(sprites)
SpeedUp(player, sprites)
ColorChange(player, sprites)
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
screen.fill('black')
sprites.draw(screen)
sprites.update(events, dt)
pygame.display.flip()
dt = clock.tick(120)/1000
if __name__ == '__main__':
main()
Upvotes: 2