进度
- 调整僵尸动画(原版动画比较复杂,暂时搁置)
# 添加僵尸的血量属性(由于各僵尸血量可能不一样,必须写在init里)
self.HP = 100
# 更新队列方法中添加死亡判断
def update(self, screen):
dieZBs_id = []
i = 0
for aZB in self.ZBs:
if aZB.HP <= 0: # 僵尸死亡判断
dieZBs_id.append(i)
aZB.update(screen) # 僵尸显示
i += 1
for i in dieZBs_id:
self.ZBs.pop(i)
# 然后添加豌豆的碰撞判断,防止豌豆射死僵尸后,该行没有僵尸导致豌豆报错
if zbq.isEmpty():
break
# 此处的循环逻辑有些复杂,因为不能在循环的过程中移除元素(会导致迭代器长度变化),只能在循环过程中记录下标,待循环结束后统一移除,有些搞,但想不到更好的办法,待改进
# 已找到改进方法:使用index方法
dieZBs_id.append(self.ZBs.index(aZB))
# 在豌豆碰撞检测中添加僵尸受伤逻辑
for aZB in zbq.ZBs:
if pygame.sprite.collide_circle(aPea, aZB):
aZB.HP -= 20
diePeas.append(aPea)
break
以上代码可实现每5颗豌豆即可杀死僵尸
- 使豌豆能杀死僵尸(见上)
- 添加僵尸啃食植物动画和逻辑,并使其能杀死植物
# 这里有些复杂,因为僵尸与植物碰撞时,二者都要发生状态改变:
# 僵尸停止行走并啃食,植物血量减少,且植物死亡时会消失,僵尸需在其消失后改变啃食状态
# 首先修改僵尸属性,使之能加载啃食动画
self.status = 'walk'
self.animations = {'walk': [], 'eat': []} # 改列表为字典,由状态来索引保存的帧图
# 导入帧图的方法也要修改
def import_assets(self):
for status in self.animations.keys():
status_path = self.animepath + '/' + status
for image in os.listdir(status_path):
full_path = status_path + '/' + image
image_surf = pygame.image.load(full_path).convert_alpha()
self.animations[status].append(image_surf)
self.image = self.animations[self.status][int(self.f)] # 显示图片很容易,按字典索引即可
# 接下来制作啃食触发逻辑,僵尸碰撞到植物时触发状态改变
# 按照规范,由僵尸队列来统一控制、管理僵尸的碰撞
# 以下代码作用是:当僵尸碰到植物,改变状态,并获取其位置、对植物造成伤害
def isZBcollidePL(self, aZB, agrr):
# 由该僵尸的位置定位到格子id,再判断该格左中右三格的碰撞
acell = int((aZB.pos.x - Benchmark[0]) / 100)
# 首先僵尸中心所在的格子应该在草地上,否则不执行判断
def func():
aZB.status = 'eat'
aZB.eatpl = acell
thepl.HP -= aZB.ATK
if 0 <= acell <= 8:
thepl = agrr.PLs[acell]
# 若该格有植物,100%僵尸和其碰撞,直接吃
if thepl is not None:
func()
# 若该格没有植物,则判断左右格,注意0和8号位列表溢出
else:
if 0 > acell:
thepl = agrr.PLs[acell - 1]
if thepl is not None and pygame.sprite.collide_circle(thepl, aZB):
func()
if acell < 8:
thepl = agrr.PLs[acell + 1]
if thepl is not None and pygame.sprite.collide_circle(thepl, aZB):
func()
# 在植物列表下,添加死亡判断:
if aplant.HP <= 0:
self.PLs[i] = None
# 当植物死亡后,对应位置会置空,此时僵尸的eat方法会检测到并改变状态
def eat(self, aggr):
if aggr.PLs[self.eatpl] is None:
self.status = 'walk'
self.eatpl = 1000