Merge branch 'garlic'

This commit is contained in:
星外之神 2022-06-03 22:36:13 +08:00
commit f1117a862f
42 changed files with 227 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -12,22 +12,27 @@ class Map():
if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS: if self.background_type in c.POOL_EQUIPPED_BACKGROUNDS:
self.width = c.GRID_POOL_X_LEN self.width = c.GRID_POOL_X_LEN
self.height = c.GRID_POOL_Y_LEN self.height = c.GRID_POOL_Y_LEN
self.gridHeightSize = c.GRID_POOL_Y_SIZE
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)] 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.ON_ROOF_BACKGROUNDS: elif self.background_type in c.ON_ROOF_BACKGROUNDS:
self.width = c.GRID_ROOF_X_LEN self.width = c.GRID_ROOF_X_LEN
self.height = c.GRID_ROOF_Y_LEN self.height = c.GRID_ROOF_Y_LEN
self.gridHeightSize = c.GRID_ROOF_Y_SIZE
self.map = [[deepcopy(c.MAP_STATE_TILE) for x in range(self.width)] for y in range(self.height)] self.map = [[deepcopy(c.MAP_STATE_TILE) for x in range(self.width)] for y in range(self.height)]
elif self.background_type == c.BACKGROUND_SINGLE: elif self.background_type == c.BACKGROUND_SINGLE:
self.width = c.GRID_X_LEN self.width = c.GRID_X_LEN
self.height = c.GRID_Y_LEN self.height = c.GRID_Y_LEN
self.gridHeightSize = c.GRID_Y_SIZE
self.map = [[(deepcopy(c.MAP_STATE_UNAVAILABLE), deepcopy(c.MAP_STATE_EMPTY))[y == 2] for x in range(self.width)] for y in range(self.height)] self.map = [[(deepcopy(c.MAP_STATE_UNAVAILABLE), deepcopy(c.MAP_STATE_EMPTY))[y == 2] for x in range(self.width)] for y in range(self.height)]
elif self.background_type == c.BACKGROUND_TRIPLE: elif self.background_type == c.BACKGROUND_TRIPLE:
self.width = c.GRID_X_LEN self.width = c.GRID_X_LEN
self.height = c.GRID_Y_LEN self.height = c.GRID_Y_LEN
self.gridHeightSize = c.GRID_Y_SIZE
self.map = [[(deepcopy(c.MAP_STATE_UNAVAILABLE), deepcopy(c.MAP_STATE_EMPTY))[y in {1, 2, 3}] for x in range(self.width)] for y in range(self.height)] self.map = [[(deepcopy(c.MAP_STATE_UNAVAILABLE), deepcopy(c.MAP_STATE_EMPTY))[y in {1, 2, 3}] for x in range(self.width)] for y in range(self.height)]
else: else:
self.width = c.GRID_X_LEN self.width = c.GRID_X_LEN
self.height = c.GRID_Y_LEN self.height = c.GRID_Y_LEN
self.gridHeightSize = c.GRID_Y_SIZE
self.map = [[deepcopy(c.MAP_STATE_EMPTY) for x in range(self.width)] for y in range(self.height)] self.map = [[deepcopy(c.MAP_STATE_EMPTY) for x in range(self.width)] for y in range(self.height)]
def isValid(self, map_x, map_y): def isValid(self, map_x, map_y):

View File

@ -1780,3 +1780,27 @@ class IceFrozenPlot(Plant):
self.health = 0 self.health = 0
class Garlic(Plant):
def __init__(self, x, y):
Plant.__init__(self, x, y, c.GARLIC, c.GARLIC_HEALTH, None)
self.load_images()
self.cracked1 = False
self.cracked2 = False
def load_images(self):
self.cracked1_frames = []
self.cracked2_frames = []
cracked1_frames_name = self.name + '_cracked1'
cracked2_frames_name = self.name + '_cracked2'
self.loadFrames(self.cracked1_frames, cracked1_frames_name, 1)
self.loadFrames(self.cracked2_frames, cracked2_frames_name, 1)
def idling(self):
if (not self.cracked1) and self.health <= c.GARLIC_CRACKED1_HEALTH:
self.changeFrames(self.cracked1_frames)
self.cracked1 = True
elif (not self.cracked2) and self.health <= c.GARLIC_CRACKED2_HEALTH:
self.changeFrames(self.cracked2_frames)
self.cracked2 = True

View File

