как использовать переменные из функций в других функциях, не помещая переменную в метод __init__ класса? - PullRequest
0 голосов
/ 10 апреля 2020

Я - кодер нового уровня, и я делаю игру, в которой есть различные виды атак, и я хочу, чтобы можно было без труда комбинировать атаки, но я не могу понять, как сделать задержку между различными атаками. До сих пор я пытался использовать то же значение, что и задержка атаки, так что, если задержка сброшена, вы можете использовать другую атаку, но это не позволяет мне сделать это, потому что она не знает, что переменная "сейчас «потому что мне нужно« сейчас »должно быть конкретно в этой функции. Вот код:

class Player(pg.sprite.Sprite):
    def __init__(self, game):
        self.game = game
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface((30, 35))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.center = (WIDTH / 2, HEIGHT / 2)
        self.pos = vec(WIDTH / 2, HEIGHT / 2)
        self.vel = vec(0, 0)
        self.acc = vec(0, 0)
        self.attack_counter = 0
        self.dt = 0.2

        # this is all the attack delay stuff
        self.last_attack = 100
        self.last_attack_n_light_right = 700
        self.last_attack_s_light_right = 425
        self.last_attack_d_light_right = 700
        self.last_attack_s_air_right = 425

        self.last_attack_n_light_left = 700
        self.last_attack_s_light_left = 425
        self.last_attack_d_light_left = 700
        self.last_attack_n_air = 425
        self.last_attack_s_air_left = 425
        self.last_attack_d_air = 425

        self.attack_delay = pg.time.get_ticks()
        self.attack_delay_n_light_right = pg.time.get_ticks()
        self.attack_delay_s_light_right = pg.time.get_ticks()
        self.attack_delay_d_light_right = pg.time.get_ticks()
        self.attack_delay_s_air_right = pg.time.get_ticks()

        self.attack_delay_n_light_left = pg.time.get_ticks()
        self.attack_delay_s_light_left = pg.time.get_ticks()
        self.attack_delay_d_light_left = pg.time.get_ticks()
        self.attack_delay_n_air = pg.time.get_ticks()
        self.attack_delay_s_air_left = pg.time.get_ticks()
        self.attack_delay_d_air = pg.time.get_ticks()

        self.move_delay = pg.time.get_ticks()

    def jump(self):
        # jump if jump key is pressed, and triple jumps are recharged when touching platforms
        global player_jump_count
        self.rect.x += 1
        self.rect.x -= 1
        player_jump_count -= 1
        self.vel.y = -PLAYER_JUMP
        hits = pg.sprite.spritecollide(self, self.game.platforms, False)
        if hits:
            player_jump_count = 3
        if player_jump_count < 1:
            self.vel.y = PLAYER_GRAV

    def s_light_right(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        # print(now, "  ", self.attack_delay_s_light_right)
        if self.s_light_left.now - self.attack_delay_s_light_left > self.last_attack_s_light_left:
            if keys[pg.K_d]:
                if now - self.attack_delay_s_light_right > self.last_attack_s_light_right:     # this is where the problem is
                    self.attack_delay_s_light_right = now
                    bullet = Bullet(self.rect.centerx + 20, self.rect.centery - 10, self.vel.x + 10, 0, 20, 20, self.dt)
                    self.game.all_sprites.add(bullet)
                    self.game.bullets.add(bullet)

    def s_light_left(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_a]:
            if now - self.attack_delay_s_light_left > self.last_attack_s_light_left:
                self.attack_delay_s_light_left = now
                bullet = Bullet(self.rect.centerx - 20, self.rect.centery - 10, self.vel.x - 10, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)

    def n_light_right(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
            if now - self.attack_delay_n_light_right > self.last_attack_n_light_right:
                self.attack_delay_n_light_right = now
                bullet = Bullet(self.rect.centerx + 40, self.rect.centery - 40, 0, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)

    def n_light_left(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
            if now - self.attack_delay_n_light_left > self.last_attack_n_light_left:
                self.attack_delay_n_light_left = now
                bullet = Bullet(self.rect.centerx - 60, self.rect.centery - 40, 0, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)

    def d_light_right(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_s]:
            if not keys[pg.K_a] and not keys[pg.K_d]:
                if now - self.attack_delay_d_light_right > self.last_attack_d_light_right:
                    self.attack_delay_d_light_right = now
                    bullet = Bullet(self.rect.centerx + 40, self.rect.centery + 3.5, 0, 0, 30, 15, self.dt)
                    self.game.all_sprites.add(bullet)
                    self.game.bullets.add(bullet)

    def d_light_left(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_s]:
            if not keys[pg.K_a] and not keys[pg.K_d]:
                if now - self.attack_delay_d_light_left > self.last_attack_d_light_left:
                    self.attack_delay_d_light_left = now
                    bullet = Bullet(self.rect.centerx - 60, self.rect.centery + 3.5, 0, 0, 30, 15, self.dt)
                    self.game.all_sprites.add(bullet)
                    self.game.bullets.add(bullet)

    def s_air_right(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_d]:
            if now - self.attack_delay_s_air_right > self.last_attack_s_air_right:
                self.attack_delay_s_air_right = now
                bullet = Bullet(self.rect.centerx + 20, self.rect.centery - 10, self.vel.x + 10, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)

    def s_air_left(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_a]:
            if now - self.attack_delay_s_air_left > self.last_attack_s_air_left:
                self.attack_delay_s_air_left = now
                bullet = Bullet(self.rect.centerx - 20, self.rect.centery - 10, self.vel.x - 10, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)

    def n_air(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if not keys[pg.K_a] and not keys[pg.K_d] and not keys[pg.K_s]:
            if now - self.attack_delay_n_air > self.last_attack_n_air:
                self.attack_delay_n_air = now
                bullet = Bullet(self.rect.centerx + 5, self.rect.centery - 60, 0, 0, 20, 20, self.dt)
                bullet2 = Bullet(self.rect.centerx - 25, self.rect.centery - 60, 0, 0, 20, 20, self.dt)
                self.game.all_sprites.add(bullet)
                self.game.bullets.add(bullet)
                self.game.all_sprites.add(bullet2)
                self.game.bullets.add(bullet2)

    def d_air(self):
        keys = pg.key.get_pressed()
        now = pg.time.get_ticks()
        if keys[pg.K_s]:
            if not keys[pg.K_a] and not keys[pg.K_d]:
                if now - self.attack_delay_d_air > self.last_attack_d_air:
                    self.attack_delay_d_air = now
                    bullet = Bullet(self.rect.centerx + 5, self.rect.centery + 60, 0, 12, 20, 20, self.dt)
                    bullet2 = Bullet(self.rect.centerx - 25, self.rect.centery + 60, 0, 12, 20, 20, self.dt)
                    self.game.all_sprites.add(bullet)
                    self.game.bullets.add(bullet)
                    self.game.all_sprites.add(bullet2)
                    self.game.bullets.add(bullet2)

    def update(self):
        self.acc = vec(0, PLAYER_GRAV)
        keys = pg.key.get_pressed()
        if keys[pg.K_a]:
            self.acc.x = -PLAYER_ACC
        if keys[pg.K_d]:
            self.acc.x = PLAYER_ACC
        # apply friction
        self.acc.x += self.vel.x * PLAYER_FRICTION
        # equations of motion
        self.vel += self.acc
        self.pos += self.vel + 0.5 * self.acc

        self.rect.midbottom = self.pos

1 Ответ

3 голосов
/ 10 апреля 2020

Похоже, что вам нужна переменная уровня объекта : общая для экземпляра класса и общая для всех методов-членов этого экземпляра. Это можно объявить и использовать следующим образом:

class foo:
    def __init__(self, val):
        self.now = val
    def double_it(self):
        return self.now * 2

>>> f = foo(10)
>>> f.double_it()
20




Изменить, чтобы добавить:
Это не совсем понятно из вопроса, зачем вам это нужно, но вы указываете, что переменная не должна быть включена в __init__(). Если это так, то можно создавать атрибуты экземпляра «на лету», хотя обычно это не очень хорошая практика и приводит к некоторому довольно нечитаемому коду:

class bar:
    def double_it(self, val):
        self.now = val * 2

>>> b = bar()
>>> b.now  <----- we expect this to fail; nothing has set `b.val` yet.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'bar' object has no attribute 'now'

>>> b.double_it(10)
>>> b.now
20

На самом деле нет веских причин для тем не менее, и большинство линтеров будут отмечать его (например, pylint):

:attribute-defined-outside-init (W0201): *Attribute %r defined outside __init__*
  Used when an instance attribute is defined outside the __init__ method. This
  message belongs to the classes checker.

Было бы лучше установить значение в конструкторе None, а затем изменить его позже.

...