Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/PythonPlantsVsZombies.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added source/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added source/__pycache__/constants.cpython-312.pyc
Binary file not shown.
Binary file added source/__pycache__/main.cpython-312.pyc
Binary file not shown.
Binary file added source/__pycache__/tool.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file added source/component/__pycache__/map.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
59 changes: 59 additions & 0 deletions source/component/plant.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self, x, start_y, dest_y, name, damage, ice):
self.ice = ice
self.state = c.FLY
self.current_time = 0
self.knockback = 0 # 击退效果,默认为0表示没有击退

def loadFrames(self, frames, name):
frame_list = tool.GFX[name]
Expand Down Expand Up @@ -825,6 +826,64 @@ def loadImages(self, name, scale):

self.frames = self.idle_frames

# Chinese Red Theme Plants
class RedPeony(Plant):
"""红牡丹 - 中国红主题植物,能够释放花粉攻击多个僵尸"""
def __init__(self, x, y, zombie_groups, map_y):
Plant.__init__(self, x, y, c.RED_PEONY, c.RED_PEONY_HEALTH, None)
self.shoot_timer = 0
self.map_y = map_y
self.zombie_groups = zombie_groups
self.attack_range = 3 # 攻击范围为3行

def attacking(self):
if (self.current_time - self.shoot_timer) > 3000:
# 释放花粉攻击范围内的所有僵尸
for i in range(-self.attack_range, self.attack_range + 1):
tmp_y = self.map_y + i
if tmp_y < 0 or tmp_y >= c.GRID_Y_LEN:
continue
for zombie in self.zombie_groups[tmp_y]:
if self.canAttack(zombie):
zombie.setDamage(c.RED_PEONY_POLLEN_DAMAGE)
self.shoot_timer = self.current_time

def canAttack(self, zombie):
if (self.state != c.SLEEP and zombie.state != c.DIE and
self.rect.x <= zombie.rect.right and
self.rect.right + c.GRID_X_SIZE * 2 >= zombie.rect.x):
return True
return False

class FirecrackerPlant(Plant):
"""鞭炮花 - 中国红主题植物,能够发射鞭炮攻击僵尸"""
def __init__(self, x, y, bullet_group):
Plant.__init__(self, x, y, c.FIRECRACKER_PLANT, c.FIRECRACKER_PLANT_HEALTH, bullet_group)
self.shoot_timer = 0
self.bullet_speed = 6

def attacking(self):
if (self.current_time - self.shoot_timer) > 2500:
# 发射鞭炮子弹
self.bullet_group.add(Bullet(self.rect.right, self.rect.y, self.rect.y,
c.BULLET_PEA, c.FIRECRACKER_DAMAGE, False))
self.shoot_timer = self.current_time

class LionDancePea(Plant):
"""舞狮豌豆 - 中国红主题植物,能够发射具有击退效果的豌豆"""
def __init__(self, x, y, bullet_group):
Plant.__init__(self, x, y, c.LION_DANCE_PEA, c.LION_DANCE_PEA_HEALTH, bullet_group)
self.shoot_timer = 0

def attacking(self):
if (self.current_time - self.shoot_timer) > 3000:
# 发射具有击退效果的豌豆
bullet = Bullet(self.rect.right, self.rect.y, self.rect.y,
c.BULLET_PEA, c.LION_DANCE_PEA_DAMAGE, False)
bullet.knockback = c.LION_DANCE_PEA_KNOCKBACK
self.bullet_group.add(bullet)
self.shoot_timer = self.current_time

class WallNutBowling(Plant):
def __init__(self, x, y, map_y, level):
Plant.__init__(self, x, y, c.WALLNUTBOWLING, 1, None)
Expand Down
146 changes: 145 additions & 1 deletion source/component/zombie.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,148 @@ def loadImages(self):
color = c.WHITE
self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'], color)

self.frames = self.helmet_walk_frames
self.frames = self.helmet_walk_frames

# Chinese Red Theme Zombies
class LanternZombie(Zombie):
"""灯笼僵尸 - 中国红主题僵尸,手持灯笼照亮周围区域"""
def __init__(self, x, y, head_group):
Zombie.__init__(self, x, y, c.LANTERN_ZOMBIE, c.LANTERN_ZOMBIE_HEALTH, head_group)
self.speed = c.LANTERN_ZOMBIE_SPEED
self.lantern_light_range = c.LANTERN_LIGHT_RANGE
self.lantern_on = True

def loadImages(self):
self.walk_frames = []
self.attack_frames = []
self.losthead_walk_frames = []
self.losthead_attack_frames = []
self.die_frames = []
self.boomdie_frames = []