@ -20,6 +20,10 @@ class Zombie(pg.sprite.Sprite):
self.rect = self.image.get_rect() self.rect = self.image.get_rect()
self.rect.x = x self.rect.x = x
self.rect.bottom = y self.rect.bottom = y
# 大蒜换行移动像素值,< 0时向上= 0时不变> 0时向上
self.targetYChange = 0
self.originalY = y
self.toChangeGroup = False
self.helmetHealth = helmetHealth self.helmetHealth = helmetHealth
self.helmetType2Health = helmetType2Health self.helmetType2Health = helmetType2Health
@ -191,13 +195,45 @@ class Zombie(pg.sprite.Sprite):
if self.helmetType2Health <= 0 and self.helmetType2: if self.helmetType2Health <= 0 and self.helmetType2:
self.changeFrames(self.walk_frames) self.changeFrames(self.walk_frames)
self.helmetType2 = False self.helmetType2 = False
if (self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio()):
if ((self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio())
and self.handleGarlicYChange()):
self.walk_timer = self.current_time self.walk_timer = self.current_time
if self.is_hypno: if self.is_hypno:
self.rect.x += 1 self.rect.x += 1
else: else:
self.rect.x -= 1 self.rect.x -= 1
def handleGarlicYChange(self):
if self.targetYChange < 0:
self.setWalk()
if self.rect.bottom > self.originalY + self.targetYChange: # 注意这里加的是负数
self.rect.bottom -= 3
# 过半时换行
if ((self.toChangeGroup) and
(self.rect.bottom >= self.originalY + 0.5*self.targetYChange)):
self.level.zombie_groups[self.mapY].remove(self)
self.level.zombie_groups[self.targetMapY].add(self)
else:
self.rect.bottom = self.originalY + self.targetYChange
self.targetYChange = 0
return None
elif self.targetYChange > 0:
self.setWalk()
if self.rect.bottom < self.originalY + self.targetYChange: # 注意这里加的是负数
self.rect.bottom += 3
# 过半时换行
if ((self.toChangeGroup) and
(self.rect.bottom <= self.originalY + 0.5*self.targetYChange)):
self.level.zombie_groups[self.mapY].remove(self)
self.level.zombie_groups[self.targetMapY].add(self)
else:
self.rect.bottom = self.originalY + self.targetYChange
self.targetYChange = 0
return None
else:
return True
def attacking(self): def attacking(self):
if self.checkToDie(self.losthead_attack_frames): if self.checkToDie(self.losthead_attack_frames):
return return
@ -216,6 +252,8 @@ class Zombie(pg.sprite.Sprite):
if self.prey.health > 0: if self.prey.health > 0:
if self.prey_is_plant: if self.prey_is_plant:
self.prey.setDamage(self.damage, self) self.prey.setDamage(self.damage, self)
if self.prey.name == c.GARLIC:
self.setWalk()
else: else:
self.prey.setDamage(self.damage) self.prey.setDamage(self.damage)
@ -677,7 +715,8 @@ class NewspaperZombie(Zombie):
self.helmetType2 = False self.helmetType2 = False
# 触发报纸撕裂音效 # 触发报纸撕裂音效
pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "newspaperRip.ogg")).play() pg.mixer.Sound(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ,"resources", "sound", "newspaperRip.ogg")).play()
if (self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio()): if ((self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio())
and self.handleGarlicYChange()):
self.walk_timer = self.current_time self.walk_timer = self.current_time
if self.frames == self.lostnewspaper_frames: if self.frames == self.lostnewspaper_frames:
pass pass
@ -1160,7 +1199,8 @@ class SnorkelZombie(Zombie):
if self.swimming: if self.swimming:
self.changeFrames(self.walk_frames) self.changeFrames(self.walk_frames)
self.swimming = False self.swimming = False
if (self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio()): if ((self.current_time - self.walk_timer) > (c.ZOMBIE_WALK_INTERVAL * self.getTimeRatio())
and self.handleGarlicYChange()):
self.walk_timer = self.current_time self.walk_timer = self.current_time
# 正在上浮或者下潜不用移动 # 正在上浮或者下潜不用移动
if (self.frames == self.float_frames) or (self.frames == self.sink_frames): if (self.frames == self.float_frames) or (self.frames == self.sink_frames):
@ -1219,7 +1259,6 @@ class SnorkelZombie(Zombie):
def setWalk(self): def setWalk(self):
self.state = c.WALK self.state = c.WALK
self.animate_interval = self.walk_animate_interval self.animate_interval = self.walk_animate_interval
if self.rect.right <= c.MAP_POOL_FRONT_X:
self.swimming = True self.swimming = True
self.changeFrames(self.sink_frames) self.changeFrames(self.sink_frames)

