diff --git a/source/component/plant.py b/source/component/plant.py index 617c006..bea2d0c 100755 --- a/source/component/plant.py +++ b/source/component/plant.py @@ -605,7 +605,7 @@ class Squash(Plant): if (self.frame_index + 1) == self.frame_num: for zombie in self.zombie_group: if self.canAttack(zombie): - zombie.setDamage(1800, False) + zombie.setDamage(1800, damageType=c.ZOMBIE_RANGE_DAMAGE) self.health = 0 # 避免僵尸在原位啃食 self.kill() elif self.aim_timer == 0: @@ -651,7 +651,7 @@ class Spikeweed(Plant): self.attack_timer = self.current_time for zombie in self.zombie_group: if self.canAttack(zombie): - zombie.setDamage(20, False) + zombie.setDamage(20, damageType=c.ZOMBIE_COMMON_DAMAGE) class Jalapeno(Plant): diff --git a/source/component/zombie.py b/source/component/zombie.py index cf604d3..3eaaacb 100755 --- a/source/component/zombie.py +++ b/source/component/zombie.py @@ -4,7 +4,7 @@ from .. import constants as c class Zombie(pg.sprite.Sprite): - def __init__(self, x, y, name, head_group=None, helmetHealth=0, bodyHealth=c.NORMAL_HEALTH + c.LOSTHEAD_HEALTH, damage=30): + def __init__(self, x, y, name, head_group=None, helmetHealth=0, helmetType2Health=0, bodyHealth=c.NORMAL_HEALTH + c.LOSTHEAD_HEALTH, damage=30): pg.sprite.Sprite.__init__(self) self.name = name @@ -18,13 +18,14 @@ class Zombie(pg.sprite.Sprite): self.rect.centerx = x self.rect.bottom = y - self.bodyHealth = bodyHealth self.helmetHealth = helmetHealth - self.health = bodyHealth + helmetHealth + self.helmetType2Health = helmetType2Health + self.health = bodyHealth self.damage = damage self.dead = False self.lostHead = False - self.helmet = False + self.helmet = (self.helmetHealth > 0) + self.helmetType2 = (self.helmetType2Health > 0) self.head_group = head_group self.walk_timer = 0 @@ -80,9 +81,12 @@ class Zombie(pg.sprite.Sprite): def walking(self): self.checkToDie(self.losthead_walk_frames) - if self.health <= c.NORMAL_HEALTH and self.helmet: + if self.helmetHealth <= 0 and self.helmet: self.changeFrames(self.walk_frames) self.helmet = False + if self.helmetType2Health <= 0 and self.helmetType2: + self.changeFrames(self.walk_frames) + self.helmetType2 = False if self.name == c.NEWSPAPER_ZOMBIE: self.speed = 2 @@ -96,9 +100,12 @@ class Zombie(pg.sprite.Sprite): def attacking(self): self.checkToDie(self.losthead_attack_frames) - if self.health <= c.NORMAL_HEALTH and self.helmet: + if self.helmetHealth <= 0 and self.helmet: self.changeFrames(self.attack_frames) self.helmet = False + if self.helmetType2Health <= 0 and self.helmetType2: + self.changeFrames(self.attack_frames) + self.helmetType2 = False if (self.current_time - self.attack_timer) > (c.ATTACK_INTERVAL * self.getTimeRatio()): if self.prey.health > 0: if self.prey_is_plant: @@ -179,9 +186,33 @@ class Zombie(pg.sprite.Sprite): if (self.current_time - self.ice_slow_timer) > c.ICE_SLOW_TIME: self.ice_slow_ratio = 1 - def setDamage(self, damage, ice=False): - self.health -= damage - self.hit_timer = self.current_time + def setDamage(self, damage, ice=False, damageType=c.ZOMBIE_COMMON_DAMAGE): + if damageType == c.ZOMBIE_DEAFULT_DAMAGE: # 不穿透二类防具的攻击 + # 从第二类防具开始逐级传递 + if self.helmetType2: + self.helmetType2Health -= damage + if helmetType2Health <= 0: + self.helmetType2 = False + if self.helmet: + self.helmetHealth += self.helmetType2Health # 注意self.helmetType2Health已经带有正负 + self.helmetType2Health = 0 # 注意合并后清零 + if self.helmetHealth <= 0: + self.helmet = False + self.health += self.helmetHealth + self.helmetHealth = 0 # 注意合并后清零 + else: + self.health += self.helmetType2Health + self.helmetType2Health = 0 + elif self.helmet: # 不存在二类防具,但是存在一类防具 + self.helmetHealth -= damage + if self.helmetHealth <= 0: + self.helmet = False + self.health += self.helmetHealth + self.helmetHealth = 0 # 注意合并后清零 + else: # 没有防具 + self.health -= damage + # 记录攻击时间 + self.hit_timer = self.current_time if ice: self.setIceSlow() @@ -189,7 +220,7 @@ class Zombie(pg.sprite.Sprite): self.state = c.WALK self.animate_interval = 180 - if self.helmet: + if self.helmet or self.helmetType2: # 这里暂时没有考虑同时有两种防具的僵尸 self.changeFrames(self.helmet_walk_frames) elif self.lostHead: self.changeFrames(self.losthead_walk_frames) @@ -203,7 +234,7 @@ class Zombie(pg.sprite.Sprite): self.attack_timer = self.current_time self.animate_interval = 100 - if self.helmet: + if self.helmet or self.helmetType2: # 这里暂时没有考虑同时有两种防具的僵尸 self.changeFrames(self.helmet_attack_frames) elif self.lostHead: self.changeFrames(self.losthead_attack_frames) @@ -286,8 +317,7 @@ class NormalZombie(Zombie): # 路障僵尸 class ConeHeadZombie(Zombie): def __init__(self, x, y, head_group): - Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, head_group, c.CONEHEAD_HEALTH) - self.helmet = True + Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, head_group, helmetHealth=c.CONEHEAD_HEALTH) def loadImages(self): self.helmet_walk_frames = [] @@ -323,8 +353,7 @@ class ConeHeadZombie(Zombie): class BucketHeadZombie(Zombie): def __init__(self, x, y, head_group): - Zombie.__init__(self, x, y, c.BUCKETHEAD_ZOMBIE, head_group, c.BUCKETHEAD_HEALTH) - self.helmet = True + Zombie.__init__(self, x, y, c.BUCKETHEAD_ZOMBIE, head_group, helmetHealth=c.BUCKETHEAD_HEALTH) def loadImages(self): self.helmet_walk_frames = [] @@ -360,7 +389,7 @@ class BucketHeadZombie(Zombie): class FlagZombie(Zombie): def __init__(self, x, y, head_group): - Zombie.__init__(self, x, y, c.FLAG_ZOMBIE, head_group, c.FLAG_HEALTH) + Zombie.__init__(self, x, y, c.FLAG_ZOMBIE, head_group, bodyHealth=c.FLAG_HEALTH + c.NORMAL_HEALTH) def loadImages(self): self.walk_frames = [] @@ -390,8 +419,7 @@ class FlagZombie(Zombie): class NewspaperZombie(Zombie): def __init__(self, x, y, head_group): - Zombie.__init__(self, x, y, c.NEWSPAPER_ZOMBIE, head_group, c.NEWSPAPER_HEALTH) - self.helmet = True + Zombie.__init__(self, x, y, c.NEWSPAPER_ZOMBIE, head_group, helmetType2Health=c.NEWSPAPER_HEALTH) def loadImages(self): self.helmet_walk_frames = [] diff --git a/source/constants.py b/source/constants.py index 85b9ed2..d035a91 100755 --- a/source/constants.py +++ b/source/constants.py @@ -171,6 +171,13 @@ FLAG_ZOMBIE = 'FlagZombie' NEWSPAPER_ZOMBIE = 'NewspaperZombie' BOOMDIE = 'BoomDie' +# 对僵尸的攻击类型设置 +ZOMBIE_DEAFULT_DAMAGE = 'helmet2First' +ZOMBIE_HELMET_2_FIRST = 'helmet2First' # 优先攻击二类防具 +ZOMBIE_COMMON_DAMAGE = 'commonDamage' # 优先攻击僵尸与一类防具的整体 +ZOMBIE_RANGE_DAMAGE = 'rangeDAMAGE' # 范围攻击,同时伤害二类防具与(僵尸与一类防具的整体) +ZOMBIE_ASH_DAMAGE = 'ashDAMAGE' # 灰烬植物攻击,直接伤害本体 + # 僵尸生命值设置 LOSTHEAD_HEALTH = 70 NORMAL_HEALTH = 200 # 普通僵尸生命值 diff --git a/source/state/level.py b/source/state/level.py index b36bb75..83b856d 100644 --- a/source/state/level.py +++ b/source/state/level.py @@ -606,7 +606,7 @@ class Level(tool.State): if plant: if plant.name == c.WALLNUTBOWLING: if plant.canHit(i): - zombie.setDamage(c.WALLNUT_BOWLING_DAMAGE) + zombie.setDamage(c.WALLNUT_BOWLING_DAMAGE, damageType=c.ZOMBIE_DEAFULT_DAMAGE) plant.changeDirection(i) elif plant.name == c.REDWALLNUTBOWLING: if plant.state == c.IDLE: @@ -645,7 +645,7 @@ class Level(tool.State): for zombie in self.zombie_groups[i]: if ((abs(zombie.rect.centerx - x) <= x_range) or ((zombie.rect.right - (x-x_range) > 20) or (zombie.rect.right - (x-x_range))/zombie.rect.width > 0.15, ((x+x_range) - zombie.rect.left > 20) or ((x+x_range) - zombie.rect.left)/zombie.rect.width > 0.15)[zombie.rect.x > x]): # 这代码不太好懂,后面是一个判断僵尸在左还是在右,前面是一个元组,[0]是在左边的情况,[1]是在右边的情况 - zombie.health -= 1800 + zombie.setDamage(1800, damageType=c.ZOMBIE_ASH_DAMAGE) if zombie.health <= 0: zombie.setBoomDie() @@ -654,7 +654,7 @@ class Level(tool.State): for zombie in self.zombie_groups[i]: if zombie.rect.left <= c.SCREEN_WIDTH: zombie.setFreeze(plant.trap_frames[0]) - zombie.setDamage(20) # 寒冰菇还有全场20的伤害 + zombie.setDamage(20, damageType=c.ZOMBIE_RANGE_DAMAGE) # 寒冰菇还有全场20的伤害 def killPlant(self, plant, shovel=False): x, y = plant.getPosition() @@ -683,8 +683,7 @@ class Level(tool.State): for zombie in self.zombie_groups[i]: if ((abs(zombie.rect.centerx - x) <= plant.explode_y_range) or ((zombie.rect.right - (x-plant.explode_x_range) > 20) or (zombie.rect.right - (x-plant.explode_x_range))/zombie.rect.width > 0.15, ((x+plant.explode_x_range) - zombie.rect.left > 20) or ((x+plant.explode_x_range) - zombie.rect.left)/zombie.rect.width > 0.15)[zombie.rect.x > x]): # 这代码不太好懂,后面是一个判断僵尸在左还是在右,前面是一个元组,[0]是在左边的情况,[1]是在右边的情况 - # 如果以后要区分防具和本体,这里要跟着改动,因为土豆雷不是灰烬植物 - zombie.health -= 1800 + zombie.setDamage(1800, damageType=c.ZOMBIE_RANGE_DAMAGE) # 避免僵尸在用铲子移除植物后还在原位啃食 plant.health = 0