commit
721fb85827
@ -2,6 +2,7 @@
|
||||
"background_type":2,
|
||||
"init_sun_value":5000,
|
||||
"shovel":1,
|
||||
"spawn_zombies":"zombie_list",
|
||||
"zombie_list":[
|
||||
{"time":1000, "map_y":2, "name":"FootballZombie"},
|
||||
{"time":60000, "map_y":2, "name":"Zombie"}
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type": 0,
|
||||
"init_sun_value": 50,
|
||||
"shovel": 1,
|
||||
"spawn_zombies":"auto",
|
||||
"included_zombies":["Zombie"],
|
||||
"num_flags":2,
|
||||
"zombie_list": [
|
||||
{ "time": 20000, "name": "Zombie" },
|
||||
{ "time": 40000, "name": "FlagZombie" },
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type":0,
|
||||
"init_sun_value":50,
|
||||
"shovel":1,
|
||||
"spawn_zombies":"auto",
|
||||
"included_zombies":["Zombie", "ConeheadZombie"],
|
||||
"num_flags":3,
|
||||
"zombie_list":[
|
||||
{"time":20000, "name":"Zombie"},
|
||||
{"time":40000, "name":"FlagZombie"},
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type":1,
|
||||
"init_sun_value":50,
|
||||
"shovel":1,
|
||||
"spawn_zombies":"auto",
|
||||
"included_zombies":["Zombie", "ConeheadZombie", "BucketheadZombie"],
|
||||
"num_flags":3,
|
||||
"zombie_list":[
|
||||
{"time":20000, "name":"Zombie"},
|
||||
{"time":40000, "name":"ConeheadZombie"},
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type":2,
|
||||
"init_sun_value":50,
|
||||
"shovel":1,
|
||||
"spawn_zombies":"auto",
|
||||
"included_zombies":["Zombie", "ConeheadZombie", "BucketheadZombie", "FootballZombie"],
|
||||
"num_flags":4,
|
||||
"zombie_list":[
|
||||
{"time":20000, "name":"Zombie"},
|
||||
{"time":40000, "name":"ConeheadZombie"},
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type":0,
|
||||
"choosebar_type":1,
|
||||
"shovel":1,
|
||||
"spawn_zombies":"auto",
|
||||
"num_flags":4,
|
||||
"included_zombies":["Zombie", "ConeheadZombie", "BucketheadZombie"],
|
||||
"card_pool":[
|
||||
{"name":"Peashooter"},
|
||||
{"name":"SnowPea"},
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
"background_type":6,
|
||||
"choosebar_type":2,
|
||||
"shovel":0,
|
||||
"spawn_zombies":"auto",
|
||||
"included_zombies":["Zombie", "ConeheadZombie", "BucketheadZombie"],
|
||||
"num_flags":4,
|
||||
"card_pool":[
|
||||
{"name":"WallNutBowling"},
|
||||
{"name":"RedWallNutBowling"}
|
||||
|
||||
@ -97,6 +97,16 @@ BACKGROUND_WALLNUTBOWLING = 6
|
||||
BACKGROUND_SINGLE = 7
|
||||
BACKGROUND_TRIPLE = 8
|
||||
|
||||
# 僵尸生成方式
|
||||
SPAWN_ZOMBIES = 'spawn_zombies'
|
||||
SPAWN_ZOMBIES_AUTO = 'auto'
|
||||
SPAWN_ZOMBIES_LIST = 'list'
|
||||
INCLUDED_ZOMBIES = 'included_zombies'
|
||||
NUM_FLAGS = 'num_flags'
|
||||
INEVITABLE_ZOMBIE_DICT = 'inevitable_zombie_list'
|
||||
SURVIVAL_ROUNDS = 'survival_rounds'
|
||||
|
||||
|
||||
# 地图单元格属性
|
||||
MAP_PLANT = 'plantnames'
|
||||
MAP_SLEEP = 'sleep' # 有没有休眠的蘑菇,作是否能种植咖啡豆的判断
|
||||
|
||||
@ -104,12 +104,89 @@ class Level(tool.State):
|
||||
self.hypno_zombie_groups.append(pg.sprite.Group())
|
||||
self.bullet_groups.append(pg.sprite.Group())
|
||||
|
||||
|
||||
# 按照规则生成每一波僵尸
|
||||
# 可以考虑将波刷新和一波中的僵尸生成分开
|
||||
# useableZombie是指可用的僵尸种类的元组
|
||||
# inevitableZombie指在本轮必然出现的僵尸,输入形式为字典: {波数1:(僵尸1, 僵尸2……), 波数2:(僵尸1, 僵尸2……)……}
|
||||
def createWaves(self, useableZombies, numFlags, survivalRounds=0, inevitableZombieDict=None):
|
||||
waves = []
|
||||
|
||||
# 权重值
|
||||
weights = []
|
||||
for zombie in useableZombies:
|
||||
weights.append(self.createZombieInfo[zombie][1])
|
||||
|
||||
# 按照原版pvz设计的僵尸容量函数,是从无尽解析的,但是普通关卡也可以遵循
|
||||
for wave in range(1, 10 * numFlags + 1):
|
||||
volume = int(int((wave + survivalRounds*20)*0.8)/2) + 1
|
||||
if wave % 10 == 0:
|
||||
volume = int(volume*2.5)
|
||||
zombieList = []
|
||||
|
||||
if inevitableZombieDict and (wave in inevitableZombieDict.keys()):
|
||||
for newZombie in inevitableZombieDict[wave]:
|
||||
zombieList.append(newZombie)
|
||||
volume -= self.createZombieInfo[newZombie][0]
|
||||
if volume < 0:
|
||||
print('警告:第{}波中手动设置的僵尸级别总数超过上限!'.format(wave))
|
||||
|
||||
while (volume > 0) and (len(zombieList) < 50):
|
||||
newZombie = choices(useableZombies, weights)[0]
|
||||
if self.createZombieInfo[newZombie][0] <= volume:
|
||||
zombieList.append(newZombie)
|
||||
volume -= self.createZombieInfo[newZombie][0]
|
||||
waves.append(zombieList)
|
||||
|
||||
self.waves = waves
|
||||
|
||||
|
||||
# 僵尸的刷新机制
|
||||
def refreshWaves(self, current_time, survivalRounds=0):
|
||||
if self.waveNum >= self.map_data[c.NUM_FLAGS] * 10:
|
||||
return
|
||||
if (self.waveNum == 0): # 还未开始出现僵尸
|
||||
if (self.waveTime == 0): # 表明刚刚开始游戏
|
||||
self.waveTime = current_time
|
||||
else:
|
||||
if (survivalRounds == 0) and (self.bar_type == c.CHOOSEBAR_STATIC): # 首次选卡等待时间较长
|
||||
if current_time - self.waveTime >= 18000:
|
||||
self.waveNum += 1
|
||||
self.waveTime = current_time
|
||||
self.waveZombies = self.waves[self.waveNum - 1]
|
||||
self.numZombie = len(self.waveZombies)
|
||||
else:
|
||||
if (current_time - self.waveTime >= 6000):
|
||||
self.waveNum += 1
|
||||
self.waveTime = current_time
|
||||
self.waveZombies = self.waves[self.waveNum - 1]
|
||||
self.numZombie = len(self.waveZombies)
|
||||
return
|
||||
if (current_time - self.waveTime >= 25000 + randint(0, 6000)) or (self.bar_type != c.CHOOSEBAR_STATIC and current_time - self.waveTime >= 12500 + randint(0, 3000)):
|
||||
self.waveNum += 1
|
||||
self.waveTime = current_time
|
||||
self.waveZombies = self.waves[self.waveNum - 1]
|
||||
self.numZombie = len(self.waveZombies)
|
||||
return
|
||||
|
||||
|
||||
numZombies = 0
|
||||
for i in range(self.map_y_len):
|
||||
numZombies += len(self.zombie_groups[i])
|
||||
if numZombies / self.numZombie < 0.15:
|
||||
self.waveNum += 1
|
||||
self.waveTime = current_time
|
||||
self.waveZombies = self.waves[self.waveNum - 1]
|
||||
return
|
||||
|
||||
|
||||
|
||||
def setupZombies(self):
|
||||
def takeTime(element):
|
||||
return element[0]
|
||||
|
||||
self.zombie_list = []
|
||||
# 目前设置为从JSON文件中读取僵尸出现的时间、种类、位置信息,以后可以将时间设置为模仿原版的机制,位置设置为随机数
|
||||
# 目前设置为从JSON文件中读取僵尸出现的时间、种类、位置信息,以后可以将时间设置为模仿原版的机制
|
||||
for data in self.map_data[c.ZOMBIE_LIST]:
|
||||
if 'map_y' in data.keys():
|
||||
self.zombie_list.append((data['time'], data['name'], data['map_y']))
|
||||
@ -199,7 +276,34 @@ class Level(tool.State):
|
||||
|
||||
self.removeMouseImage()
|
||||
self.setupGroups()
|
||||
if (c.ZOMBIE_LIST in self.map_data.keys()) and self.map_data[c.SPAWN_ZOMBIES] == c.SPAWN_ZOMBIES_LIST:
|
||||
self.setupZombies()
|
||||
else:
|
||||
# 僵尸波数数据及僵尸生成数据
|
||||
self.waveNum = 0 # 还未出现僵尸时定义为0
|
||||
self.waveTime = 0
|
||||
self.waveZombies = []
|
||||
self.numZombie = 0
|
||||
# 新的僵尸生成机制:级别——权重生成
|
||||
self.createZombieInfo = {# 生成僵尸:(级别, 权重)
|
||||
c.NORMAL_ZOMBIE:(1, 4000),
|
||||
c.FLAG_ZOMBIE:(1, 0),
|
||||
c.CONEHEAD_ZOMBIE:(2, 4000),
|
||||
c.BUCKETHEAD_ZOMBIE:(4, 3000),
|
||||
c.NEWSPAPER_ZOMBIE:(2, 1000),
|
||||
c.FOOTBALL_ZOMBIE:(2, 2000)
|
||||
}
|
||||
|
||||
# 暂时没有生存模式,所以 survivalRounds = 0
|
||||
if c.INEVITABLE_ZOMBIE_DICT in self.map_data.keys():
|
||||
self.createWaves( useableZombies=self.map_data[c.INCLUDED_ZOMBIES],
|
||||
numFlags=self.map_data[c.NUM_FLAGS],
|
||||
survivalRounds=0,
|
||||
inevitableZombieDict=self.map_data[c.INEVITABLE_ZOMBIE_DICT])
|
||||
else:
|
||||
self.createWaves( useableZombies=self.map_data[c.INCLUDED_ZOMBIES],
|
||||
numFlags=self.map_data[c.NUM_FLAGS],
|
||||
survivalRounds=0)
|
||||
self.setupCars()
|
||||
|
||||
# 地图有铲子才添加铲子
|
||||
@ -217,15 +321,6 @@ class Level(tool.State):
|
||||
|
||||
self.setupLittleMenu()
|
||||
|
||||
# 新的僵尸生成机制:级别——权重生成
|
||||
self.createZombieInfo = {# 生成僵尸:(级别, 权重)
|
||||
c.NORMAL_ZOMBIE:(1, 4000),
|
||||
c.FLAG_ZOMBIE:(1, 0),
|
||||
c.CONEHEAD_ZOMBIE:(2, 4000),
|
||||
c.BUCKETHEAD_ZOMBIE:(4, 3000),
|
||||
c.NEWSPAPER_ZOMBIE:(2, 1000),
|
||||
c.FOOTBALL_ZOMBIE:(2, 2000)
|
||||
}
|
||||
|
||||
# 小菜单
|
||||
def setupLittleMenu(self):
|
||||
@ -357,6 +452,7 @@ class Level(tool.State):
|
||||
pg.mixer.music.play(-1, 0)
|
||||
return
|
||||
|
||||
if (c.ZOMBIE_LIST in self.map_data.keys()) and self.map_data[c.SPAWN_ZOMBIES] == c.SPAWN_ZOMBIES_LIST:
|
||||
# 旧僵尸生成方式
|
||||
if self.zombie_start_time == 0:
|
||||
self.zombie_start_time = self.current_time
|
||||
@ -370,6 +466,13 @@ class Level(tool.State):
|
||||
else: # len(data) == 2 没有指定map_y
|
||||
self.createZombie(data[1])
|
||||
self.zombie_list.remove(data)
|
||||
else:
|
||||
self.refreshWaves(self.current_time)
|
||||
for i in self.waveZombies:
|
||||
self.createZombie(i)
|
||||
else:
|
||||
self.waveZombies = []
|
||||
|
||||
|
||||
for i in range(self.map_y_len):
|
||||
self.bullet_groups[i].update(self.game_info)
|
||||
@ -451,42 +554,6 @@ class Level(tool.State):
|
||||
self.checkGameState()
|
||||
|
||||
|
||||
# 按照规则生成每一波僵尸
|
||||
# 可以考虑将波刷新和一波中的僵尸生成分开
|
||||
# useableZombie是指可用的僵尸种类的元组
|
||||
# inevitableZombie指在本轮必然出现的僵尸,输入形式为字典: {波数1:(僵尸1, 僵尸2……), 波数2:(僵尸1, 僵尸2……)……}
|
||||
def createWaves(self, useableZombies, numFlags, survivalRounds=0, inevitableZombieDict=None):
|
||||
waves = []
|
||||
|
||||
# 权重值
|
||||
weights = []
|
||||
for zombie in useableZombies:
|
||||
weights.append(self.createZombieInfo[zombie][1])
|
||||
|
||||
# 按照原版pvz设计的僵尸容量函数,是从无尽解析的,但是普通关卡也可以遵循
|
||||
for wave in range(1, 10 * numFlags + 1):
|
||||
volume = int(int((wave + survivalRounds*20)*0.8)/2) + 1
|
||||
if wave % 10 == 0:
|
||||
volume = int(volume*2.5)
|
||||
zombieList = []
|
||||
|
||||
if inevitableZombieDict and (wave in inevitableZombieDict.keys()):
|
||||
for newZombie in inevitableZombieDict[wave]:
|
||||
zombieList += newZombie
|
||||
volume -= self.createZombieInfo[newZombie][0]
|
||||
if volume < 0:
|
||||
print('警告:第{}波中手动设置的僵尸级别总数超过上限!'.format(wave))
|
||||
|
||||
while (volume > 0) and (len(zombieList) < 50):
|
||||
newZombie = choices(useableZombies, weights) # 注意这个的输出是列表
|
||||
if self.createZombieInfo[newZombie][0] <= volume:
|
||||
zombieList += newZombie
|
||||
volume -= self.createZombieInfo[newZombie][0]
|
||||
waves.append(zombieList)
|
||||
|
||||
self.waves = waves
|
||||
|
||||
|
||||
def createZombie(self, name, map_y=None):
|
||||
# 有指定时按照指定生成,无指定时随机位置生成
|
||||
# 0:白天 1:夜晚 2:泳池 3:浓雾 4:屋顶 5:月夜 6:坚果保龄球
|
||||
@ -911,12 +978,20 @@ class Level(tool.State):
|
||||
self.killPlant(plant)
|
||||
|
||||
def checkVictory(self):
|
||||
if (c.ZOMBIE_LIST in self.map_data.keys()) and self.map_data[c.SPAWN_ZOMBIES] == c.SPAWN_ZOMBIES_LIST:
|
||||
if len(self.zombie_list) > 0:
|
||||
return False
|
||||
for i in range(self.map_y_len):
|
||||
if len(self.zombie_groups[i]) > 0:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
if self.waveNum < self.map_data[c.NUM_FLAGS] * 10:
|
||||
return False
|
||||
for i in range(self.map_y_len):
|
||||
if len(self.zombie_groups[i]) > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
def checkLose(self):
|
||||
for i in range(self.map_y_len):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user