维护清理
This commit is contained in:
parent
25bf28e4f4
commit
cd32e142e0
@ -9,11 +9,11 @@ class Map():
|
||||
self.background_type = background_type
|
||||
# 注意:从0开始编号
|
||||
# 集合内容需要deepcopy
|
||||
if self.background_type in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
self.width = c.GRID_POOL_X_LEN
|
||||
self.height = c.GRID_POOL_Y_LEN
|
||||
self.map = [[(deepcopy(c.MAP_STATE_EMPTY), deepcopy(c.MAP_STATE_WATER))[y in {2, 3}] for x in range(self.width)] for y in range(self.height)]
|
||||
elif self.background_type in {c.BACKGROUND_ROOF, c.BACKGROUND_ROOFNIGHT}:
|
||||
elif self.background_type in c.ON_ROOF_BACKGROUNDS:
|
||||
self.width = c.GRID_ROOF_X_LEN
|
||||
self.height = c.GRID_ROOF_Y_LEN
|
||||
self.map = [[deepcopy(c.MAP_STATE_TILE) for x in range(self.width)] for y in range(self.height)]
|
||||
@ -52,11 +52,11 @@ class Map():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if any((i in {c.HOLE, c.ICE_FROZEN_PLOT, c.GRAVE}) for i in self.map[map_y][map_x][c.MAP_PLANT]):
|
||||
if any((i in c.NON_PLANT_OBJECTS) for i in self.map[map_y][map_x][c.MAP_PLANT]):
|
||||
return False
|
||||
if self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_GRASS: # 草地
|
||||
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
||||
if plantName not in {c.LILYPAD, c.SEASHROOM, c.TANGLEKLEP}: # 这里的集合也可以换成存储在某一文件中的常数的表达
|
||||
if plantName not in c.WATER_PLANTS:
|
||||
if not self.map[map_y][map_x][c.MAP_PLANT]: # 没有植物肯定可以种植
|
||||
return True
|
||||
elif (all((i in {'花盆(未实现)', '南瓜头(未实现)'}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||
@ -68,7 +68,7 @@ class Map():
|
||||
return False
|
||||
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_TILE: # 屋顶
|
||||
# 首先需要判断植物是否是水生植物,水生植物不能种植在陆地上
|
||||
if plantName not in {c.LILYPAD, c.SEASHROOM, c.TANGLEKLEP}: # 这里的集合也可以换成存储在某一文件中的常数的表达
|
||||
if plantName not in c.WATER_PLANTS:
|
||||
if '花盆(未实现)' in self.map[map_y][map_x][c.MAP_PLANT]:
|
||||
if (all((i in {'花盆(未实现)', '南瓜头(未实现)'}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||
and (plantName not in self.map[map_y][map_x][c.MAP_PLANT])): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植;判断方法:并集
|
||||
@ -83,7 +83,7 @@ class Map():
|
||||
else:
|
||||
return False
|
||||
elif self.map[map_y][map_x][c.MAP_PLOT_TYPE] == c.MAP_WATER: # 水里
|
||||
if plantName in {c.LILYPAD, c.SEASHROOM, c.TANGLEKLEP}: # 是水生植物
|
||||
if plantName in c.WATER_PLANTS: # 是水生植物
|
||||
if not self.map[map_y][map_x][c.MAP_PLANT]: # 只有无植物时才能在水里种植水生植物
|
||||
return True
|
||||
else:
|
||||
@ -92,7 +92,7 @@ class Map():
|
||||
if c.LILYPAD in self.map[map_y][map_x][c.MAP_PLANT]:
|
||||
if (all((i in {c.LILYPAD, '南瓜头(未实现)'}) for i in self.map[map_y][map_x][c.MAP_PLANT])
|
||||
and (plantName not in self.map[map_y][map_x][c.MAP_PLANT])): # 例外植物:集合中填花盆和南瓜头,只要这里没有这种植物就能种植;判断方法:并集
|
||||
if plantName in {c.SPIKEWEED, c.POTATOMINE,'花盆(未实现)'}: # 不能在睡莲上种植的植物
|
||||
if plantName in {c.SPIKEWEED, c.POTATOMINE, '花盆(未实现)'}: # 不能在睡莲上种植的植物
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@ -105,11 +105,11 @@ class Map():
|
||||
|
||||
def getMapIndex(self, x, y):
|
||||
# 引入新地图后需要增加这里的内容
|
||||
if self.background_type in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
x -= c.MAP_POOL_OFFSET_X
|
||||
y -= c.MAP_POOL_OFFSET_Y
|
||||
return (x // c.GRID_POOL_X_SIZE, y // c.GRID_POOL_Y_SIZE)
|
||||
elif self.background_type in {c.BACKGROUND_ROOF, c.BACKGROUND_ROOFNIGHT}:
|
||||
elif self.background_type in c.ON_ROOF_BACKGROUNDS:
|
||||
x -= c.MAP_ROOF_OFFSET_X
|
||||
y -= c.MAP_ROOF_OFFSET_X
|
||||
gridX = x // c.GRID_ROOF_X_SIZE
|
||||
@ -124,10 +124,10 @@ class Map():
|
||||
return (x // c.GRID_X_SIZE, y // c.GRID_Y_SIZE)
|
||||
|
||||
def getMapGridPos(self, map_x, map_y):
|
||||
if self.background_type in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
return (map_x * c.GRID_POOL_X_SIZE + c.GRID_POOL_X_SIZE//2 + c.MAP_POOL_OFFSET_X,
|
||||
map_y * c.GRID_POOL_Y_SIZE + c.GRID_POOL_Y_SIZE//5 * 3 + c.MAP_POOL_OFFSET_Y)
|
||||
elif self.background_type in {c.BACKGROUND_ROOF, c.BACKGROUND_ROOFNIGHT}:
|
||||
elif self.background_type in c.ON_ROOF_BACKGROUNDS:
|
||||
return (map_x * c.GRID_ROOF_X_SIZE + c.GRID_ROOF_X_SIZE//2 + c.MAP_ROOF_OFFSET_X,
|
||||
map_y * c.GRID_ROOF_Y_SIZE + 20 * max(0, (6 - map_y)) + c.GRID_ROOF_Y_SIZE//5 * 3 + c.MAP_POOL_OFFSET_Y)
|
||||
else:
|
||||
|
||||
@ -467,7 +467,7 @@ class ThreePeaShooter(Plant):
|
||||
offset_y = 9 # modify bullet in the same y position with bullets of other plants
|
||||
for i in range(3):
|
||||
tmp_y = self.map_y + (i - 1)
|
||||
if self.background_type in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
if tmp_y < 0 or tmp_y >= c.GRID_POOL_Y_LEN:
|
||||
continue
|
||||
else:
|
||||
|
||||
@ -104,6 +104,19 @@ BACKGROUND_WALLNUTBOWLING = 6
|
||||
BACKGROUND_SINGLE = 7
|
||||
BACKGROUND_TRIPLE = 8
|
||||
|
||||
# 地图类型集合
|
||||
# 白天场地
|
||||
DAYTIME_BACKGROUNDS = { BACKGROUND_DAY, BACKGROUND_POOL,
|
||||
BACKGROUND_ROOF, BACKGROUND_WALLNUTBOWLING,
|
||||
BACKGROUND_SINGLE, BACKGROUND_TRIPLE,
|
||||
}
|
||||
# 带有泳池的场地
|
||||
POOL_EQUIPPED_BACKGROUNDS = { BACKGROUND_POOL, BACKGROUND_FOG,
|
||||
}
|
||||
# 屋顶上的场地
|
||||
ON_ROOF_BACKGROUNDS = { BACKGROUND_ROOF, BACKGROUND_ROOFNIGHT,
|
||||
}
|
||||
|
||||
# 夜晚地图的墓碑数量等级
|
||||
GRADE_GRAVES = 'grade_graves'
|
||||
GRADE0_GRAVES = 0 # 无墓碑
|
||||
@ -218,6 +231,60 @@ GRAVE = 'Grave'
|
||||
GRAVEBUSTER = 'GraveBuster'
|
||||
FUMESHROOM = 'FumeShroom'
|
||||
|
||||
# 植物集体属性
|
||||
# 在生效时不用与僵尸进行碰撞检测的对象
|
||||
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING = {# 注意爆炸坚果的触发也是啃食类碰撞,因此这里不能省略
|
||||
SQUASH, ICESHROOM,
|
||||
REDWALLNUTBOWLING, CHERRYBOMB,
|
||||
JALAPENO, DOOMSHROOM,
|
||||
POTATOMINE,
|
||||
}
|
||||
# 非植物对象
|
||||
NON_PLANT_OBJECTS = { HOLE, ICE_FROZEN_PLOT,
|
||||
GRAVE,
|
||||
}
|
||||
# 所有可能不用与僵尸进行碰撞检测的对象
|
||||
CAN_SKIP_ZOMBIE_COLLISION_CHECK = ( # 生效时不检测的植物
|
||||
SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING |
|
||||
# 非植物对象
|
||||
NON_PLANT_OBJECTS |
|
||||
# 地刺类
|
||||
{SPIKEWEED, }
|
||||
)
|
||||
# 死亡时不触发音效的对象
|
||||
PLANT_DIE_SOUND_EXCEPTIONS = { WALLNUTBOWLING, TANGLEKLEP,
|
||||
ICE_FROZEN_PLOT, HOLE,
|
||||
GRAVE, JALAPENO,
|
||||
REDWALLNUTBOWLING, CHERRYBOMB,
|
||||
}
|
||||
# color_key为白色的对象
|
||||
PLANT_COLOR_KEY_WHITE = { POTATOMINE, SPIKEWEED,
|
||||
JALAPENO, SCAREDYSHROOM,
|
||||
SUNSHROOM, ICESHROOM,
|
||||
HYPNOSHROOM, SQUASH,
|
||||
WALLNUTBOWLING, REDWALLNUTBOWLING,
|
||||
}
|
||||
# 直接水生植物
|
||||
WATER_PLANTS = { LILYPAD, SEASHROOM,
|
||||
TANGLEKLEP,
|
||||
}
|
||||
# 不用使用通用方法检验攻击状态的植物
|
||||
PLANT_NON_CHECK_ATTACK_STATE = ({ # 单独指定攻击状态的植物
|
||||
WALLNUTBOWLING,
|
||||
# 没有攻击状态的植物
|
||||
WALLNUT, TALLNUT,
|
||||
TORCHWOOD, SUNFLOWER,
|
||||
SUNSHROOM, COFFEEBEAN,
|
||||
GRAVEBUSTER, LILYPAD,
|
||||
HYPNOSHROOM,
|
||||
} |
|
||||
# 非植物类
|
||||
NON_PLANT_OBJECTS
|
||||
)
|
||||
# 范围爆炸植物,即灰烬植物与寒冰菇
|
||||
ASH_PLANTS_AND_ICESHROOM = { REDWALLNUTBOWLING, CHERRYBOMB,
|
||||
JALAPENO, DOOMSHROOM,
|
||||
ICESHROOM,}
|
||||
|
||||
# 植物生命值
|
||||
PLANT_HEALTH = 300
|
||||
@ -316,6 +383,12 @@ ZOMBONI = 'Zomboni'
|
||||
|
||||
BOOMDIE = 'BoomDie'
|
||||
|
||||
# 僵尸集体属性
|
||||
# 水上僵尸集合
|
||||
WATER_ZOMBIE = { DUCKY_TUBE_ZOMBIE, CONEHEAD_DUCKY_TUBE_ZOMBIE,
|
||||
BUCKETHEAD_DUCKY_TUBE_ZOMBIE,
|
||||
}
|
||||
|
||||
# 对僵尸的攻击类型设置
|
||||
ZOMBIE_DEAFULT_DAMAGE = 'helmet2First'
|
||||
ZOMBIE_HELMET_2_FIRST = 'helmet2First' # 优先攻击二类防具
|
||||
|
||||
@ -149,7 +149,7 @@ class Level(tool.State):
|
||||
while (volume >= minCost) and (len(zombieList) < 50):
|
||||
newZombie = choices(useableZombies, weights)[0]
|
||||
# 普通僵尸、路障僵尸、铁桶僵尸有概率生成水中变种
|
||||
if self.background_type in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
# 有泳池第一轮的第四波设定上生成水生僵尸
|
||||
if survivalRounds == 0 and wave == 4:
|
||||
if newZombie in self.convertZombieInPool:
|
||||
@ -226,7 +226,7 @@ class Level(tool.State):
|
||||
else:
|
||||
self.zombie_groups[item[1]].add(zombie.ConeHeadZombie(itemX, itemY, self.head_group))
|
||||
self.graveZombieCreated = True
|
||||
elif self.map_data[c.BACKGROUND_TYPE] in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
elif self.map_data[c.BACKGROUND_TYPE] in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
if not self.createdZombieFromPool:
|
||||
if current_time - self.waveTime > 1500:
|
||||
for i in range(3):
|
||||
@ -637,7 +637,7 @@ class Level(tool.State):
|
||||
for i in self.plant_groups[map_y]:
|
||||
if (x >= i.rect.x and x <= i.rect.right and
|
||||
y >= i.rect.y and y <= i.rect.bottom):
|
||||
if i.name in {c.HOLE, c.ICE_FROZEN_PLOT, c.GRAVE}:
|
||||
if i.name in c.NON_PLANT_OBJECTS:
|
||||
continue
|
||||
# 优先移除花盆、睡莲上的植物而非花盆、睡莲本身
|
||||
if len(self.map.map[map_y][map_x][c.MAP_PLANT]) >= 2:
|
||||
@ -791,8 +791,8 @@ class Level(tool.State):
|
||||
if map_y == None:
|
||||
# 情况复杂:分水路和陆路,不能简单实现,需要另外加判断
|
||||
# 0, 1, 4, 5路为陆路,2, 3路为水路
|
||||
if self.map_data[c.BACKGROUND_TYPE] in {c.BACKGROUND_POOL, c.BACKGROUND_FOG}:
|
||||
if name in {c.DUCKY_TUBE_ZOMBIE, c.CONEHEAD_DUCKY_TUBE_ZOMBIE, c.BUCKETHEAD_DUCKY_TUBE_ZOMBIE}: # 水生僵尸集合
|
||||
if self.map_data[c.BACKGROUND_TYPE] in c.POOL_EQUIPPED_BACKGROUNDS:
|
||||
if name in c.WATER_ZOMBIE: # 水生僵尸集合
|
||||
map_y = randint(2, 3)
|
||||
elif name == '这里应该换成气球僵尸的名字(最好写调用的变量名,最好不要直接写,保持风格统一)':
|
||||
map_y = randint(0, 5)
|
||||
@ -923,7 +923,7 @@ class Level(tool.State):
|
||||
new_plant = plant.FumeShroom(x, y, self.bullet_groups[map_y], self.zombie_groups[map_y])
|
||||
|
||||
|
||||
if new_plant.can_sleep and self.background_type in {c.BACKGROUND_DAY, c.BACKGROUND_POOL, c.BACKGROUND_ROOF, c.BACKGROUND_WALLNUTBOWLING, c.BACKGROUND_SINGLE, c.BACKGROUND_TRIPLE}:
|
||||
if new_plant.can_sleep and self.background_type in c.DAYTIME_BACKGROUNDS:
|
||||
new_plant.setSleep()
|
||||
mushroomSleep = True
|
||||
else:
|
||||
@ -981,12 +981,7 @@ class Level(tool.State):
|
||||
rect = frame_list[0].get_rect()
|
||||
width, height = rect.w, rect.h
|
||||
|
||||
if (plant_name in { c.POTATOMINE, c.SPIKEWEED,
|
||||
c.JALAPENO, c.SCAREDYSHROOM,
|
||||
c.SUNSHROOM, c.ICESHROOM,
|
||||
c.HYPNOSHROOM, c.SQUASH,
|
||||
c.WALLNUTBOWLING, c.REDWALLNUTBOWLING,
|
||||
}):
|
||||
if (plant_name in c.PLANT_COLOR_KEY_WHITE):
|
||||
color = c.WHITE
|
||||
else:
|
||||
color = c.BLACK
|
||||
@ -1087,27 +1082,10 @@ class Level(tool.State):
|
||||
attackableBackupPlant.append(plant)
|
||||
# 一般植物情形
|
||||
# 同时也忽略了不可啃食对象
|
||||
elif plant.name not in {# 不可啃食对象
|
||||
# 非植物对象
|
||||
c.HOLE, c.ICE_FROZEN_PLOT,
|
||||
c.GRAVE,
|
||||
# 对一般僵尸无条件不可啃食植物:地刺
|
||||
c.SPIKEWEED,
|
||||
# 对一般僵尸有条件不可啃食植物:跳起的倭瓜、释放效果后的爆炸类植物
|
||||
# 这类在后面还需要判断
|
||||
c.SQUASH, c.ICESHROOM,
|
||||
c.REDWALLNUTBOWLING, c.CHERRYBOMB,
|
||||
c.JALAPENO, c.DOOMSHROOM,
|
||||
c.POTATOMINE
|
||||
}:
|
||||
elif plant.name not in c.CAN_SKIP_ZOMBIE_COLLISION_CHECK:
|
||||
attackableCommonPlants.append(plant)
|
||||
# 在某些状态下忽略啃食碰撞但某些状况下不能忽略的情形
|
||||
elif plant.name in {# 注意爆炸坚果的触发也是啃食类碰撞,因此这里不能省略
|
||||
c.SQUASH, c.ICESHROOM,
|
||||
c.REDWALLNUTBOWLING, c.CHERRYBOMB,
|
||||
c.JALAPENO, c.DOOMSHROOM,
|
||||
c.POTATOMINE,
|
||||
}:
|
||||
elif plant.name in c.SKIP_ZOMBIE_COLLISION_CHECK_WHEN_WORKING:
|
||||
if plant.name == c.SQUASH:
|
||||
if not plant.squashing:
|
||||
attackableCommonPlants.append(plant)
|
||||
@ -1125,7 +1103,7 @@ class Level(tool.State):
|
||||
for actualTargetPlant in self.plant_groups[i]:
|
||||
# 检测同一格的其他植物
|
||||
if self.map.getMapIndex(actualTargetPlant.rect.centerx, actualTargetPlant.rect.bottom) == (map_x, map_y):
|
||||
if actualTargetPlant.name in {"南瓜头(未实现)"}:
|
||||
if actualTargetPlant.name == "南瓜头(未实现)":
|
||||
targetPlant = actualTargetPlant
|
||||
break
|
||||
elif actualTargetPlant.name not in {c.LILYPAD, "花盆(未实现)"}:
|
||||
@ -1241,10 +1219,7 @@ class Level(tool.State):
|
||||
# 毁灭菇的情况:爆炸时为了防止蘑菇云被坑掩盖没有加入坑,这里毁灭菇死亡(即爆炸动画结束)后再加入
|
||||
if targetPlant.name == c.DOOMSHROOM:
|
||||
self.plant_groups[map_y].add(plant.Hole(targetPlant.originalX, targetPlant.originalY, self.map.map[map_y][map_x][c.MAP_PLOT_TYPE]))
|
||||
elif targetPlant.name not in { c.WALLNUTBOWLING, c.TANGLEKLEP,
|
||||
c.ICE_FROZEN_PLOT, c.HOLE,
|
||||
c.GRAVE, c.JALAPENO,
|
||||
c.REDWALLNUTBOWLING, c.CHERRYBOMB,}:
|
||||
elif targetPlant.name not in c.PLANT_DIE_SOUND_EXCEPTIONS:
|
||||
# 触发植物死亡音效
|
||||
pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "plantDie.ogg")).play()
|
||||
else:
|
||||
@ -1265,17 +1240,7 @@ class Level(tool.State):
|
||||
def checkPlant(self, targetPlant, i):
|
||||
zombie_len = len(self.zombie_groups[i])
|
||||
# 不用检查攻击状况的情况
|
||||
if targetPlant.name in { # 单独指定攻击状态的植物
|
||||
c.WALLNUTBOWLING,
|
||||
# 没有攻击状态的植物
|
||||
c.WALLNUT, c.TALLNUT,
|
||||
c.TORCHWOOD, c.SUNFLOWER,
|
||||
c.SUNSHROOM, c.COFFEEBEAN,
|
||||
c.GRAVEBUSTER, c.LILYPAD,
|
||||
c.HYPNOSHROOM,
|
||||
# 非植物类
|
||||
c.HOLE, c.GRAVE,
|
||||
c.ICE_FROZEN_PLOT}:
|
||||
if targetPlant.name in c.PLANT_NON_CHECK_ATTACK_STATE:
|
||||
pass
|
||||
elif targetPlant.name == c.THREEPEASHOOTER:
|
||||
if targetPlant.state == c.IDLE:
|
||||
@ -1360,9 +1325,7 @@ class Level(tool.State):
|
||||
targetPlant.setAttack(zombie, self.zombie_groups[i])
|
||||
break
|
||||
# 灰烬植物与寒冰菇
|
||||
elif targetPlant.name in { c.REDWALLNUTBOWLING, c.CHERRYBOMB,
|
||||
c.JALAPENO, c.DOOMSHROOM,
|
||||
c.ICESHROOM,}:
|
||||
elif targetPlant.name in c.ASH_PLANTS_AND_ICESHROOM:
|
||||
if targetPlant.start_boom and (not targetPlant.boomed):
|
||||
# 这样分成两层是因为场上灰烬植物肯定少,一个一个判断代价高,先笼统判断灰烬即可
|
||||
if targetPlant.name in {c.REDWALLNUTBOWLING, c.CHERRYBOMB}:
|
||||
@ -1467,7 +1430,7 @@ class Level(tool.State):
|
||||
for i in self.plant_groups[map_y]:
|
||||
if (x >= i.rect.x and x <= i.rect.right and
|
||||
y >= i.rect.y and y <= i.rect.bottom):
|
||||
if i.name in {c.HOLE, c.ICE_FROZEN_PLOT, c.GRAVE}:
|
||||
if i.name in c.NON_PLANT_OBJECTS:
|
||||
continue
|
||||
# 优先选中睡莲、花盆上的植物
|
||||
if len(self.map.map[map_y][map_x][c.MAP_PLANT]) >= 2:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user