Вопрос или проблема
У меня есть класс под названием 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
не окажут на них влияния.