Pygame Beat-Em-Up游戏//敌人攻击计时器永远不会达到零

时间:2017-04-03 19:44:04

标签: python timer pygame

Pastebin Link

我正在与Pygame合作进行一场节拍游戏,我遇到了一个问题,即敌人会抓住玩家,永远不让他离开。计时器应该运行,当它达到零时,敌人应该将玩家推开,但它永远不会达到零。

变量联系人是实际触碰玩家的敌人群体。它使用pygame.sprite.Group()函数。如果精灵重叠(玩家和所有敌人列表中的任何敌人),则将它们添加到组中。如果精灵停止重叠(敌人走开,或者玩家走开),则从该组中移除敌人。

contact = pygame.sprite.spritecollide(heroBoonrit, enemy_list, False)

对于时钟的每个嘀嗒声,我设置它以检查是否有任何敌人触及玩家,如果有,则通过它们中的每一个并查看是否有任何敌人处于抓取状态(的 villan.grabbing_cooldown )。它只是一个开/关开关,意味着敌人目前正在通过抓取动作进行攻击。我可能想出一个更逻辑的变量名。

如果满足这些条件,则会发生一些事情,例如将玩家的位置向上(或向下)捕捉,以便与敌人处于同一y坐标。变量 heroBoonrit.held_cooldown 是另一个开/关开关,意味着他当前被关押。玩家和敌人都有自己的变量,分别称为 heroBoonrit.held_countdown villan.grabbing_countdown 。我看到的问题(通过运行print()进行诊断的问题是,敌人的倒计时减1然后它会停止减少,而我的英雄的倒数计时器会减少直到0.所以敌人永远不会放手。 / p>

我有一种感觉,这可能是一种更加优雅和干净的方式来处理玩家和敌人的行为,而不是为玩家打开/关闭与他是否有关的开关被震惊,抓住等等(另外,相应的倒数计时器),但我只做了一个月的编程,并希望得到任何反馈。也许在每个时钟滴答之后,敌人持有计时器再次重置为60 ...我在其他帖子中读到,当你使用Pygame Group()函数时,你不能轻易地遍历该组。还在学习许多细节......

我在我的主游戏循环中运行了这个命令,发现敌人的抓取倒数计时器只从60变为59然后停止倒计时:

print("||Shit Clown|| Grabbing = ", enemyShit_Clown.grabbing_cooldown, " Countdown = ", enemyShit_Clown.grabbing_countdown, "||Boonrit|| Grabbed = ", heroBoonrit.held_cooldown, " Countdown = ", heroBoonrit.held_countdown)

以下是我遇到此问题的代码块。

    for villan in contact:
        for villan in enemy_list:
            if villan.grabbing_cooldown:
                heroBoonrit.held_cooldown = True
                heroBoonrit.rect.y = villan.rect.y
                heroBoonrit.rect.x = (villan.rect.x + 30)
                heroBoonrit.held_countdown = villan.grabbing_countdown
                villan.grabbing_countdown -= 1
                heroBoonrit.held_countdown -= 1
                if villan.grabbing_countdown <= 0:
                    villan.grabbing_countdown = 0
                    heroBoonrit.held_countdown = 0
                    villan.grabbing_cooldown = False
                    heroBoonrit.held_cooldown = False
                    heroBoonrit.rect.x += 30
            elif villan.attacking_cooldown:
                if heroBoonrit.blocking != True:
                    heroBoonrit.hp -= 100
                else:
                    heroBoonrit.hp -= 10

这是敌人类:

class Enemy(pygame.sprite.Sprite):
def __init__(self, name, level, speed, hp, stamina, fear, blocking_cooldown, jumping_cooldown, attacking_cooldown, held_cooldown, knockdown_cooldown, stun_cooldown, jumping_countdown, attacking_countdown, held_countdown, knockdown_countdown, stun_countdown, grabbing_cooldown, grabbing_countdown, blocking_countdown):
    super().__init__()
    self.image = pygame.image.load(os.path.join('res','img','chars','shit_clown-3.png'))
    #self.image = pygame.Surface([30,20])
    #self.image.fill(color)
    self.rect = self.image.get_rect()
    self.surf = pygame.Surface((30,20))
    self.name = name
    self.speed = speed
    self.level = level
    self.hp = hp
    self.stamina = stamina
    self.fear = fear
    self.blocking_cooldown = blocking_cooldown
    self.jumping_cooldown = jumping_cooldown
    self.jumping_countdown = jumping_countdown
    self.attacking_cooldown = attacking_cooldown
    self.attacking_countdown = attacking_countdown
    self.held_cooldown = held_cooldown
    self.held_countdown = held_countdown
    self.knockdown_cooldown = knockdown_cooldown
    self.knockdown_countdown = knockdown_countdown
    self.stun_cooldown = stun_cooldown
    self.stun_countdown = stun_countdown
    self.grabbing_cooldown = grabbing_cooldown
    self.grabbing_countdown = grabbing_countdown
    self.blocking_countdown = blocking_countdown

    blocking_cooldown = False
    jumping_cooldown = False
    jumping_coutndown = 0
    attacking_cooldown = False
    attacking_countdown = 0
    held_cooldown = False
    held_countdown = 0
    knockdown_cooldown = False
    knockdown_countdown = 0
    stun_cooldown = False
    stun_countdown = 0
    grabbing_cooldown = False
    grabbing_countdown = 0
    blocking_countdown = 0

产生敌人:

enemyShit_Clown = Enemy("Shit Clown", 1, 4, 1000, 10, 90, False, False, False, False, False, False, 0, 0, 0, 0, 0, True, 60, 0)
enemyShit_Clown.image = pygame.image.load(os.path.join('res','img','chars','shit_clown-3.png')).convert()
enemyShit_Clown.rect.x = 300 #random.randrange(300, 400)
enemyShit_Clown.rect.y =  300 #random.randrange(200, 400)
enemy_list.add(enemyShit_Clown)
all_sprites_list.add(enemyShit_Clown)

非常感谢你的帮助

1 个答案:

答案 0 :(得分:2)

我没有看到恶棍停止倒计时的明显原因。也就是说,我确实看到你在hero.update代码和主循环中减少了倒计时。我希望你的英雄倒数比恶棍快两倍,但不会快60倍。

我想建议一些代码更改。首先,删除__init__代码中的大多数参数。只需将默认值设置为0或False或其他。

接下来,我看到你创建一个角色,然后为其分配一个图像。这应该在构造函数中,可能有一个默认参数来选择不同的起始图像。

接下来,您在英雄的update方法中有倒计时代码,但在恶棍中没有。我认为这是一个错误。将倒计时移动到更新例程中,不用担心在主循环中搜索它。

最后,对于你缺少的OO编程有一个经验法则:“告诉,不要问。”

基本上,除其他外,这表示您不应该访问另一个对象的属性,而肯定不应该修改另一个对象的属性。

我建议你为这些东西编写方法,如下:

class Villain: 
    def grab(self, hero):
        """Start a grabbing attack on hero, if not blocked/busy"""

        if self.grabbing:
            # Already grabbing someone. Fail.
            return False

        ticks = 60

        if hero.grabbed(self, ticks):
            self.grabbing = hero
            self.grabbing_countdown = ticks
            hero.moveto(self.rect.y, self.rect.x + 30)
            return True
        else:
            return False

    def update(self, *args):
        :
        blah blah blah
        :
        if self.grabbing:
            self.grabbing_countdown -= 1

            if self.grabbing_countdown == 0:
                self.grabbing.release(self)
                self.grabbing.push_away(self.rect.x, self.rect.y, 30)
                self.grabbing = None