我正在与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)
非常感谢你的帮助
答案 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