fix
This commit is contained in:
parent
e58fdb1656
commit
81dcdfb76d
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,3 +6,5 @@ main.spec
|
|||||||
.vscode/
|
.vscode/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*/__pycache__/
|
*/__pycache__/
|
||||||
|
# ignore test
|
||||||
|
test.py
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"background_type":0,
|
"background_type":0,
|
||||||
"init_sun_value":50,
|
"init_sun_value":5000,
|
||||||
"zombie_list":[
|
"zombie_list":[
|
||||||
{"time":20000, "map_y":0, "name":"Zombie"},
|
{"time":20000, "map_y":0, "name":"Zombie"},
|
||||||
{"time":40000, "map_y":2, "name":"FlagZombie"},
|
{"time":40000, "map_y":2, "name":"FlagZombie"},
|
||||||
|
|||||||
@ -216,6 +216,7 @@ class MenuBar():
|
|||||||
for card in self.card_list:
|
for card in self.card_list:
|
||||||
card.draw(surface)
|
card.draw(surface)
|
||||||
|
|
||||||
|
# 关卡模式选植物的界面
|
||||||
class Panel():
|
class Panel():
|
||||||
def __init__(self, card_list, sun_value):
|
def __init__(self, card_list, sun_value):
|
||||||
self.loadImages(sun_value)
|
self.loadImages(sun_value)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
self.health = health
|
self.health = health
|
||||||
self.damage = damage
|
self.damage = damage
|
||||||
self.dead = False
|
self.dead = False
|
||||||
self.losHead = False
|
self.lostHead = False
|
||||||
self.helmet = False
|
self.helmet = False
|
||||||
self.head_group = head_group
|
self.head_group = head_group
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
def walking(self):
|
def walking(self):
|
||||||
if self.health <= 0:
|
if self.health <= 0:
|
||||||
self.setDie()
|
self.setDie()
|
||||||
elif self.health <= c.LOSTHEAD_HEALTH and not self.losHead:
|
elif self.health <= c.LOSTHEAD_HEALTH and not self.lostHead:
|
||||||
self.changeFrames(self.losthead_walk_frames)
|
self.changeFrames(self.losthead_walk_frames)
|
||||||
self.setLostHead()
|
self.setLostHead()
|
||||||
elif self.health <= c.NORMAL_HEALTH and self.helmet:
|
elif self.health <= c.NORMAL_HEALTH and self.helmet:
|
||||||
@ -83,7 +83,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
def attacking(self):
|
def attacking(self):
|
||||||
if self.health <= 0:
|
if self.health <= 0:
|
||||||
self.setDie()
|
self.setDie()
|
||||||
elif self.health <= c.LOSTHEAD_HEALTH and not self.losHead:
|
elif self.health <= c.LOSTHEAD_HEALTH and not self.lostHead:
|
||||||
self.changeFrames(self.losthead_attack_frames)
|
self.changeFrames(self.losthead_attack_frames)
|
||||||
self.setLostHead()
|
self.setLostHead()
|
||||||
elif self.health <= c.NORMAL_HEALTH and self.helmet:
|
elif self.health <= c.NORMAL_HEALTH and self.helmet:
|
||||||
@ -107,7 +107,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
def freezing(self):
|
def freezing(self):
|
||||||
if self.health <= 0:
|
if self.health <= 0:
|
||||||
self.setDie()
|
self.setDie()
|
||||||
elif self.health <= c.LOSTHEAD_HEALTH and not self.losHead:
|
elif self.health <= c.LOSTHEAD_HEALTH and not self.lostHead:
|
||||||
if self.old_state == c.WALK:
|
if self.old_state == c.WALK:
|
||||||
self.changeFrames(self.losthead_walk_frames)
|
self.changeFrames(self.losthead_walk_frames)
|
||||||
else:
|
else:
|
||||||
@ -117,7 +117,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
self.setWalk()
|
self.setWalk()
|
||||||
|
|
||||||
def setLostHead(self):
|
def setLostHead(self):
|
||||||
self.losHead = True
|
self.lostHead = True
|
||||||
if self.head_group is not None:
|
if self.head_group is not None:
|
||||||
self.head_group.add(ZombieHead(self.rect.centerx, self.rect.bottom))
|
self.head_group.add(ZombieHead(self.rect.centerx, self.rect.bottom))
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
|
|
||||||
if self.helmet:
|
if self.helmet:
|
||||||
self.changeFrames(self.helmet_walk_frames)
|
self.changeFrames(self.helmet_walk_frames)
|
||||||
elif self.losHead:
|
elif self.lostHead:
|
||||||
self.changeFrames(self.losthead_walk_frames)
|
self.changeFrames(self.losthead_walk_frames)
|
||||||
else:
|
else:
|
||||||
self.changeFrames(self.walk_frames)
|
self.changeFrames(self.walk_frames)
|
||||||
@ -195,7 +195,7 @@ class Zombie(pg.sprite.Sprite):
|
|||||||
|
|
||||||
if self.helmet:
|
if self.helmet:
|
||||||
self.changeFrames(self.helmet_attack_frames)
|
self.changeFrames(self.helmet_attack_frames)
|
||||||
elif self.losHead:
|
elif self.lostHead:
|
||||||
self.changeFrames(self.losthead_attack_frames)
|
self.changeFrames(self.losthead_attack_frames)
|
||||||
else:
|
else:
|
||||||
self.changeFrames(self.attack_frames)
|
self.changeFrames(self.attack_frames)
|
||||||
@ -270,6 +270,7 @@ class NormalZombie(Zombie):
|
|||||||
|
|
||||||
self.frames = self.walk_frames
|
self.frames = self.walk_frames
|
||||||
|
|
||||||
|
# 路障僵尸
|
||||||
class ConeHeadZombie(Zombie):
|
class ConeHeadZombie(Zombie):
|
||||||
def __init__(self, x, y, head_group):
|
def __init__(self, x, y, head_group):
|
||||||
Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, c.CONEHEAD_HEALTH, head_group)
|
Zombie.__init__(self, x, y, c.CONEHEAD_ZOMBIE, c.CONEHEAD_HEALTH, head_group)
|
||||||
|
|||||||
@ -6,10 +6,11 @@ from .state import mainmenu, screen, level
|
|||||||
|
|
||||||
# create a standard game
|
# create a standard game
|
||||||
def main():
|
def main():
|
||||||
|
# 控制状态机运行
|
||||||
game = tool.Control()
|
game = tool.Control()
|
||||||
state_dict = {c.MAIN_MENU: mainmenu.Menu(),
|
state_dict = {c.MAIN_MENU: mainmenu.Menu(),
|
||||||
c.GAME_VICTORY: screen.GameVictoryScreen(),
|
c.GAME_VICTORY: screen.GameVictoryScreen(),
|
||||||
c.GAME_LOSE: screen.GameLoseScreen(),
|
c.GAME_LOSE: screen.GameLoseScreen(),
|
||||||
c.LEVEL: level.Level()}
|
c.LEVEL: level.Level()}
|
||||||
game.setup_states(state_dict, c.MAIN_MENU)
|
game.setup_states(state_dict, c.MAIN_MENU)
|
||||||
game.main()
|
game.run()
|
||||||
@ -67,6 +67,7 @@ class Level(tool.State):
|
|||||||
_, y = self.map.getMapGridPos(0, i)
|
_, y = self.map.getMapGridPos(0, i)
|
||||||
self.cars.append(plant.Car(-25, y+20, i))
|
self.cars.append(plant.Car(-25, y+20, i))
|
||||||
|
|
||||||
|
# 更新函数每帧被调用,将鼠标事件传入给状态处理函数
|
||||||
def update(self, surface, current_time, mouse_pos, mouse_click):
|
def update(self, surface, current_time, mouse_pos, mouse_click):
|
||||||
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
||||||
if self.state == c.CHOOSE:
|
if self.state == c.CHOOSE:
|
||||||
@ -83,6 +84,7 @@ class Level(tool.State):
|
|||||||
self.map.setMapGridType(x, y, c.MAP_EXIST)
|
self.map.setMapGridType(x, y, c.MAP_EXIST)
|
||||||
|
|
||||||
def initState(self):
|
def initState(self):
|
||||||
|
# 小游戏才有CHOOSEBAR_TYPE
|
||||||
if c.CHOOSEBAR_TYPE in self.map_data:
|
if c.CHOOSEBAR_TYPE in self.map_data:
|
||||||
self.bar_type = self.map_data[c.CHOOSEBAR_TYPE]
|
self.bar_type = self.map_data[c.CHOOSEBAR_TYPE]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -16,6 +16,10 @@ class Menu(tool.State):
|
|||||||
|
|
||||||
def setupBackground(self):
|
def setupBackground(self):
|
||||||
frame_rect = [80, 0, 800, 600]
|
frame_rect = [80, 0, 800, 600]
|
||||||
|
# 1、形参中加单星号,即f(*x)则表示x为元组,所有对x的操作都应将x视为元组类型进行。
|
||||||
|
# 2、双星号同上,区别是x视为字典。
|
||||||
|
# 3、在变量前加单星号表示将元组(列表、集合)拆分为单个元素。
|
||||||
|
# 4、双星号同上,区别是目标为字典,字典前加单星号的话可以得到“键”。
|
||||||
self.bg_image = tool.get_image(tool.GFX[c.MAIN_MENU_IMAGE], *frame_rect)
|
self.bg_image = tool.get_image(tool.GFX[c.MAIN_MENU_IMAGE], *frame_rect)
|
||||||
self.bg_rect = self.bg_image.get_rect()
|
self.bg_rect = self.bg_image.get_rect()
|
||||||
self.bg_rect.x = 0
|
self.bg_rect.x = 0
|
||||||
@ -27,8 +31,7 @@ class Menu(tool.State):
|
|||||||
frame_rect = [0, 0, 165, 77]
|
frame_rect = [0, 0, 165, 77]
|
||||||
|
|
||||||
for name in frame_names:
|
for name in frame_names:
|
||||||
self.option_frames.append(tool.get_image(tool.GFX[name], *frame_rect, c.BLACK, 1.7))
|
self.option_frames.append(tool.get_image_menu(tool.GFX[name], *frame_rect, c.BLACK, 1.7))
|
||||||
|
|
||||||
self.option_frame_index = 0
|
self.option_frame_index = 0
|
||||||
self.option_image = self.option_frames[self.option_frame_index]
|
self.option_image = self.option_frames[self.option_frame_index]
|
||||||
self.option_rect = self.option_image.get_rect()
|
self.option_rect = self.option_image.get_rect()
|
||||||
@ -50,10 +53,12 @@ class Menu(tool.State):
|
|||||||
def update(self, surface, current_time, mouse_pos, mouse_click):
|
def update(self, surface, current_time, mouse_pos, mouse_click):
|
||||||
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
self.current_time = self.game_info[c.CURRENT_TIME] = current_time
|
||||||
|
|
||||||
|
# 没有选到选项时,检查有没有点到选项
|
||||||
if not self.option_clicked:
|
if not self.option_clicked:
|
||||||
if mouse_pos:
|
if mouse_pos:
|
||||||
self.checkOptionClick(mouse_pos)
|
self.checkOptionClick(mouse_pos)
|
||||||
else:
|
else:
|
||||||
|
# 点到后播放动画
|
||||||
if(self.current_time - self.option_timer) > 200:
|
if(self.current_time - self.option_timer) > 200:
|
||||||
self.option_frame_index += 1
|
self.option_frame_index += 1
|
||||||
if self.option_frame_index >= 2:
|
if self.option_frame_index >= 2:
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import os
|
|||||||
import json
|
import json
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
import pygame as pg
|
import pygame as pg
|
||||||
|
from pygame.locals import *
|
||||||
from . import constants as c
|
from . import constants as c
|
||||||
|
|
||||||
# an abstract class, one state of automata
|
# an abstract class, one state of automata
|
||||||
@ -9,18 +10,19 @@ class State():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.start_time = 0.0
|
self.start_time = 0.0
|
||||||
self.current_time = 0.0
|
self.current_time = 0.0
|
||||||
self.done = False # is it finished
|
self.done = False # false 代表未做完
|
||||||
self.next = None
|
self.next = None # 表示这个状态退出后要转到的下一个状态
|
||||||
self.persist = {}
|
self.persist = {} # 在状态间转换时需要传递的数据
|
||||||
|
|
||||||
|
# 当从其他状态进入这个状态时,需要进行的初始化操作
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def startup(self, current_time, persist):
|
def startup(self, current_time, persist):
|
||||||
'''abstract method'''
|
'''abstract method'''
|
||||||
|
# 当从这个状态退出时,需要进行的清除操作
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self.done = False
|
self.done = False
|
||||||
return self.persist
|
return self.persist
|
||||||
|
# 在这个状态运行时进行的更新操作
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update(self, surface, keys, current_time):
|
def update(self, surface, keys, current_time):
|
||||||
'''abstract method'''
|
'''abstract method'''
|
||||||
@ -30,7 +32,7 @@ class Control():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.screen = pg.display.get_surface()
|
self.screen = pg.display.get_surface()
|
||||||
self.done = False
|
self.done = False
|
||||||
self.clock = pg.time.Clock()
|
self.clock = pg.time.Clock() # 创建一个对象来帮助跟踪时间
|
||||||
self.fps = 60
|
self.fps = 60
|
||||||
self.keys = pg.key.get_pressed()
|
self.keys = pg.key.get_pressed()
|
||||||
self.mouse_pos = None
|
self.mouse_pos = None
|
||||||
@ -49,14 +51,18 @@ class Control():
|
|||||||
self.state.startup(self.current_time, self.game_info)
|
self.state.startup(self.current_time, self.game_info)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
# 返回自 pygame_init() 调用以来的毫秒数
|
||||||
self.current_time = pg.time.get_ticks()
|
self.current_time = pg.time.get_ticks()
|
||||||
|
|
||||||
if self.state.done:
|
if self.state.done:
|
||||||
self.flip_state()
|
self.flip_state()
|
||||||
|
|
||||||
self.state.update(self.screen, self.current_time, self.mouse_pos, self.mouse_click)
|
self.state.update(self.screen, self.current_time, self.mouse_pos, self.mouse_click)
|
||||||
self.mouse_pos = None
|
self.mouse_pos = None
|
||||||
self.mouse_click[0] = False
|
self.mouse_click[0] = False
|
||||||
self.mouse_click[1] = False
|
self.mouse_click[1] = False
|
||||||
|
|
||||||
|
# 状态转移
|
||||||
def flip_state(self):
|
def flip_state(self):
|
||||||
previous, self.state_name = self.state_name, self.state.next
|
previous, self.state_name = self.state_name, self.state.next
|
||||||
persist = self.state.cleanup()
|
persist = self.state.cleanup()
|
||||||
@ -75,11 +81,11 @@ class Control():
|
|||||||
self.mouse_pos = pg.mouse.get_pos()
|
self.mouse_pos = pg.mouse.get_pos()
|
||||||
self.mouse_click[0], _, self.mouse_click[1] = pg.mouse.get_pressed()
|
self.mouse_click[0], _, self.mouse_click[1] = pg.mouse.get_pressed()
|
||||||
print('pos:', self.mouse_pos, ' mouse:', self.mouse_click)
|
print('pos:', self.mouse_pos, ' mouse:', self.mouse_click)
|
||||||
else:
|
#else:
|
||||||
print(pg.event.event_name(event.type))
|
# print(pg.event.event_name(event.type))
|
||||||
|
|
||||||
|
|
||||||
def main(self):
|
def run(self):
|
||||||
while not self.done:
|
while not self.done:
|
||||||
self.event_loop()
|
self.event_loop()
|
||||||
self.update()
|
self.update()
|
||||||
@ -98,6 +104,18 @@ def get_image(sheet, x, y, width, height, colorkey=c.BLACK, scale=1):
|
|||||||
int(rect.height*scale)))
|
int(rect.height*scale)))
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
def get_image_menu(sheet, x, y, width, height, colorkey=c.BLACK, scale=1):
|
||||||
|
# 一定要保留阿尔法通道,修复主菜单bug,游戏中car显示又有bug
|
||||||
|
image = pg.Surface([width, height], SRCALPHA)
|
||||||
|
rect = image.get_rect()
|
||||||
|
|
||||||
|
image.blit(sheet, (0, 0), (x, y, width, height))
|
||||||
|
image.set_colorkey(colorkey)
|
||||||
|
image = pg.transform.scale(image,
|
||||||
|
(int(rect.width*scale),
|
||||||
|
int(rect.height*scale)))
|
||||||
|
return image
|
||||||
|
|
||||||
def load_image_frames(directory, image_name, colorkey, accept):
|
def load_image_frames(directory, image_name, colorkey, accept):
|
||||||
frame_list = []
|
frame_list = []
|
||||||
tmp = {}
|
tmp = {}
|
||||||
@ -121,6 +139,7 @@ def load_image_frames(directory, image_name, colorkey, accept):
|
|||||||
frame_list.append(tmp[i])
|
frame_list.append(tmp[i])
|
||||||
return frame_list
|
return frame_list
|
||||||
|
|
||||||
|
# colorkeys 是设置图像中的某个颜色值为透明,这里用来消除白边
|
||||||
def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.gif')):
|
def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.gif')):
|
||||||
graphics = {}
|
graphics = {}
|
||||||
for name1 in os.listdir(directory):
|
for name1 in os.listdir(directory):
|
||||||
@ -156,6 +175,7 @@ def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.
|
|||||||
graphics[name] = img
|
graphics[name] = img
|
||||||
return graphics
|
return graphics
|
||||||
|
|
||||||
|
# 从文件加载矩形碰撞范围
|
||||||
def loadZombieImageRect():
|
def loadZombieImageRect():
|
||||||
file_path = os.path.join('resources', 'data', 'entity', 'zombie.json')
|
file_path = os.path.join('resources', 'data', 'entity', 'zombie.json')
|
||||||
f = open(file_path)
|
f = open(file_path)
|
||||||
@ -171,8 +191,8 @@ def loadPlantImageRect():
|
|||||||
return data[c.PLANT_IMAGE_RECT]
|
return data[c.PLANT_IMAGE_RECT]
|
||||||
|
|
||||||
pg.init()
|
pg.init()
|
||||||
pg.display.set_caption(c.ORIGINAL_CAPTION)
|
pg.display.set_caption(c.ORIGINAL_CAPTION) # 设置标题
|
||||||
SCREEN = pg.display.set_mode(c.SCREEN_SIZE)
|
SCREEN = pg.display.set_mode(c.SCREEN_SIZE) # 设置初始屏幕
|
||||||
|
|
||||||
GFX = load_all_gfx(os.path.join("resources","graphics"))
|
GFX = load_all_gfx(os.path.join("resources","graphics"))
|
||||||
ZOMBIE_RECT = loadZombieImageRect()
|
ZOMBIE_RECT = loadZombieImageRect()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user