From 1fe841dcb338a607136d804700c533e713ad97a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E5=A4=96=E4=B9=8B=E7=A5=9E?= Date: Sat, 14 May 2022 21:31:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E7=88=86=E7=82=B8=E4=BC=A4=E5=AE=B3?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=94=B1=E7=88=86=E7=82=B8=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E6=97=B6=E6=94=B9=E4=B8=BA=E7=88=86=E7=82=B8=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/component/plant.py | 22 +++-- source/component/zombie.py | 3 +- source/state/level.py | 175 ++++++++++++++++++++----------------- 3 files changed, 113 insertions(+), 87 deletions(-) diff --git a/source/component/plant.py b/source/component/plant.py index 176e7ad..b066e6d 100755 --- a/source/component/plant.py +++ b/source/component/plant.py @@ -541,6 +541,7 @@ class CherryBomb(Plant): Plant.__init__(self, x, y, c.CHERRYBOMB, c.INF, None) self.state = c.ATTACK self.start_boom = False + self.boomed = False self.bomb_timer = 0 self.explode_y_range = 1 self.explode_x_range = c.GRID_X_SIZE * 1.5 @@ -699,6 +700,8 @@ class PotatoMine(Plant): self.init_timer = 0 self.bomb_timer = 0 self.explode_x_range = c.GRID_X_SIZE / 2 + self.start_boom = False + self.boomed = False def loadImages(self, name, scale): self.init_frames = [] @@ -740,6 +743,7 @@ class PotatoMine(Plant): # 播放音效 pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "potatomine.ogg")).play() self.changeFrames(self.explode_frames) + self.start_boom = True elif (self.current_time - self.bomb_timer) > 500: self.health = 0 @@ -865,7 +869,8 @@ class Jalapeno(Plant): Plant.__init__(self, x, y, c.JALAPENO, c.INF, None) self.orig_pos = (x, y) self.state = c.ATTACK - self.start_explode = False + self.start_boom = False + self.boomed = False self.explode_y_range = 0 self.explode_x_range = 500 @@ -880,10 +885,10 @@ class Jalapeno(Plant): self.changeFrames(self.explode_frames) self.animate_timer = self.current_time self.rect.x = c.MAP_OFFSET_X - self.start_explode = True + self.start_boom = True def animation(self): - if self.start_explode: + if self.start_boom: if (self.current_time - self.animate_timer) > 100: if self.frame_index == 1: # 播放爆炸音效 @@ -1010,7 +1015,8 @@ class IceShroom(Plant): Plant.__init__(self, x, y, c.ICESHROOM, c.PLANT_HEALTH, None) self.can_sleep = True self.orig_pos = (x, y) - self.start_freeze = False + self.start_boom = False + self.boomed = False def loadImages(self, name, scale): self.idle_frames = [] @@ -1037,10 +1043,10 @@ class IceShroom(Plant): self.animate_timer = self.current_time self.rect.x = c.MAP_OFFSET_X self.rect.y = c.MAP_OFFSET_Y - self.start_freeze = True + self.start_boom = True def animation(self): - if self.start_freeze: + if self.start_boom: if (self.current_time - self.animate_timer) > 500: self.frame_index += 1 if self.frame_index >= self.frame_num: @@ -1189,6 +1195,8 @@ class RedWallNutBowling(Plant): self.move_timer = 0 self.move_interval = 70 self.vel_x = randint(12, 15) + self.start_boom = False + self.boomed = False def loadImages(self, name, scale): self.idle_frames = [] @@ -1217,6 +1225,7 @@ class RedWallNutBowling(Plant): def attacking(self): if self.explode_timer == 0: + self.start_boom = True self.explode_timer = self.current_time self.changeFrames(self.explode_frames) # 播放爆炸音效 @@ -1484,6 +1493,7 @@ class DoomShroom(Plant): self.explode_y_range = 2 self.explode_x_range = c.GRID_X_SIZE * 2.5 self.start_boom = False + self.boomed = False self.originalX = x self.originalY = y diff --git a/source/component/zombie.py b/source/component/zombie.py index adeaf7a..21c1f04 100755 --- a/source/component/zombie.py +++ b/source/component/zombie.py @@ -975,8 +975,7 @@ class Zomboni(Zombie): # 冰车僵尸不可冰冻 self.ice_slow_ratio = 1 - def freezing(self): - # 冰车僵尸不可冰冻 + def setFreeze(self, ice_trap_image): pass def walking(self): diff --git a/source/state/level.py b/source/state/level.py index cc0093a..6999cb7 100644 --- a/source/state/level.py +++ b/source/state/level.py @@ -942,6 +942,8 @@ class Level(tool.State): self.map.addMapPlant(map_x, map_y, self.plant_name, sleep=mushroomSleep) self.removeMouseImage() + # print(self.newPlantAndPositon) + # 播放种植音效 pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plant.ogg")).play() @@ -1195,49 +1197,25 @@ class Level(tool.State): # 用铲子铲不用触发植物功能 if not shovel: - if targetPlant.name in {c.CHERRYBOMB, c.REDWALLNUTBOWLING}: - self.boomZombies(targetPlant.rect.centerx, map_y, targetPlant.explode_y_range, - targetPlant.explode_x_range) - elif (targetPlant.name == c.DOOMSHROOM) and (targetPlant.state != c.SLEEP): - x, y = targetPlant.originalX, targetPlant.originalY - map_x, map_y = self.map.getMapIndex(x, y) - self.boomZombies(targetPlant.rect.centerx, map_y, targetPlant.explode_y_range, - targetPlant.explode_x_range) - for i in self.plant_groups[map_y]: - checkMapX, _ = self.map.getMapIndex(i.rect.centerx, i.rect.bottom) - if map_x == checkMapX: - i.health = 0 - self.plant_groups[map_y].add(plant.Hole(x, y, self.map.map[map_y][map_x][c.MAP_PLOT_TYPE])) - self.map.map[map_y][map_x][c.MAP_PLANT].add(c.HOLE) - elif targetPlant.name == c.JALAPENO: - self.boomZombies(targetPlant.rect.centerx, map_y, targetPlant.explode_y_range, - targetPlant.explode_x_range, effect=c.BULLET_EFFECT_UNICE) - # 消除冰道 - for i in self.plant_groups[map_y]: - if i.name == c.ICE_FROZEN_PLOT: - i.health = 0 - elif targetPlant.name == c.ICESHROOM and targetPlant.state != c.SLEEP: - self.freezeZombies(targetPlant) - elif targetPlant.name == c.HYPNOSHROOM and targetPlant.state != c.SLEEP: + if targetPlant.name == c.HYPNOSHROOM and targetPlant.state != c.SLEEP: if targetPlant.zombie_to_hypno: zombie = targetPlant.zombie_to_hypno zombie.setHypno() _, map_y = self.map.getMapIndex(zombie.rect.centerx, zombie.rect.bottom) self.zombie_groups[map_y].remove(zombie) self.hypno_zombie_groups[map_y].add(zombie) - elif (targetPlant.name == c.POTATOMINE and not targetPlant.is_init): # 土豆雷不是灰烬植物,不能用Boom - for zombie in self.zombie_groups[map_y]: - # 双判断:发生碰撞或在攻击范围内 - if ((pg.sprite.collide_mask(zombie, targetPlant)) or - (abs(zombie.rect.centerx - x) <= targetPlant.explode_x_range)): - zombie.setDamage(1800, damageType=c.ZOMBIE_RANGE_DAMAGE) # 对于墓碑:移除存储在墓碑集合中的坐标 # 注意这里是在描述墓碑而非墓碑吞噬者 elif targetPlant.name == c.GRAVE: self.graveSet.remove((map_x, map_y)) + elif ((targetPlant.name in { c.DOOMSHROOM, c.ICESHROOM, + c.POTATOMINE, }) + and (self.boomed)): + pass elif targetPlant.name not in { c.WALLNUTBOWLING, c.TANGLEKLEP, c.ICE_FROZEN_PLOT, c.HOLE, - c.GRAVE}: + c.GRAVE, c.JALAPENO, + c.REDWALLNUTBOWLING, c.CHERRYBOMB,}: # 触发植物死亡音效 pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plantDie.ogg")).play() else: @@ -1255,11 +1233,11 @@ class Level(tool.State): targetPlant.health = 0 targetPlant.kill() - def checkPlant(self, plant, i): + def checkPlant(self, targetPlant, i): zombie_len = len(self.zombie_groups[i]) # 不用检查攻击状况的情况 - if plant.name in { # 单独指定攻击状态的植物 - c.WALLNUTBOWLING, c.REDWALLNUTBOWLING, + if targetPlant.name in { # 单独指定攻击状态的植物 + c.WALLNUTBOWLING, # 没有攻击状态的植物 c.WALLNUT, c.TALLNUT, c.TORCHWOOD, c.SUNFLOWER, @@ -1270,15 +1248,15 @@ class Level(tool.State): c.HOLE, c.GRAVE, c.ICE_FROZEN_PLOT}: pass - elif plant.name == c.THREEPEASHOOTER: - if plant.state == c.IDLE: + elif targetPlant.name == c.THREEPEASHOOTER: + if targetPlant.state == c.IDLE: if zombie_len > 0: - plant.setAttack() + targetPlant.setAttack() elif (i-1) >= 0 and len(self.zombie_groups[i-1]) > 0: - plant.setAttack() + targetPlant.setAttack() elif (i+1) < self.map_y_len and len(self.zombie_groups[i+1]) > 0: - plant.setAttack() - elif plant.state == c.ATTACK: + targetPlant.setAttack() + elif targetPlant.state == c.ATTACK: if zombie_len > 0: pass elif (i-1) >= 0 and len(self.zombie_groups[i-1]) > 0: @@ -1286,76 +1264,115 @@ class Level(tool.State): elif (i+1) < self.map_y_len and len(self.zombie_groups[i+1]) > 0: pass else: - plant.setIdle() - elif plant.name == c.CHOMPER: + targetPlant.setIdle() + elif targetPlant.name == c.CHOMPER: for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): - plant.setAttack(zombie, self.zombie_groups[i]) + if targetPlant.canAttack(zombie): + targetPlant.setAttack(zombie, self.zombie_groups[i]) break - elif plant.name == c.POTATOMINE: + elif targetPlant.name == c.POTATOMINE: for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): - plant.setAttack() + if targetPlant.canAttack(zombie): + targetPlant.setAttack() break - elif plant.name == c.SQUASH: + if targetPlant.start_boom and (not targetPlant.boomed): + for zombie in self.zombie_groups[i]: + # 双判断:发生碰撞或在攻击范围内 + if ((pg.sprite.collide_mask(zombie, targetPlant)) or + (abs(zombie.rect.centerx - x) <= targetPlant.explode_x_range)): + zombie.setDamage(1800, damageType=c.ZOMBIE_RANGE_DAMAGE) + targetPlant.boomed = True + elif targetPlant.name == c.SQUASH: for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): - plant.setAttack(zombie, self.zombie_groups[i]) + if targetPlant.canAttack(zombie): + targetPlant.setAttack(zombie, self.zombie_groups[i]) break - elif plant.name == c.SPIKEWEED: + elif targetPlant.name == c.SPIKEWEED: can_attack = False for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): + if targetPlant.canAttack(zombie): can_attack = True break - if plant.state == c.IDLE and can_attack: - plant.setAttack(self.zombie_groups[i]) - elif plant.state == c.ATTACK and not can_attack: - plant.setIdle() - elif plant.name == c.SCAREDYSHROOM: + if targetPlant.state == c.IDLE and can_attack: + targetPlant.setAttack(self.zombie_groups[i]) + elif targetPlant.state == c.ATTACK and not can_attack: + targetPlant.setIdle() + elif targetPlant.name == c.SCAREDYSHROOM: need_cry = False can_attack = False for zombie in self.zombie_groups[i]: - if plant.needCry(zombie): + if targetPlant.needCry(zombie): need_cry = True break - elif plant.canAttack(zombie): + elif targetPlant.canAttack(zombie): can_attack = True if need_cry: - if plant.state != c.CRY: - plant.setCry() + if targetPlant.state != c.CRY: + targetPlant.setCry() elif can_attack: - if plant.state != c.ATTACK: - plant.setAttack() - elif plant.state != c.IDLE: - plant.setIdle() - elif plant.name == c.STARFRUIT: + if targetPlant.state != c.ATTACK: + targetPlant.setAttack() + elif targetPlant.state != c.IDLE: + targetPlant.setIdle() + elif targetPlant.name == c.STARFRUIT: can_attack = False for zombie_group in self.zombie_groups: # 遍历循环所有僵尸 for zombie in zombie_group: - if plant.canAttack(zombie): + if targetPlant.canAttack(zombie): can_attack = True break - if plant.state == c.IDLE and can_attack: - plant.setAttack() - elif (plant.state == c.ATTACK and not can_attack): - plant.setIdle() - elif plant.name == c.TANGLEKLEP: + if targetPlant.state == c.IDLE and can_attack: + targetPlant.setAttack() + elif (targetPlant.state == c.ATTACK and not can_attack): + targetPlant.setIdle() + elif targetPlant.name == c.TANGLEKLEP: for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): - plant.setAttack(zombie, self.zombie_groups[i]) + if targetPlant.canAttack(zombie): + targetPlant.setAttack(zombie, self.zombie_groups[i]) break + # 灰烬植物与寒冰菇 + elif targetPlant.name in { c.REDWALLNUTBOWLING, c.CHERRYBOMB, + c.JALAPENO, c.DOOMSHROOM, + c.ICESHROOM,}: + if targetPlant.start_boom and (not targetPlant.boomed): + # 这样分成两层是因为场上灰烬植物肯定少,一个一个判断代价高,先笼统判断灰烬即可 + if targetPlant.name in {c.REDWALLNUTBOWLING, c.CHERRYBOMB}: + self.boomZombies(targetPlant.rect.centerx, i, targetPlant.explode_y_range, + targetPlant.explode_x_range) + elif (targetPlant.name == c.DOOMSHROOM): + x, y = targetPlant.originalX, targetPlant.originalY + map_x, map_y = self.map.getMapIndex(x, y) + self.boomZombies(targetPlant.rect.centerx, i, targetPlant.explode_y_range, + targetPlant.explode_x_range) + for item in self.plant_groups[map_y]: + checkMapX, _ = self.map.getMapIndex(item.rect.centerx, item.rect.bottom) + if map_x == checkMapX: + item.health = 0 + self.plant_groups[map_y].add(plant.Hole(x, y, self.map.map[map_y][map_x][c.MAP_PLOT_TYPE])) + self.map.map[map_y][map_x][c.MAP_PLANT].add(c.HOLE) + elif targetPlant.name == c.JALAPENO: + self.boomZombies(targetPlant.rect.centerx, i, targetPlant.explode_y_range, + targetPlant.explode_x_range, effect=c.BULLET_EFFECT_UNICE) + # 消除冰道 + for item in self.plant_groups[i]: + if item.name == c.ICE_FROZEN_PLOT: + item.health = 0 + elif targetPlant.name == c.ICESHROOM: + self.freezeZombies(targetPlant) + targetPlant.boomed = True + else: + pass else: can_attack = False if (zombie_len > 0): for zombie in self.zombie_groups[i]: - if plant.canAttack(zombie): + if targetPlant.canAttack(zombie): can_attack = True break - if plant.state == c.IDLE and can_attack: - plant.setAttack() - elif (plant.state == c.ATTACK and (not can_attack)): - plant.setIdle() + if targetPlant.state == c.IDLE and can_attack: + targetPlant.setAttack() + elif (targetPlant.state == c.ATTACK and (not can_attack)): + targetPlant.setIdle() def checkPlants(self): for i in range(self.map_y_len):