Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difficiating objects in a group

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?

like image 709
Daeshaun Morrison Avatar asked Dec 06 '25 11:12

Daeshaun Morrison


1 Answers

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()

enter image description here

like image 71
sloth Avatar answered Dec 09 '25 00:12

sloth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!