1

I am working with pygame libary. I have Actor classes (for game objects) and ActorContext classes (for game object lists):

class ActorContext:
    list = []
    alpha_range = 255
    time_diff = 0
    alpha_diff = 0

    def add(self, obj: Actor):
        self.list.append(obj)

In my main app I define objects:

enemy_context = ActorContext()
bullet_context = ActorContext()
dummy_context = ActorContext()

Later, in a loop, I create and add objects to those contexts:

            if event.key == pg.K_e:
                e = Enemy(img_src=enemy)
                e.rand_change()
                e.rand_pos()
                enemy_context.add(e)
            if event.key == pg.K_r:
                if len(enemy_list) > 0:
                    enemy_context.remove(1)

The problem is that when I call enemy_context.add(e), the same value is added in all lists of objects: enemy_context, bullet_context and dummy_context

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Matej J
  • 615
  • 1
  • 9
  • 33
  • 1
    Do the initialization in `__init__`, not at the class level. – tobias Jun 23 '21 at 22:25
  • There's just one `list` attribute, shared by all the instances. – Barmar Jun 23 '21 at 22:26
  • @tobias, how do you mean? initialization of context? I am running this in a loop, I cannot create new context each time I need to add new object... – Matej J Jun 23 '21 at 22:29
  • @Barmar what should I do in this case? I also tried creating multiple sub-classes for context, but the result is still the same. Could I somehow create a copy of existing object with a different reference? – Matej J Jun 23 '21 at 22:30
  • [Pygame Zero](https://pygame-zero.readthedocs.io/en/stable/) is not [PyGame](https://www.pygame.org/news). You have to use the [tag:pgzero] tag instead of the [tag:pygame] tag. – Rabbid76 Jun 24 '21 at 04:52

3 Answers3

2

Per-instance attributes should be initialized in the __init__ method, not as class attributes.

class ActorContext:
    alpha_range = 255
    time_diff = 0
    alpha_diff = 0

    def __init__(self):
        self.list = []

    def add(self, obj: Actor):
        self.list.append(obj)
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

You should adjust your class this way:

class ActorContext:
    alpha_range = 255
    time_diff = 0
    alpha_diff = 0

    def __init__(self):
        self.list = []

    def add(self, obj: Actor):
        self.list.append(obj)

This makes sure the list is an instance attribute, not a class attribute. It will now be separate for all instances of ActorContext.

The __init__(self) function is what's called a constructor - a special function called whenever you create an instance of related object, like ActorContext().

Captain Trojan
  • 2,800
  • 1
  • 11
  • 28
0

Try to define your class ActorContext like this :

class ActorContext:
    def __init__(self):
        self.list = []
        self.alpha_range = 255
        self.time_diff = 0
        self.alpha_diff = 0

    def add(self, obj: Actor):
        self.list.append(obj)

Does it worked ?

Yvant2000
  • 11
  • 4