walk_name = self.name
attack_name = self.name + 'Attack'
losthead_walk_name = self.name + 'LostHead'
losthead_attack_name = self.name + 'LostHeadAttack'
die_name = c.NORMAL_ZOMBIE + 'Die'
boomdie_name = c.BOOMDIE

frame_list = [self.walk_frames, self.attack_frames, self.losthead_walk_frames,
self.losthead_attack_frames, self.die_frames, self.boomdie_frames]
name_list = [walk_name, attack_name, losthead_walk_name,
losthead_attack_name, die_name, boomdie_name]

for i, name in enumerate(name_list):
self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'])

self.frames = self.walk_frames

class LionDanceZombie(Zombie):
"""舞狮僵尸 - 中国红主题僵尸,穿着舞狮服装,具有较高的生命值和攻击力"""
def __init__(self, x, y, head_group):
Zombie.__init__(self, x, y, c.LION_DANCE_ZOMBIE, c.LION_DANCE_ZOMBIE_HEALTH, head_group)
self.speed = c.LION_DANCE_ZOMBIE_SPEED
self.damage = c.LION_DANCE_ATTACK_DAMAGE
self.helmet = True

def loadImages(self):
self.helmet_walk_frames = []
self.helmet_attack_frames = []
self.walk_frames = []
self.attack_frames = []
self.losthead_walk_frames = []
self.losthead_attack_frames = []
self.die_frames = []
self.boomdie_frames = []

helmet_walk_name = self.name
helmet_attack_name = self.name + 'Attack'
walk_name = self.name + 'NoCostume'
attack_name = self.name + 'NoCostumeAttack'
losthead_walk_name = self.name + 'LostHead'
losthead_attack_name = self.name + 'LostHeadAttack'
die_name = self.name + 'Die'
boomdie_name = c.BOOMDIE

frame_list = [self.helmet_walk_frames, self.helmet_attack_frames,
self.walk_frames, self.attack_frames, self.losthead_walk_frames,
self.losthead_attack_frames, self.die_frames, self.boomdie_frames]
name_list = [helmet_walk_name, helmet_attack_name,
walk_name, attack_name, losthead_walk_name,
losthead_attack_name, die_name, boomdie_name]

for i, name in enumerate(name_list):
self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'])

self.frames = self.helmet_walk_frames

class ChineseNewYearZombie(Zombie):
"""春节僵尸 - 中国红主题僵尸,穿着春节服装,死亡时掉落金币"""
def __init__(self, x, y, head_group, gold_group):
Zombie.__init__(self, x, y, c.CHINESE_NEW_YEAR_ZOMBIE, c.CHINESE_NEW_YEAR_ZOMBIE_HEALTH, head_group)
self.speed = c.CHINESE_NEW_YEAR_ZOMBIE_SPEED
self.gold_group = gold_group
self.gold_drop = c.CHINESE_NEW_YEAR_GOLD_DROP

def loadImages(self):
self.walk_frames = []
self.attack_frames = []
self.losthead_walk_frames = []
self.losthead_attack_frames = []
self.die_frames = []
self.boomdie_frames = []

walk_name = self.name
attack_name = self.name + 'Attack'
losthead_walk_name = self.name + 'LostHead'
losthead_attack_name = self.name + 'LostHeadAttack'
die_name = self.name + 'Die'
boomdie_name = c.BOOMDIE

frame_list = [self.walk_frames, self.attack_frames, self.losthead_walk_frames,
self.losthead_attack_frames, self.die_frames, self.boomdie_frames]
name_list = [walk_name, attack_name, losthead_walk_name,
losthead_attack_name, die_name, boomdie_name]

for i, name in enumerate(name_list):
self.loadFrames(frame_list[i], name, tool.ZOMBIE_RECT[name]['x'])

self.frames = self.walk_frames

def dying(self):
# 死亡时掉落金币
if not self.dead:
for i in range(self.gold_drop):
gold = Gold(self.rect.centerx, self.rect.y)
self.gold_group.add(gold)
self.dead = True
super().dying()

class Gold(pg.sprite.Sprite):
"""金币类 - 春节僵尸死亡时掉落"""
def __init__(self, x, y):
pg.sprite.Sprite.__init__(self)
self.image = tool.get_image(tool.GFX['Gold'], 0, 0, 30, 30, c.BLACK, 1)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.y = y
self.y_vel = -2 # 金币向上飘
self.gravity = 0.1 # 重力效果
self.live_time = 5000 # 金币存在时间
self.created_time = pg.time.get_ticks()

def update(self, game_info):
# 金币向上飘然后下落
self.y_vel += self.gravity
self.rect.y += self.y_vel

