提示:python坦克大战(当初在b站学习尚学堂的python课,中间有一个坦克大战的项目,但是那个非常简陋,就一个半拉子框架,当时学的挺感兴趣,自己就又加工了一番。需要的可以拿来当python大作业,我感觉应该是没问题的。哈哈~~)
是基于pygame外部库的,没有这个库的小伙伴,在运行时,要先导入库啊。
pip install pygame
代码如下(示例):
'''
面向对象的需求分析:
1.坦克类
坦克的移动
发射子弹
碰撞检测
2.子弹类
移动
碰撞检测
3.爆炸物类
爆炸效果
4.墙壁类
基本属性
可不可以被击毁
能否穿过
5.音频类
播放音效
6.主逻辑类
游戏的开始
接受键盘值(实现对应功能)
游戏的结束
# 获取当前文件绝对路径
current_path = os.path.abspath(_file_)
# 获取当前文件的父目录
father_path = os.path.dirname(current_path)
'''
import pygame,time,random,os
# 宏定义
_pydis=pygame.display
# 全局变量
MY_COLOR=pygame.Color(255,255,255)
Font_color=pygame.Color(255,0,0)
Font_color2=pygame.Color(0,0,0)
class Main():
win=None
Screen_Height=800
Screen_Width=500
# 记录得分,击毁一辆得20分
Score=0
# 英雄坦
Tank_D=None
# 敌方坦克(列表存储)
EnemyTankList=[]
# 敌方坦克数量
EnemyTank_count=2
# 创建敌方坦克子弹列表
EnemyBulletList=[]
# 创建英雄子弹列表
BulletList=[]
# 爆炸效果列表
ExplorerList=[]
# 墙体爆炸效果列表
WallExplorerList=[]
# 砖墙墙壁列表
WallList=[]
# 草丛列表
CaoWallList=[]
# 铁墙列表
TieWallList=[]
# 游戏暂停开始标志位
flag=True
count=0
# 游戏开始界面控制
flag1=False
# 重开音效控制位
flag2=True
# 游戏胜利音效控制位
flag3=True
def __init__(self):
pass
#开始
def StartGame(self):
# 初始化窗口
_pydis.init()
# 创建窗口
Main.win=_pydis.set_mode([Main.Screen_Height,Main.Screen_Width])
# 设置标题
_pydis.set_caption("简易版坦克大战")
# 创建初始英雄坦克
self.CreatTank()
# 创减敌方坦克
self.CreatEnemyTank()
# 创建墙壁
self.CreatWall()
# 判断是不是重开
# 开场背景音乐
if self.flag2:
# music=Music('坦克大战 修改测试版\sound\\bgm.wav')
music=Music(os.path.abspath("sound\\bgm.wav"))
music.playMusic(-1)
while True:
# 事件接受处理
self.getEvent()
if self.flag1:
# 游戏是否暂停
if self.flag:
# 游戏胜利音效的控制
if self.flag3:
if len(Main.EnemyTankList)!=0:
# 设置窗口颜色
Main.win.fill(MY_COLOR)
# 在窗体上显示
Main.win.blit(self.SetFont("剩余敌机数量:%d"%len(Main.EnemyTankList)),(10,10))
Main.win.blit(self.SetFont1("R-重生 T-重新开局 Y-提升难度 U-暂停"),(230,16))
Main.win.blit(self.SetFont("游戏当前得分:%d"%self.Score),(600,10))
# 绘画英雄坦克
if Main.Tank_D.live and Main.Tank_D:
Main.Tank_D.displayTank()
# 英雄坦的移动控制
if not Main.Tank_D.stop and Main.Tank_D :
Main.Tank_D.MoveTank()
# 墙体碰撞检测
Main.Tank_D.HitTankWall()
# 英雄坦与敌方相撞
Main.Tank_D.HitETank()
# 创建敌方坦克
self.ShowEnemyTank()
# 创建英雄坦子弹
self.ShowBullet()
# 创建敌方坦子弹
self.EShowBullet()
# 创建爆炸效果
self.ShowExplode()
# 创建墙壁
self.ShowWall()
# 睡眠一下
time.sleep(0.02)
# 持续刷新(页面一直显示)
_pydis.update()
else:
Main.win.blit(self.SetFont("剩余敌机数量:%d"%0),(10,10))
Main.win.blit(self.SetFont1("R-重生 T-重新开局 Y-提升难度 U-暂停"),(230,16))
Main.win.blit(self.SetFont("游戏当前得分:%d"%self.Score),(600,10))
# 图片尺寸
self.ima=pygame.transform.scale(pygame.image.load(os.path.abspath("images\胜利1.png")),(400,100))
# 图片加载位置
Main.win.blit(self.ima,(200,200,500,500))
music=Music(os.path.abspath("sound\\002.mp3"))
music.playMusic(0)
self.flag3=False
_pydis.update()
else:
_pydis.update()
else:
# 图片尺寸
self.ima=pygame.transform.scale(pygame.image.load(os.path.abspath("images\开始封面.png")),(800,500))
# 图片加载位置
Main.win.blit(self.ima,(0,0,800,500))
_pydis.update()
# 创建敌方坦克的方法
def CreatEnemyTank(self):
for i in range(Main.EnemyTank_count):
left=random.randint(1,7)
top=1
speed=random.randint(1,3)
# 随机坦克参数
ETank=EnemyTank(left*100,top*100,speed)
# 将坦克加入列表
Main.EnemyTankList.append(ETank)
# 将敌方坦克放入窗体
def ShowEnemyTank(self):
for e in Main.EnemyTankList:
# 坦克存在(活着)
if e.live:
# 继承Tank父类的方法
e.displayTank()
# 自定义敌坦随机移动方法
e.RandomMove()
# 墙体碰撞检测
e.HitTankWall()
# 敌方坦主动与英雄坦相碰撞
e.HitYingTank()
# 加入射击子弹
ET=e.ShoutTank()
# ET非空时
if ET:
Main.EnemyBulletList.append(ET)
# 坦克死亡了,从列表移除
else:
Main.EnemyTankList.remove(e)
# 创建英雄坦
def CreatTank(self):
Main.Tank_D=Mytank(330,420)
# 创建障碍物的方法
def CreatWall(self):
# 砖墙
Main.WallList.append(Wall(0,190,0))
Main.WallList.append(Wall(50,190,0))
Main.WallList.append(Wall(50,240,0))
Main.WallList.append(Wall(0,290,0))
Main.WallList.append(Wall(50,290,0))
Main.WallList.append(Wall(300,200,0))
Main.WallList.append(Wall(350,200,0))
Main.WallList.append(Wall(400,200,0))
Main.WallList.append(Wall(700,350,0))
Main.WallList.append(Wall(700,250,0))
Main.WallList.append(Wall(750,200,0))
Main.WallList.append(Wall(750,250,0))
Main.WallList.append(Wall(750,300,0))
Main.WallList.append(Wall(650,200,0))
Main.WallList.append(Wall(600,200,0))
Main.WallList.append(Wall(600,150,0))
Main.WallList.append(Wall(600,350,0))
Main.WallList.append(Wall(600,400,0))
Main.WallList.append(Wall(550,400,0))
# 铁墙
Main.TieWallList.append(Wall(0,240,1))
Main.TieWallList.append(Wall(300,240,1))
Main.TieWallList.append(Wall(350,240,1))
Main.TieWallList.append(Wall(400,240,1))
Main.TieWallList.append(Wall(200,150,1))
Main.TieWallList.append(Wall(250,150,1))
Main.TieWallList.append(Wall(300,150,1))
Main.TieWallList.append(Wall(400,150,1))
Main.TieWallList.append(Wall(700,300,1))
Main.TieWallList.append(Wall(700,200,1))
Main.TieWallList.append(Wall(750,350,1))
Main.TieWallList.append(Wall(100,350,1))
Main.TieWallList.append(Wall(100,400,1))
Main.TieWallList.append(Wall(650,150,1))
Main.TieWallList.append(Wall(150,400,1))
# 草丛
Main.CaoWallList.append(Wall(0,50,2))
Main.CaoWallList.append(Wall(330,100,2))
Main.CaoWallList.append(Wall(210,350,2))
Main.CaoWallList.append(Wall(500,350,2))
Main.CaoWallList.append(Wall(500,200,2))
Main.CaoWallList.append(Wall(580,250,2))
# 将墙壁放入窗体
def ShowWall(self):
for wall in Main.WallList:
if wall.live:
wall.displayWall()
else:
Main.WallList.remove(wall)
for wall in Main.TieWallList:
wall.displayWall()
for wall in Main.CaoWallList:
wall.displayWall()
# 将英雄坦子弹放入窗体
def ShowBullet(self):
for bullet in Main.BulletList:
if bullet.live:
bullet.displayBullet()
bullet.MoveBullet()
# 调用子弹的碰撞检测
bullet.Hit()
# 调用子弹与墙体的碰撞检测
bullet.HitWalls()
else:
Main.BulletList.remove(bullet)
# 将敌方坦子弹放入窗体
def EShowBullet(self):
for Ebullet in Main.EnemyBulletList:
if Ebullet.live:
Ebullet.displayBullet()
Ebullet.MoveBullet()
# 调用子弹与墙体的碰撞检测
Ebullet.HitWalls()
# 英雄坦克对象不为空,并且活着
if Main.Tank_D and Main.Tank_D.live:
Ebullet.HitMyTank()
else:
Main.EnemyBulletList.remove(Ebullet)
# 将爆炸效果放入窗体
def ShowExplode(self):
for explode in Main.ExplorerList:
if explode.live:
explode.displayExplode()
# 爆炸音效
music=Music(os.path.abspath("sound\\baozha.mp3"))
music.playMusic(0)
else:
Main.ExplorerList.remove(explode)
for explode in Main.WallExplorerList:
if explode.live:
explode.displayExplode()
else:
Main.WallExplorerList.remove(explode)
# 结束
def EndGame(self):
print("游戏结束!!!")
exit()
# 功能按键字体设置
def SetFont1(self,text):
# 初始化字体
pygame.font.init()
# 设置字体和大小
font=pygame.font.SysFont('kaiti',18)
# text为要显示的内容,true是抗锯齿,颜色
textSurface=font.render(text,True,Font_color2)
# 返回画布,surface对象
return textSurface
# 设置字体
def SetFont(self,text):
# 初始化字体
pygame.font.init()
# 设置字体和大小
font=pygame.font.SysFont('kaiti',22)
# text为要显示的内容,true是抗锯齿,颜色
textSurface=font.render(text,True,Font_color)
# 返回画布,surface对象
return textSurface
# 清空列表(重开和提升难度用)
def ClearList(self):
# 清空列表数据和得分
# 英雄坦子弹,敌方坦子弹,敌方坦克,爆炸效果列表
Main.BulletList.clear()
Main.EnemyBulletList.clear()
Main.EnemyTankList.clear()
Main.ExplorerList.clear()
Main.Score=0
Main.EnemyTank_count=5
# 重开音乐
music=Music(os.path.abspath("sound\\update.wav"))
music.playMusic(0)
# 获取事件
def getEvent(self):
# 返回的是列表对象
Evlist=pygame.event.get()
for event in Evlist:
# 点击窗口的x号,结束游戏
if event.type==pygame.QUIT:
self.EndGame()
# 判断按键按下 上下左右(调头+移动)空格(发射子弹)
if event.type==pygame.KEYDOWN:
# 按B键开始游戏
if event.key==pygame.K_b:
# 开始音乐
music=Music(os.path.abspath("sound\\update.wav"))
music.playMusic(0)
self.flag1=True
if self.flag1:
''' R-重生 T-重新开局 Y-提升难度 U-暂停'''
if event.key==pygame.K_t:
self.ClearList()
self.flag2=False
self.flag3=True
self.StartGame()
# 游戏已经胜利
if self.flag3:
# 英雄坦克重生R键
if event.key==pygame.K_r:
# 开场背景音乐
music=Music(os.path.abspath("sound\\protect.wav"))
music.playMusic(0)
# 坦克已经死亡了
if not Main.Tank_D.live:
del Main.Tank_D
self.CreatTank()
if event.key==pygame.K_y:
# 清空列表
self.ClearList()
# 坦克数量增加为10
Main.EnemyTank_count=20
self.flag2=False
self.flag3=True
self.StartGame()
if event.key==pygame.K_u:
self.count+=1
if self.count%2==1:
# 图片尺寸
self.im=pygame.transform.scale(pygame.image.load(os.path.abspath("images\暂停102.png")),(600,40))
# 图片加载位置
Main.win.blit(self.im,(100,200,800,500))
# 开场背景音乐
music=Music(os.path.abspath("sound\\bgm.wav"))
music.playMusic(-1)
self.flag=False
else:
# 开场背景音乐
music=Music(os.path.abspath("sound\\update.wav"))
music.playMusic(0)
self.flag=True
# 游戏是否暂停
if self.flag and self.flag3:
# 英雄坦存在并活着
if Main.Tank_D and Main.Tank_D.live:
# 产生key,按键
if event.key==pygame.K_LEFT or event.key==pygame.K_a:
print("左移")
Main.Tank_D.direction='L'
Main.Tank_D.stop=False
elif event.key==pygame.K_RIGHT or event.key==pygame.K_d:
print("右移")
Main.Tank_D.direction='R'
Main.Tank_D.stop=False
elif event.key==pygame.K_UP or event.key==pygame.K_w:
print("上移")
Main.Tank_D.direction='U'
Main.Tank_D.stop=False
elif event.key==pygame.K_DOWN or event.key==pygame.K_s:
print("下移")
Main.Tank_D.direction='D'
Main.Tank_D.stop=False
elif event.key==pygame.K_SPACE:
print("发射子弹")
# 发射子弹音效
music=Music(os.path.abspath("sound\\ball.wav"))
music.playMusic(0)
# 控制子弹数量
if len(Main.BulletList)<3:
# 创建子弹对象
m=Bullet(Main.Tank_D)
# 子弹对象加入列表
Main.BulletList.append(m)
# 按键松开时
if event.type==pygame.KEYUP:
if event.key==pygame.K_LEFT or event.key==pygame.K_RIGHT or event.key==pygame.K_UP or event.key==pygame.K_DOWN:
if Main.Tank_D and Main.Tank_D.live:
Main.Tank_D.stop=True
elif event.key==pygame.K_w or event.key==pygame.K_a or event.key==pygame.K_s or event.key==pygame.K_d:
if Main.Tank_D and Main.Tank_D.live:
Main.Tank_D.stop=True
# 继承精灵类,用自带的碰撞检测方法
class BaseItem(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Tank(BaseItem):
def __init__(self,left,top):
# 以字典形式存储
self.images={
'U':pygame.image.load(os.path.abspath("images\DU1.jpg")),
'D':pygame.image.load(os.path.abspath("images\DD1.jpg")),
'L':pygame.image.load(os.path.abspath("images\DL1.jpg")),
'R':pygame.image.load(os.path.abspath("images\DR1.jpg"))
}
# 默认初始图片方向
self.direction='U'
self.image=self.images[self.direction]
# 设置图片位置
self.rect=self.image.get_rect()
self.rect.left=left
self.rect.top=top
self.rect.height=38
self.rect.width=38
# 坦克移动速度
self.speed=5
# 坦克是否可以移动
self.stop=True
# 坦克是否活着
self.live=True
# 记录原来位置坐标
self.oldleft=0
self.oldtop=0
# 移动
def MoveTank(self):
self.oldleft=self.rect.left
self.oldtop=self.rect.top
if self.direction=='L':
self.rect.left-=self.speed
if self.rect.left<=0:
self.rect.left=0
elif self.direction=='R':
self.rect.left+=self.speed
if self.rect.left>=760:
self.rect.left=760
elif self.direction=='U':
self.rect.top-=self.speed
if self.rect.top<=20:
self.rect.top=20
elif self.direction=='D':
self.rect.top+=self.speed
if self.rect.top>=460:
self.rect.top=460
# 射击
def ShoutTank(self):
return Bullet(self)
# 归位函数,哈哈
def Stay(self):
self.rect.left=self.oldleft
self.rect.top=self.oldtop
# 检测墙体是否与坦克碰撞
def HitTankWall(self):
# 遍历墙体列表
for wall in Main.WallList:
if pygame.sprite.collide_rect(self,wall):
self.Stay()
for wall in Main.TieWallList:
if pygame.sprite.collide_rect(self,wall):
self.Stay()
# 显示 surface对象显示在窗体上
def displayTank(self):
# 重新绘制图片方向
self.image=self.images[self.direction]
# 图片大小
self.image=pygame.transform.scale(self.image,(40,40))
# 在窗体上加载图片
Main.win.blit(self.image,self.rect)
class Mytank(Tank):
def __init__(self,left,top) -> None:
super(Mytank,self).__init__(left,top)
# 英雄坦克主动碰撞敌方坦克
def HitETank(self):
for ent in Main.EnemyTankList:
if pygame.sprite.collide_rect(ent,self):
self.Stay()
class EnemyTank(Tank):
def __init__(self,left,top,speed):
# 调用父类构造方法
super(EnemyTank,self).__init__(left,top)
# 以字典形式存储
self.images={
'U':pygame.image.load(os.path.abspath("images\PU1.jpg")),
'D':pygame.image.load(os.path.abspath("images\PD1.jpg")),
'L':pygame.image.load(os.path.abspath("images\PL1.jpg")),
'R':pygame.image.load(os.path.abspath("images\PR1.jpg"))
}
# 敌方坦克随机产生方向
self.direction=self.RandomEnemy()
self.image=self.images[self.direction]
# 设置图片位置
self.rect=self.image.get_rect()
self.rect.left=left
self.rect.top=top
self.rect.height=38
self.rect.width=38
# 坦克移动速度
self.speed=speed
# 坦克移动变向步数
self.step=40
# 随机移动
def RandomMove(self):
if self.step<=0:
self.direction=self.RandomEnemy()
self.step=40
else:
self.MoveTank()
self.step-=1
# 创建随机坦克位置
def RandomEnemy(self):
num=random.randint(1,100)
if num%4==0:
return 'U'
if num%4==1:
return 'D'
if num%4==2:
return 'L'
if num%4==3:
return 'R'
# 重写Tank父类的射击方法
#敌方坦克产生子弹的频率
def ShoutTank(self):
num=random.randint(1,1000)
if num<=10:
return Bullet(self)
# 敌方坦克主动与英雄坦相碰
def HitYingTank(self):
if pygame.sprite.collide_rect(self,Main.Tank_D):
self.Stay()
class Bullet():
def __init__(self,Tank):
self.image=pygame.transform.scale(pygame.image.load(os.path.abspath("images\子弹.jpg")),(12,12))
self.direction=Tank.direction
# print("子弹的方向{0}".format(self.direction))
# print("图片大小x:{0}y:{1},宽度{2},高度{3}".format(Tank.rect.left,Tank.rect.top,Tank.rect.width,Tank.rect.height))
# 子弹的速度
self.speed=Tank.speed*2
# 子弹的生命值
self.live=True
# 子弹的位置和图片大小
self.rect=self.image.get_rect()
self.rect.width=11
self.rect.height=11
# print("子弹的大小宽{0},高{1}".format(self.rect.width,self.rect.height))
# 不同方向子弹的移动位置
if self.direction=='U':
self.rect.left=Tank.rect.left+20-self.rect.width/2
self.rect.top=Tank.rect.top-self.rect.height
elif self.direction=='D':
self.rect.left=Tank.rect.left+20-self.rect.width/2
self.rect.top=Tank.rect.top+self.rect.height+30
elif self.direction=='L':
self.rect.left=Tank.rect.left-self.rect.width
self.rect.top=Tank.rect.top+20-self.rect.width/2
elif self.direction=='R':
self.rect.left=Tank.rect.left+40
self.rect.top=Tank.rect.top+20-self.rect.width/2
# 移动
def MoveBullet(self):
if self.direction=='L':
self.rect.left-=self.speed
if self.rect.left<=0:
self.rect.left=0
self.live=False
elif self.direction=='R':
self.rect.left+=self.speed
if self.rect.left>=790:
self.rect.left=790
self.live=False
elif self.direction=='U':
self.rect.top-=self.speed
if self.rect.top<=3:
self.rect.top=3
self.live=False
elif self.direction=='D':
self.rect.top+=self.speed
if self.rect.top>=490:
self.rect.top=490
self.live=False
# 显示
def displayBullet(self):
# 重新绘制图片方向
# self.image=self.images[self.direction]
# 在窗体上加载图片
Main.win.blit(self.image,self.rect)
# 碰撞检测
def Hit(self):
for enT in Main.EnemyTankList:
# 判断敌方坦克与我方子弹是否碰撞
# pygame.sprite.collide_rect该方法判断矩形碰撞,返回布尔值
if pygame.sprite.collide_rect(enT,self):
# 击中产生爆炸
exp=Explode(enT)
# 将产生的爆炸效果加入列表
Main.ExplorerList.append(exp)
self.live=False
enT.live=False
# 击毁坦克得20分
Main.Score+=20
# 敌方坦克子弹击中我方
def HitMyTank(self):
# 显示敌方子弹时已经进行过遍历,所以此处不需要遍历子弹
# 敌方子弹与英雄坦碰撞
if pygame.sprite.collide_rect(self,Main.Tank_D):
# 产生爆照,加入列表
explode=Explode(Main.Tank_D)
Main.ExplorerList.append(explode)
# 修改子弹和英雄坦克的状态
self.live=False
Main.Tank_D.live=False
# 判断子弹与墙体的碰撞
def HitWalls(self):
# 遍历墙体列表
for wall in Main.WallList:
if pygame.sprite.collide_rect(self,wall):
# 碰撞了,修改子弹的属性
self.live=False
wall.blood-=1
if wall.blood==0:
# # 产生爆照,加入列表
explode=Explode(wall)
Main.WallExplorerList.append(explode)
# # 墙体击毁音效
music=Music(os.path.abspath("sound\\bomb.wav"))
music.playMusic(0)
wall.live=False
for wall in Main.TieWallList:
if pygame.sprite.collide_rect(self,wall):
# 碰撞了,修改子弹的属性
self.live=False
class Explode():
def __init__(self,Tank):
self.rect=Tank.rect
# 是否显示爆炸效果
self.live=True
# 加载第几张图片的索引值
self.step=0
# 爆炸图片集
self.images={
0: pygame.image.load(os.path.abspath("images\dd2.jpg")),
1: pygame.image.load(os.path.abspath("images\\dd3.jpg")),
2: pygame.image.load(os.path.abspath("images\\dd4.jpg")),
3: pygame.image.load(os.path.abspath("images\\dd5.jpg")),
4: pygame.image.load(os.path.abspath("images\\dd6.jpg")),
5: pygame.image.load(os.path.abspath("images\\dd7.jpg")),
6: pygame.image.load(os.path.abspath("images\\dd8.jpg")),
}
self.image=self.images[self.step]
# 显示
def displayExplode(self):
if self.step<len(self.images):
self.image=pygame.transform.scale(self.images[self.step],(65,65))
Main.win.blit(self.image,self.rect)
self.step+=1
else:
# 图片展示一遍后,就停止了
self.live=False
# 索引值清0
self.step=0
class Wall():
def __init__(self,left,top,num) -> None:
# # 墙体1可击毁
# # 墙体2不可击毁
self.images={
0:pygame.image.load(os.path.abspath("images\墙体1.png")),
1:pygame.image.load(os.path.abspath("images\墙体2.png")),
2:pygame.image.load(os.path.abspath("images\草丛.png"))
}
self.step=num
self.image=self.images[self.step]
self.rect=self.image.get_rect()
# 是草丛时
if self.step==2:
self.image=pygame.transform.scale(self.image,(80,50))
self.rect.width=100
self.rect.height=100
# 是墙体时
else:
self.image=pygame.transform.scale(self.image,(50,50))
self.rect.width=50
self.rect.height=50
self.rect.left=left
self.rect.top=top
# 砖墙的属性(可被击毁)铁强不可被击毁 草丛可以隐藏
self.live=True
self.blood=3
#显示
def displayWall(self):
Main.win.blit(self.image,self.rect)
class Music():
def __init__(self,MusicName) -> None:
self.MusicName=MusicName
# 对混响器进行初始化
pygame.mixer.init()
# 加载游戏音效地址
pygame.mixer.music.load(self.MusicName)
# 播放
def playMusic(self,num):
pygame.mixer.music.play(loops=num)
# 调用开始方法
Main().StartGame()
'''
仍需优化的地方:
游戏代码的执行逻辑优化,按键潜在的冲突问题
敌机之间的碰撞检测
'''
链接: https://pan.baidu.com/s/1nWZEjMN6GXO44pWeXikipg?pwd=1234
提取码: 1234
(摸索了好久,这个上边好像不能传这类资源,就上传到网盘了,永久有效,感觉可以的给个赞,鼓励一下,哈哈~~)
自学的python,刚开始学,所以对代码的编写并不会分什么架构,采用什么模式,全都堆积在一个py源文件里了,所以阅读起来,感觉可能不是太爽,还请见谅,照顾照顾新手。