View File

@ -242,6 +242,7 @@ HOLE = 'Hole'
GRAVE = 'Grave' GRAVE = 'Grave'
GRAVEBUSTER = 'GraveBuster' GRAVEBUSTER = 'GraveBuster'
FUMESHROOM = 'FumeShroom' FUMESHROOM = 'FumeShroom'
GARLIC = 'Garlic'
# 植物集体属性集合 # 植物集体属性集合
@ -302,7 +303,7 @@ PLANT_NON_CHECK_ATTACK_STATE = ( # 这里运用了集合运算
TORCHWOOD, SUNFLOWER, TORCHWOOD, SUNFLOWER,
SUNSHROOM, COFFEEBEAN, SUNSHROOM, COFFEEBEAN,
GRAVEBUSTER, LILYPAD, GRAVEBUSTER, LILYPAD,
HYPNOSHROOM, HYPNOSHROOM, GARLIC,
} | } |
# 非植物类 # 非植物类
NON_PLANT_OBJECTS NON_PLANT_OBJECTS
@ -324,6 +325,9 @@ WALLNUT_CRACKED2_HEALTH = WALLNUT_HEALTH//3
TALLNUT_HEALTH = 8000 TALLNUT_HEALTH = 8000
TALLNUT_CRACKED1_HEALTH = TALLNUT_HEALTH//3 * 2 TALLNUT_CRACKED1_HEALTH = TALLNUT_HEALTH//3 * 2
TALLNUT_CRACKED2_HEALTH = TALLNUT_HEALTH//3 TALLNUT_CRACKED2_HEALTH = TALLNUT_HEALTH//3
GARLIC_HEALTH = 450
GARLIC_CRACKED1_HEALTH = GARLIC_HEALTH//3 * 2
GARLIC_CRACKED2_HEALTH = GARLIC_HEALTH//3
# 坚果保龄球攻击伤害 # 坚果保龄球攻击伤害
WALLNUT_BOWLING_DAMAGE = 550 WALLNUT_BOWLING_DAMAGE = 550
@ -367,6 +371,136 @@ CARD_TANGLEKLEP = 'card_tangleklep'
CARD_DOOMSHROOM = 'card_doomshroom' CARD_DOOMSHROOM = 'card_doomshroom'
CARD_GRAVEBUSTER = 'card_gravebuster' CARD_GRAVEBUSTER = 'card_gravebuster'
CARD_FUMESHROOM = 'card_fumeshroom' CARD_FUMESHROOM = 'card_fumeshroom'
CARD_GARLIC = 'card_garlic'
# 植物卡片信息汇总(包括植物名称, 卡片名称, 阳光, 冷却时间)
PLANT_CARD_INFO = (# 元组 (植物名称, 卡片名称, 阳光, 冷却时间)
(PEASHOOTER,
CARD_PEASHOOTER,
100,
7500),
(SUNFLOWER,
CARD_SUNFLOWER,
50,
7500),
(CHERRYBOMB,
CARD_CHERRYBOMB,
150,
50000),
(WALLNUT,
CARD_WALLNUT,
50,
30000),
(POTATOMINE,
CARD_POTATOMINE,
25,
30000),
(SNOWPEASHOOTER,
CARD_SNOWPEASHOOTER,
175,
7500),
(CHOMPER,
CARD_CHOMPER,
150,
7500),
(REPEATERPEA,
CARD_REPEATERPEA,
200,
7500),
(PUFFSHROOM,
CARD_PUFFSHROOM,
0,
7500),
(SUNSHROOM,
CARD_SUNSHROOM,
25,
7500),
(FUMESHROOM,
CARD_FUMESHROOM,
75,
7500),
(GRAVEBUSTER,
CARD_GRAVEBUSTER,
75,
7500),
(HYPNOSHROOM,
CARD_HYPNOSHROOM,
75,
30000),
(SCAREDYSHROOM,
CARD_SCAREDYSHROOM,
25,
7500),
(ICESHROOM,
CARD_ICESHROOM,
75,
50000),
(DOOMSHROOM,
CARD_DOOMSHROOM,
75,
50000),
(LILYPAD,
CARD_LILYPAD,
25,
7500),
(SQUASH,
CARD_SQUASH,
50,
30000),
(TANGLEKLEP,
CARD_TANGLEKLEP,
25,
30000),
(THREEPEASHOOTER,
CARD_THREEPEASHOOTER,
325,
7500),
(JALAPENO,
CARD_JALAPENO,
125,
50000),
(SPIKEWEED,
CARD_SPIKEWEED,
100,
7500),
(TORCHWOOD,
CARD_TORCHWOOD,
175,
7500),
(TALLNUT,
CARD_TALLNUT,
125,
30000),
(SEASHROOM,
CARD_SEASHROOM,
125,
30000),
(STARFRUIT,
CARD_STARFRUIT,
125,
7500),
(COFFEEBEAN,
CARD_COFFEEBEAN,
75,
7500),
(GARLIC,
CARD_GARLIC,
50,
7500),
# 应当保证这两个在一般模式下不可选的特殊植物恒在最后
(WALLNUTBOWLING,
CARD_WALLNUT,
0,
0),
(REDWALLNUTBOWLING,
CARD_REDWALLNUT,
0,
0),
)
# 指定了哪些卡可选(排除坚果保龄球特殊植物)
CARDS_TO_CHOOSE = range(len(PLANT_CARD_INFO) - 2)
# 植物卡片信息汇总(包括植物名称, 卡片名称, 阳光, 冷却时间) # 植物卡片信息汇总(包括植物名称, 卡片名称, 阳光, 冷却时间)

