Переменная в классе Pygame постоянно обновляется, когда не должна [закрыто]

Вопрос или проблема

У меня есть класс под названием Magic, а также класс под названием Player. В классе Player есть переменная под названием self.direction, которая является pygame.math.Vector2 (), и я обновляю её в функции ввода. Однако, когда я создаю класс Magic в функции ввода в классе Player, я передаю переменную self.direction как направление. Я хотел, чтобы направление соответствовало тому, когда был создан класс Magic, и не изменялось. Но когда я запускаю код, направление, похоже, постоянно обновляется до self.direction в классе Player, даже когда этого не должно быть. Ниже приведен код:

class Magic(pygame.sprite.Sprite):

    def __init__(self,pos,groups,dir):

        super().__init__(groups)
        self.image = pygame.image.load('rock.png').convert_alpha()
        self.rect = self.image.get_rect(topleft = pos)
        self.direction = dir
        print("я был вызван")
    def move(self):

        self.rect.center  += self.direction
        print(self.rect.center)
        #print(self.direction)                                                                                                                                                                                                                                                                                                         
    def update(self):
        self.move()

class Player(pygame.sprite.Sprite):
    def __init__(self,pos,groups,obstacles_sprites,visible_sprites):
        super().__init__(groups)
        global plr
        self.image = pygame.image.load('player.png').convert_alpha()
        self.rect = self.image.get_rect(topleft = pos) 
        self.direction = pygame.math.Vector2()
        self.obstacle_sprites = obstacles_sprites
        self.visible_sprites = visible_sprites
        plr = self.image.get_rect()
    def input(self):

        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP]:
            self.direction.y = -1   

        elif keys[pygame.K_DOWN]:
            self.direction.y = 1
        else:
            self.direction.y = 0 
        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
            self.collision("Horizontal")
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0
        if keys[pygame.K_SPACE]:
            Magic((self.rect.x + 50,self.rect.y),[self.visible_sprites],self.direction)
    def move(self):
        self.rect.x += self.direction.x * 5 
        self.collision('Horizontal')
        self.rect.y += self.direction.y * 5
        self.collision('Vertical')
    def collision(self,direction):
        global collided
        global loc
        if direction == "Horizontal":
            if self.direction.x > 0:
                for sprite in self.obstacle_sprites:
                    if self.rect.colliderect(sprite.rect):
                        self.rect.right = sprite.rect.left
            if self.direction.x < 0:
                for sprite in self.obstacle_sprites:
                    if self.rect.colliderect(sprite.rect):
                        self.rect.left = sprite.rect.right
        if direction == "Vertical":
            if self.direction.y > 0:
                for sprite in self.obstacle_sprites:
                    if self.rect.colliderect(sprite.rect):
                        self.rect.bottom = sprite.rect.top

                        #print(sprite.rect.topleft)
                        for i in loc:
                            if sprite.rect.topleft == i:
                                collided = True
                                self.rect.top = sprite.rect.bottom

            if self.direction.y < 0:
                for sprite in self.obstacle_sprites:
                    if self.rect.colliderect(sprite.rect):
                        self.rect.top = sprite.rect.bottom

                        #print(sprite.rect.topleft)
                        for i in loc:

                            if sprite.rect.topleft == i:
                                collided = False
                                self.rect.bottom = sprite.rect.top

    def update(self):
        global plr
        self.input()
        self.move()
        plr = (self.rect.x,self.rect.y)
        #print(self.rect.x)

Ответ или решение

Ваша проблема связана с тем, что вы передаете объект self.direction в качестве аргумента в класс Magic. Поскольку self.direction — это объект типа pygame.math.Vector2, передача его напрямую в конструктор класса Magic создает ссылку на тот же самый объект, а не его копию. В результате, когда вы обновляете self.direction в классе Player, это также изменяет direction в объекте Magic, поскольку они ссылаются на один и тот же объект.

Чтобы решить эту проблему, вам нужно создать копию вектора направления при передаче его в класс Magic. Вы можете сделать это с помощью метода .copy(). Вот как вы можете изменить вашу функцию input в классе Player:

def input(self):
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]:
        self.direction.y = -1   
    elif keys[pygame.K_DOWN]:
        self.direction.y = 1
    else:
        self.direction.y = 0 
    if keys[pygame.K_RIGHT]:
        self.direction.x = 1
        self.collision("Horizontal")
    elif keys[pygame.K_LEFT]:
        self.direction.x = -1
    else:
        self.direction.x = 0
    if keys[pygame.K_SPACE]:
        # Создание копии self.direction
        Magic((self.rect.x + 50, self.rect.y), [self.visible_sprites], self.direction.copy())

Теперь, когда вы вызываете Magic((self.rect.x + 50, self.rect.y), [self.visible_sprites], self.direction.copy()), вы создаете новую копию вектора направления, которая не будет изменяться при обновлении self.direction в классе Player.

В дополнение, в классе Magic, вам не нужно вносить изменения. Он будет работать как и прежде:

class Magic(pygame.sprite.Sprite):
    def __init__(self, pos, groups, dir):
        super().__init__(groups)
        self.image = pygame.image.load('rock.png').convert_alpha()
        self.rect = self.image.get_rect(topleft=pos)
        self.direction = dir  # Теперь это копия вектора
        print("i have been called")

    def move(self):
        self.rect.center += self.direction
        print(self.rect.center)

    def update(self):
        self.move()

С помощью этих изменений ваши экземпляры класса Magic будут сохранять значение направления на момент создания, и изменения в self.direction в классе Player не окажут на них влияния.

Оцените материал
Добавить комментарий

Капча загружается...