Порождение нескольких экземпляров класса в разных x позициях - PullRequest
1 голос
/ 10 ноября 2019

Я делаю клон Понг в Pygame, но у меня проблемы с порождением весла. Мой класс весла выглядит следующим образом:

class Paddle(pygame.sprite.Sprite, x_pos):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((20,70))
        self.image.fill(colors["WHITE"])
        self.rect = self.image.get_rect()
        self.rect.x = x_pos
        self.rect.y = SCREEN_HEIGHT/2
        self.y_speed = 0

И я пытаюсь породить двух из них на противоположных сторонах экрана с

player1 = Paddle(SCREEN_WIDTH - self.image.get_width() - 10) # Adjust for paddle width and border
player2 = Paddle(10)

Но я получаю ошибку

Traceback (most recent call last):
  File "pypong.py", line 19, in <module>
    class Paddle(pygame.sprite.Sprite, x_pos):
NameError: name 'x_pos' is not defined

Я попытался заменить self.rect.x = x_pos на self.rect.x_pos = self.x_pos, но все равно получаю ту же ошибку. Я думал, что овладеваю ООП, но это заставило меня замкнуться. Кто-нибудь может помочь? Заранее спасибо.

1 Ответ

2 голосов
/ 10 ноября 2019

Итак, у класса, который вы определили, есть некоторые проблемы, и я думаю, что стоит сначала пройтись по некоторым основам, а затем взглянуть на второй урок. Я разделил ответ на эти два раздела, поэтому вы можете пропустить его, если нужно.


Класс Python может «видеть» переменные, которые переданы ему или определены в нем. Мы делаем это, передавая и определяя в методе __init__:

class Paddle:
    def __init__(self, x_pos):
        ...

Обратите внимание, что сам класс не принимает аргументов (у него даже нет скобок!). Вместо этого мы передаем все аргументы, которые мы хотим использовать в нашем классе, методу __init__! Класс может быть определен в скобках, но это только в том случае, если это класс, основанный на другом классе, который называется производным классом:

class pygame.sprite.Sprite:
    def __init__(self, ...):
        ...

class Paddle(pygame.sprite.Sprite):
    def __init__(self, ...):
        ...

Далее мы увидели, чтомы можем передавать переменные в классы через их __init__ методы, но как мы можем сохранить их в классе как атрибуты и использовать их в классе методы (функции)? Мы делаем это, добавляя атрибуты класса к self. следующим образом:

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos):
        ...
        self.x_position = x_pos

Теперь мы можем использовать этот атрибут в других методах класса, а не только в методе __init__:

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos):
        ...
        self.x_position = x_pos

    def x_add_1(self):
        self.x_position += 1

Материал внутри метода x_add_1() знает об атрибуте x_position, потому что мы передали self методу, где хранится атрибут x_position (потому что мы определили его как self.x_position).

Итак, теперь у нас есть класс с атрибутом (self.x_position) и методом (x_add_1), давайте использовать его, создав экземпляр класса:

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos):
        ...
        self.x_position = x_pos

    def x_add_1(self):
        self.x_position += 1

player_1 = Paddle(5)
print(player1.x_position)
> 5
player1.x_add_1()
print(player1.x_position)
> 6

Теперь вы можете увидеть, как мы создали экземпляр класса Paddle и передали ему значение x_pos, равное 5. Затем мы получили доступ к атрибуту x_position нашего экземпляра player_1 и использовалиx_add_1 метод тоже.


Теперь давайте посмотрим, где вы столкнулись с некоторыми проблемами:

class Paddle(pygame.sprite.Sprite, x_pos):
    def __init__(self):
    ...

Прежде всего, вы сделали Paddle производнымкласс pygame.sprite.Sprite. Это кажется разумным. Но вы также передали его x_pos, который должен быть передан методу __init__, который вы ничего не передали! Вот почему вы получаете сообщение об ошибке, что x_pos не определен, потому что метод __init__ получил указание использовать его, но не прошел его.

Но как только мы исправили этоу нас все еще проблемы:

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos):
        ...
        self.image.fill(colors["WHITE"])
        self.rect.y = SCREEN_HEIGHT/2

Вашему классу не было сказано ни о словаре с именем colors, ни о целом числе с именем SCREEN_HEIGHT. Чтобы иметь возможность использовать их, нужно будет передать их при создании экземпляра класса.

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos, colors, SCREEN_HEIGHT):
        ...
        self.image.fill(colors["WHITE"])
        self.rect.y = SCREEN_HEIGHT/2

Вам не нужно хранить эти новые переменные в качестве атрибутов класса, если вы не думаете, что будете использовать их вне метода __init__, но могли бы. Например, вы можете захотеть сделать весло красным, когда мяч ударяет по нему, и в этом случае вам нужно будет сделать атрибут для хранения словаря colors:

class Paddle(pygame.sprite.Sprite):
    def __init__(self, x_pos, colors, SCREEN_HEIGHT):
        self.colors = colors
        ...
        self.image.fill(self.colors["WHITE"])
        self.rect.y = SCREEN_HEIGHT/2

    def paddle_hit(self):
        ...
        self.image.fill(self.colors["RED"])
        ...

Это, вероятно, все, что вам нужнознать, чтобы иметь возможность исправить свой класс. Боюсь, я не дал вам ничего, что вы можете скопировать и вставить, но я выделил все проблемы, которые я вижу (я думаю ), и описал, как их исправить!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...