View File

@ -918,6 +918,8 @@ class Level(tool.State):
new_plant = plant.GraveBuster(x, y, self.plant_groups[map_y], self.map, map_x) new_plant = plant.GraveBuster(x, y, self.plant_groups[map_y], self.map, map_x)
elif self.plant_name == c.FUMESHROOM: elif self.plant_name == c.FUMESHROOM:
new_plant = plant.FumeShroom(x, y, self.bullet_groups[map_y], self.zombie_groups[map_y]) new_plant = plant.FumeShroom(x, y, self.bullet_groups[map_y], self.zombie_groups[map_y])
elif self.plant_name == c.GARLIC:
new_plant = plant.Garlic(x, y)
if new_plant.can_sleep and self.background_type in c.DAYTIME_BACKGROUNDS: if new_plant.can_sleep and self.background_type in c.DAYTIME_BACKGROUNDS:
@ -1043,7 +1045,6 @@ class Level(tool.State):
# 被攻击对象是植物时才可能刷新 # 被攻击对象是植物时才可能刷新
if zombie.prey_is_plant: if zombie.prey_is_plant:
# 新植物种在被攻击植物同一格时才可能刷新 # 新植物种在被攻击植物同一格时才可能刷新
mapX, mapY = self.map.getMapIndex(zombie.prey.rect.centerx, zombie.prey.rect.centery)
if (mapX, mapY) == self.newPlantAndPositon[1]: if (mapX, mapY) == self.newPlantAndPositon[1]:
# 如果被攻击植物是睡莲和花盆,同一格种了植物必然刷新 # 如果被攻击植物是睡莲和花盆,同一格种了植物必然刷新
# 如果被攻击植物不是睡莲和花盆,同一格种了南瓜头才刷新 # 如果被攻击植物不是睡莲和花盆,同一格种了南瓜头才刷新
@ -1131,6 +1132,22 @@ class Level(tool.State):
elif targetPlant.name == c.REDWALLNUTBOWLING: elif targetPlant.name == c.REDWALLNUTBOWLING:
if targetPlant.state == c.IDLE: if targetPlant.state == c.IDLE:
targetPlant.setAttack() targetPlant.setAttack()
elif targetPlant.name == c.GARLIC:
zombie.setAttack(targetPlant)
# 向吃过大蒜的僵尸传入level
zombie.level = self
zombie.toChangeGroup = True
zombie.mapY = i
if i == 0:
_move = 1
elif i == self.map_y_len - 1:
_move = -1
else:
_move = random.randint(0, 1)*2 - 1
if self.map.map[i][0][c.MAP_PLOT_TYPE] != self.map.map[i + _move][0][c.MAP_PLOT_TYPE]:
_move = -_move
zombie.targetMapY = i + _move
zombie.targetYChange = _move * self.map.gridHeightSize
else: else:
zombie.setAttack(targetPlant) zombie.setAttack(targetPlant)