import pygame,time,random,os
from pygame.locals import *
def getPic(path): #添加函数把路径拼接到一块儿,可以方便使用,增加可移植性
return os.path.join("D:\\python使用软件\\New_Stydy\\img",path) #把路径拼接到一块儿
class Base(): #提取飞机和子弹的共性,然后封装,子类继承他的属性,然后调用初始化的属性
def __init__(self,x,y,windows):
self.x = x
self.y = y
self.windows = windows
class BasePlane(Base): #定义飞机父类
def __init__(self,x,y,windows,normalImageList,bombImageList):
super().__init__(x,y,windows) #继承Base属性
self.normalImageList = normalImageList # 正常飞机切换的图片
self.normalIndex = 0 # 飞机图片开始切换前的初始值
self.bombImageList = bombImageList # 爆炸图片
self.bombImageIndex = 0 # 飞机爆炸的初始值
self.isBomb = False #
def draw(self): #画出飞机图片
if self.isBomb==False: #飞机未爆炸
pic=pygame.image.load(getPic(self.normalImageList[self.normalIndex])) #加载飞机图片
self.windows.blit(pic,(self.x,self.y)) #把飞机贴到windows上
self.normalIndex=(self.normalIndex+1)%len(self.normalImageList) #切换飞机图片
else:#敌方飞机被击中,击中时切换爆照效果的四张图片
if self.bombImageIndex==len(self.bombImageList):
# exit(1) #被敌方击中退出
self.isBomb=False #这样就死不了了
return
pic=pygame.image.load(getPic(self.bombImageList[self.bombImageIndex]))
self.windows.blit(pic,(self.x,self.y))
self.bombImageIndex=self.bombImageIndex+1
time.sleep(0.5)
class HeroPlane(BasePlane): #定义一个飞机类
def __init__(self,x,y,windows): #传入飞机的一些参数
super().__init__(x,y,windows,["3.png"],["hero_blowup_n1.png", "hero_blowup_n2.png", "hero_blowup_n3.png", "hero_blowup_n4.png"])
self.biuList = []
def draw(self): #画出子弹图片
super().draw()
for biu in self.biuList:
biu.draw()
self.biuList.remove(biu) if biu.y<0 else ""
def dealEvent(self,eventList): #飞机事件
for event in eventList:
if event.type==QUIT:
exit(0)
if event.type==KEYDOWN:
key_pressde = pygame.key.get_pressed()
if key_pressde[K_LEFT]:
self.x = self.x - 5 if self.x >= 5 else 0
if key_pressde[K_RIGHT]:
self.x = self.x + 5 if self.x < 375 else 375
if key_pressde[K_UP]:
self.y = self.y - 5 if self.y > 0 else 0
if key_pressde[K_DOWN]:
self.y = self.y + 5 if self.y < 650 - 124 else 650 - 124
if key_pressde[K_SPACE]:
oneBiu = HeroBullet(self.x + 39, self.y - 22, windows)
self.biuList.append(oneBiu)
#检测我方飞机是否被击中
def pzjc(self,bList): #检测敌方飞机何时被击中
hRect=Rect(self.x,self.y,100,124)
for biu in bList:
bRect=Rect(biu.x,biu.y,9,21)
if bRect.colliderect(hRect):
self.isBomb=True
class EnemyPlane(BasePlane): #定义一个敌方飞机类
def __init__(self,x,y,windows): #传入飞机的一些参数
super().__init__(x,y,windows,["enemy1.png"],["enemy1_down1.png","enemy1_down2.png","enemy1_down3.png","enemy1_down3.png"] )
self.direct = "左" #类调用函数需要传入参数才能使用,静态属性不用传参,跟在类外写函数一样,设置飞机的初始飞行方向
self.enemyBiuList=[] #设置敌机的弹夹列表
def draw(self): #画出飞机图片
super().draw()
self.move() #调用飞机移动方法
self.fire() #调用开火函数
for biu in self.enemyBiuList:
biu.draw()
self.enemyBiuList.remove(biu) if biu.y < 0 else ""
def move(self): #飞机移动的方法
k=random.randint(0,480) #设置随机数,当飞机为随机数时让飞机往相反方向飞行
if self.direct == "左":
self.x = self.x - 3
if self.x <= 0 or self.x==k:
self.direct = "右"
elif self.direct == "右":
self.x = self.x + 3
if self.x >= 480 - 69 or self.x==k:
self.direct = "左"
def pzjc(self,bList): #检测敌方飞机何时被击中
eRect=Rect(self.x,self.y,69,89) #敌方位置
for biu in bList: #遍历我方子弹位置
bRect=Rect(biu.x,biu.y,22,22) #生成我方子弹位置
if bRect.colliderect(eRect): #如果我方子弹和敌方位置相遇,那么触发爆炸事件
self.isBomb=True
#定义开火装填子弹,定义随机数,当x为随机数时生成子弹,然后把子弹装进enemyBiuList列表里
def fire(self):
x = random.randint(0, 50)
if x == 5 or x == 7:
oneBiu = EnemyBullt(self.x + 69 // 2 - 9 // 2, self.y + 89, windows)
self.enemyBiuList.append(oneBiu)
#下面为子弹类
class BaseBullt(Base): #定义子弹父类
def __init__(self,x,y,windows,bpic): #定义子弹位置坐标和传入子弹图片
super().__init__(x, y, windows)
self.pic = pygame.image.load(getPic(bpic)) #生成子弹图片
def draw(self):#这个地方本来写在EnemyBullt类和HeroBullet类下的,现在被提取出来,
# BaseBullt类不能被直接实例化,因为其中没有move()方法,而EnemyBullt和HeroBullet实例化后可以直接调用move()方法,
# 因为EnemyBullt和HeroBullet方法下有move()方法
self.windows.blit(self.pic,(self.x,self.y)) #贴上子弹的图片
self.move() #子类实例化后,如果子类中有move()函数,在子类调用draw()函数时将执行move()函数
class EnemyBullt(BaseBullt): #定义敌方子弹
def __init__(self,x,y,windows):
super().__init__(x,y,windows,"bullet2.png") #调用父类生成敌机的x,y位置,传入敌机子弹的图片
def move(self): #定义子弹的移动函数,让敌方子弹往下走
self.y+=5
class HeroBullet(BaseBullt): #定义我方子弹
def __init__(self,x,y,windows):
super().__init__(x,y,windows,"bullet_1.png") #调用父类生成我方飞机的x,y位置,传入英雄飞机子弹的图片
def move(self): #定义子弹的移动函数,让敌方子弹往上走
self.y-=5
windows=pygame.display.set_mode((480,650),0,32) #设置窗口大小色深
pygame.display.set_caption("灰机大战") #设置标题名
icon=pygame.image.load(getPic("icon72x72.png")) #引入图标
pygame.key.set_repeat(20,30) #按下20毫秒后起反应,如果30毫秒内未抬起,认为再次按下
pygame.display.set_icon(icon) #把图标加到窗口上
bg=pygame.image.load(getPic("background1.png")) #引入背景图片
heroPlane=HeroPlane(480//2-100//2,650-124,windows) #把英雄飞机实例化成类,传入飞机的初始位置
enemyPlane=EnemyPlane(480//2-100//2,0,windows) #把敌方飞机实例化成类,传入飞机的初始位置
enemyPlane1=EnemyPlane(40,0,windows) #把另一台敌方飞机实例化成类,传入飞机的初始位置
while True:
windows.blit(bg,(0,0)) #把背景图贴到窗口上,窗口的左上角位置为(0,0)
heroPlane.draw() #调用draw()方法画出飞机
enemyPlane.draw() #调用draw()方法画出敌机
enemyPlane.pzjc(heroPlane.biuList) #调用敌方碰撞检测,检测是否被我方击中
#画出另一个敌机
enemyPlane1.draw() #调用draw()方法画出敌机
enemyPlane1.pzjc(heroPlane.biuList) #调用敌方碰撞检测,检测是否被我方击中
heroPlane.pzjc(enemyPlane1.enemyBiuList) #进行碰撞检测
heroPlane.pzjc(enemyPlane.enemyBiuList) #调用我方碰撞检测,检测是否被敌方击中
heroPlane.dealEvent(pygame.event.get()) #调用事件列表,然后把飞机列表传进去
pygame.display.update() #相当于把帷幕拉开,这样才能看到背景后的东西