# 金币存在时间结束后消失
if pg.time.get_ticks() - self.created_time > self.live_time:
self.kill()

def checkCollision(self, x, y):
if(x >= self.rect.x and x <= self.rect.right and
y >= self.rect.y and y <= self.rect.bottom):
self.kill()
return True
return False
32 changes: 32 additions & 0 deletions source/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,26 @@
HYPNOSHROOM = 'HypnoShroom'
WALLNUTBOWLING = 'WallNutBowling'
REDWALLNUTBOWLING = 'RedWallNutBowling'
# Chinese Red Theme Plants
RED_PEONY = 'RedPeony' # 红牡丹
FIRECRACKER_PLANT = 'FirecrackerPlant' # 鞭炮花
LION_DANCE_PEA = 'LionDancePea' # 舞狮豌豆

PLANT_HEALTH = 5
WALLNUT_HEALTH = 30
WALLNUT_CRACKED1_HEALTH = 20
WALLNUT_CRACKED2_HEALTH = 10
WALLNUT_BOWLING_DAMAGE = 10

# Chinese Red Theme Plant Properties
RED_PEONY_HEALTH = 15 # 红牡丹生命值
RED_PEONY_POLLEN_DAMAGE = 3 # 红牡丹花粉伤害
FIRECRACKER_PLANT_HEALTH = 10 # 鞭炮花生命值
FIRECRACKER_DAMAGE = 2 # 鞭炮伤害
LION_DANCE_PEA_HEALTH = 5 # 舞狮豌豆生命值
LION_DANCE_PEA_DAMAGE = 4 # 舞狮豌豆伤害
LION_DANCE_PEA_KNOCKBACK = 50 # 舞狮豌豆击退效果

PRODUCE_SUN_INTERVAL = 7000
FLOWER_SUN_INTERVAL = 22000
SUN_LIVE_TIME = 7000
Expand Down Expand Up @@ -129,6 +142,10 @@
CARD_ICESHROOM = 'card_iceshroom'
CARD_HYPNOSHROOM = 'card_hypnoshroom'
CARD_REDWALLNUT = 'card_redwallnut'
# Chinese Red Theme Plant Cards
CARD_RED_PEONY = 'card_redpeony'
CARD_FIRECRACKER_PLANT = 'card_firecrackerplant'
CARD_LION_DANCE_PEA = 'card_liondancepea'

#BULLET INFO
BULLET_PEA = 'PeaNormal'
Expand All @@ -145,6 +162,10 @@
FLAG_ZOMBIE = 'FlagZombie'
NEWSPAPER_ZOMBIE = 'NewspaperZombie'
BOOMDIE = 'BoomDie'
# Chinese Red Theme Zombies
LANTERN_ZOMBIE = 'LanternZombie' # 灯笼僵尸
LION_DANCE_ZOMBIE = 'LionDanceZombie' # 舞狮僵尸
CHINESE_NEW_YEAR_ZOMBIE = 'ChineseNewYearZombie' # 春节僵尸

LOSTHEAD_HEALTH = 5
NORMAL_HEALTH = 10
Expand All @@ -153,6 +174,17 @@
BUCKETHEAD_HEALTH = 30
NEWSPAPER_HEALTH = 15

# Chinese Red Theme Zombie Properties
LANTERN_ZOMBIE_HEALTH = 15 # 灯笼僵尸生命值
LANTERN_ZOMBIE_SPEED = 1.2 # 灯笼僵尸移动速度
LANTERN_LIGHT_RANGE = 3 # 灯笼照亮范围
LION_DANCE_ZOMBIE_HEALTH = 30 # 舞狮僵尸生命值
LION_DANCE_ZOMBIE_SPEED = 0.8 # 舞狮僵尸移动速度
LION_DANCE_ATTACK_DAMAGE = 2 # 舞狮僵尸攻击伤害
CHINESE_NEW_YEAR_ZOMBIE_HEALTH = 25 # 春节僵尸生命值
CHINESE_NEW_YEAR_ZOMBIE_SPEED = 1.0 # 春节僵尸移动速度
CHINESE_NEW_YEAR_GOLD_DROP = 5 # 春节僵尸掉落金币数量

ATTACK_INTERVAL = 1000
ZOMBIE_WALK_INTERVAL = 70

Expand Down
Binary file added source/state/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added source/state/__pycache__/level.cpython-312.pyc
Binary file not shown.
Binary file added source/state/__pycache__/mainmenu.cpython-312.pyc
Binary file not shown.
Binary file added source/state/__pycache__/screen.cpython-312.pyc
Binary file not shown.
Loading