main.py
'''
游戏框架:
1.导入python程序运行所需的环境模块sys,pygame模块,以及pygame.locals模块提供常用的常量和函数。
2.定义窗口大小,并创建窗口,设置游戏标题,以及加载背景。
3.定义主函数main(),设置程序退出机制,绘制背景图像,flip()方法刷新所有待显示的图像(更新整个窗口),设置程序运行的帧率。
'''
# 首先导入三个pygame的基本模块,以及其他附加模块
import sys # sys模块提供了一系列python程序运行环境的变量和函数(方法),比如退出程序的函数:sys.exit()
import pygame # pygame模块提供了游戏设计中用到的加载图片、声音等函数(方法)
from pygame.locals import * #pygame.locals模块包含了一些程序常用的常量,使用from modulename import *的方式导入模块,使得后期使用模块中的函数或变量时更加方便,直接使用变量的名字就可以,不用modulename(模块名).variable(变量)这样复杂的格式。比如QUIT常量直接使用,而不是pygame.locals.QUIT。
import myplane #导入我方飞机模块
import enemy #导入敌方飞机模块
import bullet #导入子弹模块
# 然后初始化pygame及其一些模块(音频,字体)。
pygame.init() #初始化pygame,只有初始化pygame了我们才能使用
pygame.mixer.init() #初始化pygame中的音频模块
pygame.font.init() #初始化pygame中的字体
# 设置游戏窗口(宽度、长度,标题名字),加载所有的声音文件(音乐、音效)并设置音量
screen_size = width, height = 480, 700 #定义表示窗口大小的变量screen_size
screen = pygame.display.set_mode(screen_size) #将元组变量screen_size传给set_mode()函数,来设定窗口的宽和高。调用该函数将返回一个”pygame.surface对象”,并起名字为screen
pygame.display.set_caption("飞机大战") #定义一个标题名字,将显示在游戏窗口的左上角。
background=pygame.image.load("images/background.png").convert() # 用pygame的image模块导入一张背景图片备用,# 利用surface对象的convert_alpha()方法或convert()方法,加载图片并转换图片的像素格式,使得程序效率更高,小飞机移动的会快一点
#加载背景音乐
pygame.mixer.music.load("sound/game_music.ogg") #加载背景音乐文件
pygame.mixer.music.set_volume(0.1) #设置音量,括号中传入的参数为从0到1的小数,0.5表示最大音量的50%
#加载大型飞机飞行声音
enemy3_fly_sound=pygame.mixer.Sound("sound/enemy3_flying.wav")
enemy3_fly_sound.set_volume(0.2)
#加载敌机坠毁的声音
small_down_sound=pygame.mixer.Sound("sound/enemy1_down.wav")
small_down_sound.set_volume(0.3)
mid_down_sound=pygame.mixer.Sound("sound/enemy2_down.wav")
mid_down_sound.set_volume(0.3)
big_down_sound=pygame.mixer.Sound("sound/enemy3_down.wav")
big_down_sound.set_volume(0.6)
#加载我方飞机撞毁的声音
me_down_sound=pygame.mixer.Sound("sound/me_down.wav")
me_down_sound.set_volume(0.2)
#定义将敌方小飞机添加到组的函数(这一步和下面两步就是写一个方法方便下面飞机添加到组里)
def add_small_enemies(group1, group2, num):#定义方法,名字(参数)
for small_enemy_num in range(num):#定义变量遍历给定范围
each_small_enemy = enemy.SmallEnemy(screen_size) #定义生成小飞机
group1.add(each_small_enemy)#将生成的小飞机添加到一个组
group2.add(each_small_enemy)#将生成的小飞机添加到另一个组
#定义将敌方中型飞机添加到组的函数
def add_mid_enemies(group1, group2, num):
for mid_enemy_num in range(num):
each_mid_enemy = enemy.MidEnemy(screen_size)
group1.add(each_mid_enemy)
group2.add(each_mid_enemy)
#定义将敌方大型飞机添加到组的函数
def add_big_enemies(group1, group2, num):
for big_enemy_num in range(num):
each_big_enemy = enemy.BigEnemy(screen_size)
group1.add(each_big_enemy)
group2.add(each_big_enemy)
# 函数主要部分开始,将主要功能包含在main主函数中!
#定义一个main()函数用来管理主程序
def main():
pygame.mixer.music.play(-1) # 一直循环播放背景音乐,我们可以在调用play()方法时,在括号内传入一个特殊值 -1,这样音乐就会永远重复下去;如果传入其他数值,可以让音乐播放一定的次数,比如 3,可以让音乐重复播放3次。
clock = pygame.time.Clock() # pygame中的时间模块,用来延迟时间(python中也有时间模块,主要用来延迟事件的发生或结束)
# 下面是生成部分,生成(从其他子模块中调用)我方飞机、敌机、子弹…
#生成我方飞机
heroPlane = myplane.myPlane(screen_size)
#创建敌方飞机组(动画精灵组)
enemies = pygame.sprite.Group()#创建一个组用来添加所有敌机
#生成小敌方飞机(创建小型敌机组,并执行之前添加到组的方法)
small_enemies = pygame.sprite.Group() #创建敌方小飞机组(动画精灵组)添加敌方小飞机
add_small_enemies(small_enemies, enemies, 15) #将生成的多个敌方小飞机添加到敌方小飞机组以及敌方飞机组
#生成中型敌方飞机
mid_enemies = pygame.sprite.Group() #创建敌方小飞机组(动画精灵组)
add_mid_enemies(mid_enemies, enemies, 4) #将生成的多个中型飞机添加到敌方中型飞机组以及敌方飞机组
#生成大型敌方飞机
big_enemies = pygame.sprite.Group() #创建敌方大型飞机组(动画精灵组)
add_big_enemies(big_enemies, enemies, 2) #将生成的多个大型飞机添加到敌方大型飞机组以及敌方飞机组
#生成普通子弹
bullet1 = [] #创建一个空列表
bullet1_index = 0 #子弹列表索引值变量,初始位为0
BULLET1_NUM = 4 #子弹数量为4时,按照循环10次发射一发,差不多占满窗口的高度
#生成4发子弹并放入bullet1列表
for i in range(BULLET1_NUM): # 循环遍历子弹数量
bullet1.append(bullet.Bullet1(heroPlane.rect.midtop)) #将子弹放入刚才创建的空列表中,((…))中为添加子弹的位置(我方飞机中上)
# 下面是定义一些索引,方便下面切换飞机形态、判断条件、…使用
switch_image = True#用于切换飞机特效(给一个变量,满足不同条件时切换不同的飞机形象达到切换飞机图片的效果)
#碰撞后,敌机坠毁及我方飞机撞毁动画图片索引标志定义(同上)
small_destroy_index = 0#小型飞机坠毁的索引
mid_destroy_index = 0#中型飞机坠毁的索引
big_destroy_index = 0#大型飞机坠毁的索引
hero_destroy_index = 0#我方飞机坠毁的索引
# 下面是游戏开始前的准备工作,加载、设置飞机生命值、得分、字体、游戏结束等需要的(图片、坐标、初始值、固定值…)
#我方飞机生命数量
life_image=pygame.image.load("images/life.png").convert_alpha()#加载生命数量图片
life_rect = life_image.get_rect()#加获取生命数量图片的坐标
life_NUM = 3#定义生命数量初始为3
#用于切换特效的延迟(就是规定一定时间范围来切换图片)
delay = 100
#统计得分
score = 0 # 开始分数设为0
score_font = pygame.font.Font("font/font.ttf", 36) #创建一个Font对象,分数字体
WhiteFont = (255, 255, 255) #字体颜色
#绘制游戏结束界面
gameover_font = pygame.font.Font("font/font.ttf", 48) #显示最终得分
again_image=pygame.image.load("images/again.png").convert_alpha() #加载重新开始按钮图像
again_rect = again_image.get_rect()
gameover_image = pygame.image.load("images/gameover.png").convert_alpha() #加载游戏结束按钮图像
gameover_rect = gameover_image.get_rect()
# 刚才游戏开始前的各种准备工作做完啦,接下来,进入游戏主循环,我们利用无限循环实现,除非玩家把窗口关闭,中断游戏,方可退出
while True:
for event in pygame.event.get(): #通过for循环遍历获取到的游戏事件。
if event.type == QUIT:#如果获取到的游戏事件是退出,则将pygame退出,将python程序环境退出,关闭游戏软件。
pygame.quit() # 退出pygame
sys.exit() # 退出环境
#当ESC按键被按下时,游戏暂停
if event.type == KEYDOWN: #事件类型为按键的按下
if event.key == K_ESCAPE :
pause_flag = not(pause_flag)
screen.blit(background,(0,0)) #设置前面加载的背景图片
# 下面是我方飞机和敌机的条件判断和操作方法
#当我方飞机还有生命数量,则正常运行,如果没有生命数量了,则游戏停止
if life_NUM > 0: #如果我方飞机生命值大于0。这是整个游戏的第一个判断!
#检测用户的键盘操作,并让我方飞机向上、向下、向左、向右移动
key_pressed = pygame.key.get_pressed()
if key_pressed[ K_w ] or key_pressed[ K_UP ]: #按下w键或下箭头
heroPlane.moveUp() # 飞机向上移动
if key_pressed[ K_s ] or key_pressed[ K_DOWN ]: #按下s键或上箭头
heroPlane.moveDown() # 飞机往下移动
if key_pressed[ K_a ] or key_pressed[ K_LEFT ]: #按下a键或左箭头
heroPlane.moveLeft() # 飞机往左移动
if key_pressed[ K_d ] or key_pressed[ K_RIGHT ]: #按下d键或右箭头
heroPlane.moveRight() # 飞机往右移动
#绘制小型敌机,添加敌机坠毁动画
for each in small_enemies: #生成变量each遍历刚才生成的小敌机组
if each.active == True: #each.active是飞机的存活标志,True代表存活
each.move() #调用enemy.SmallEnemy模块中的小型敌机移动方法
screen.blit(each.image, each.rect) #将小敌机绘制到屏幕上
else: #如果小型敌机没有存活
#动画图片的切换稍作延时,主循环三次切换一幅图
if not True: #判断语句,这一行多余,可以省略
#播放坠毁声音
if small_destroy_index == 0: #小敌机坠毁的索引,前面设置过
small_down_sound.play() #播放声音
#切换坠毁动画图像
screen.blit(each.destroy_images[small_destroy_index], each.rect) #绘制动画图像
small_destroy_index=(small_destroy_index + 1) % 4 #动画图像切换索引递变,因为小敌机坠毁图片有四张,所以要判断四次,然后再生成新的敌机
#重新生成敌机
if small_destroy_index == 0:
score += 100 #击中一架小型敌机得分加100
each.reset() # 调用方法重新生成敌机
#绘制中型敌机(和小敌机方法一样,不再重复注释了)
for each in mid_enemies:
if each.active == True:
each.move()
screen.blit(each.image, each.rect)
else:
#动画图片的切换稍作延时,主循环三次切换一幅图
if not(delay % 3):
if mid_destroy_index == 0:
mid_down_sound.play()
screen.blit(each.destroy_images[mid_destroy_index], each.rect) #绘制动画图像
mid_destroy_index=(mid_des
troy_index + 1) % 4 #动画图像切换索引递变
if mid_destroy_index == 0:
score += 300 #击中一架中型敌机得分加300
each.reset()
#绘制大型飞机(详见绘制小型敌机)
for each in big_enemies:
if each.active == True:
each.move()
if switch_image:
screen.blit(each.image, each.rect)
else:
screen.blit(each.image2,each.rect)
#在大型敌机出现在窗口之前,开始有飞行声音
if each.rect.bottom == -50:
enemy3_fly_sound.play()
else:
#动画图片的切换稍作延时,主循环三次切换一幅图
if not(delay % 3):
if big_destroy_index == 0:
big_down_sound.play()
screen.blit(each.destroy_images[b
ig_destroy_index], each.rect)
#绘制动画图像
big_destroy_index=(big_destroy_i
ndex + 1) % 6 #大型敌机的动画是6张图
if big_destroy_index == 0:
enemy3_fly_sound.stop() #当坠毁时,飞行的声音停止
score += 500 #击中一架大型敌机得分加500
each.reset()
# 下面该绘制我方飞机了,我方飞机是碰到敌机会坠毁(播放声音然后切换图片)
#绘制我方飞机
if heroPlane.active == True: # 如果我方飞机存活
if switch_image: #每循环5次切换一次特效图像
screen.blit(heroPlane.image,heroPLan.rect)
else:
screen.blit(heroPlane.image2,heroPlane.rect)
else:
#动画图片的切换稍作延时,主循环三次切换一幅图(这一步小飞机有)
if not True:
if hero_destroy_index == 0:
me_down_sound.play()
screen.blit(each.destroy_images[hero_destroy_index], each.rect) #绘制动画图像
hero_destroy_index=(hero_destroy_index + 1) % 4 #动画图像切换索引递变
if hero_destroy_index == 0:
life_NUM -= 1 #撞毁后,我方飞机生命减1
heroPlane.reset()
#每循环5次切换一次特效图像
if not(delay % 5):
switch_image = not switch_image # switch变量前面设置过
delay -= 1
if delay == 0:
delay = 100
#显示我方飞机生命数量
if life_NUM > 0:
for i in range(life_NUM): #遍历生命值
screen.blit(life_image,(width - 10 - (i+1)*life_rect.width,\height - 10 - life_rect.height)) #将生命值绘制在屏幕中
#发射子弹,每循环10次,发射一枚子弹
if not(delay % 10): #非0即为真
bullet1[bullet1_index].reset(heroPlane.rect.midtop) #重新发射子弹
bullet1_index = (bullet1_index + 1) % BULLET1_NUM#将原本子弹索引值+1除以子弹数量取余
#检测子弹击中敌机
for each in bullet1: #生成each变量遍历子弹
#如果子弹状态标记为True,则子弹移动
if each.active == True:
each.move() #子弹移动
screen.blit(each.image,each.rect) #绘制子弹
enemies_hit=pygame.sprite.sprite
collide(each,enemies,False,pygame.sprite.collide_mask) #检测子弹与敌机碰撞(动画精灵)
#如果有敌机被击中,则子弹状态标记改为False,被击中的敌机的状态标记也改为False
if enemies_hit:
for e in enemies_hit:
#如果被击中的敌机是中型或大型敌机,则每击中一次血量减1,当血量变为0时,敌机状态标记改为False
if e in mid_enemies or e in big_enemies:
e.energy -= 1
if e.energy == 0:
e.active = False
#如果是小型敌机,一发子弹搞定
else:
e.active = False
#如果子弹状态标记为False,则重新生成子弹(原来子弹消失)
else:
each.reset(heroPlane.rect.midtop)
#添加碰撞检测,检测我方飞机与所有敌机发生碰撞
#将发生碰撞的敌机(动画精灵)保存到enemies_collided列表, return得到的是所有在group里有参加碰撞的东西的列表,在这里,及为所有与player碰撞的alien的列表 这是官方的解释
enemies_collided=pygame.sprite.spritecollide(heroPlane,enemies,False,pygame.sprite.collide_mask)
#将发生碰撞的敌机复位(消失并重新绘制)
if enemies_collided: #如果enemies_collided列表有值
heroPlane.active = False #将我方飞机存活状态改为False
for each in enemies_collided:
each.active = False #碰撞后,将敌机状态设置为False
#显示得分
score_surface =score_font.render("Score : %s" % str(score), True, WhiteFont)
screen.blit(score_surface, (10,5)) #在左上角(10,5)的位置显示
#游戏结束
elif life_NUM == 0: #我方飞机生命值为0时,停止所有动作,跳转结束界面
#背景音乐停止
pygame.mixer.music.stop()
#停止全部音效
pygame.mixer.stop()
#显示最终得分
#这四行代码是创建字体”Your Score”,获取坐标,设置起始位置,并添加到屏幕中
gameover_TXT1 = gameover_font.render("Your Score", True, WhiteFont)
gameoverTXT1_rect = gameover_TXT1.get_rect()
gameoverTXT1_rect.left,gameoverTXT1_rect.top=(width-gameoverTXT1_rect.width)//2, height//3
screen.blit(gameover_TXT1, gameoverTXT1_rect)
#这四行代码是创建字体(分数),获取坐标,设置起始位置,并添加到屏幕中
gameover_TXT2 = gameover_font.render(str(score), True, WhiteFont)
gameoverTXT2_rect = gameover_TXT2.get_rect()
gameoverTXT2_rect.left, gameoverTXT2_rect.top = (width - gameoverTXT2_rect.width)//2, gameoverTXT1_rect.bottom + 10
screen.blit(gameover_TXT2, gameoverTXT2_rect)
#绘制重新开始和游戏结束的按钮
again_rect.left,again_rect.top=(width-again_rect.width)//2,gameoverTXT2_rect.bottom + 30
screen.blit(again_image, again_rect)
gameover_rect.left, gameover_rect.top = (width - gameover_rect.width)//2, again_rect.bottom + 30
screen.blit(gameover_image, gameover_rect)
#获取鼠标操作
mouse_down = pygame.mouse.get_pressed()
#如果玩家按下鼠标左键
if mouse_down[0]:
pos = pygame.mouse.get_pos() #获取鼠标光标的位置(x,y)
if again_rect.left < pos[0]
myplan.py
'''
定义我方飞机的对象,并在对象中定义飞机图像的矩形、位置、速度等特性值,以及定义我方飞机移动的方法,重新生成的方法
'''
# 导入pygame模块
import pygame
# 创建动画精灵的子类,命名为myPlane
class myPlane(pygame.sprite.Sprite):
def __init__(self,screen_size):
pygame.sprite.Sprite.__init__(self) #动画精灵初始化
self.image = pygame.image.load("images/me1.png").convert_alpha() #加载我方飞机的图像
self.image2 = pygame.image.load("images/me2.png").convert_alpha() #加载喷气特效图像
self.destroy_images = [] #创建一个空列表用来放置我方飞机坠毁图片
# 这一步就是加载四张我方飞机坠毁图到刚才创建的空列表里
self.destroy_images.extend([\
pygame.image.load("images/me_destroy_1.png").convert_alpha(),\
pygame.image.load("images/me_destroy_2.png").convert_alpha(),\
pygame.image.load("images/me_destroy_3.png").convert_alpha(),\
pygame.image.load("images/me_destroy_4.png").convert_alpha()])
self.rect = self.image.get_rect() #获取我方飞机的rect对象
self.width,self.height = screen_size[0], screen_size[1] #定义窗口大小的内部参数
#设置我方飞机最初的位置
self.rect.left, self.rect.bottom = (self.width- self.rect.left)//2, self.height - 60
self.speed = 10 # 设置我方飞机的速度
self.active = True # 设置我方飞机初始为存活状态
self.mask = pygame.mask.from_surface(self.image) #将图像非透明部分保存为mask,实现完美碰撞(参考碰撞检测ppt)
#定义我方飞机移动的方法
def moveUp(self): # 定义向上移动的方法
if self.rect.top > 0: # 如果上边界>0
self.rect.top -= self.speed # 将飞机的顶部坐标大小减去速度大小
else: # 如果上边界<=0
self.rect.top = 0 # 将飞机的顶部坐标设为0
def moveDown(self): # 定义向下移动的方法
if self.rect.bottom < self.height - 60: # 如果飞机下边界<屏幕长度减去飞机自身的长度
self.rect.bottom += self.speed # 将飞机的底部坐标大小减去速度坐标大小
else: # 如果飞机下边界>=屏幕长度减去飞机自身的长度
self.rect.bottom = self.height – 60 # 将飞机的底部坐标设为屏幕长度-飞机长度
def moveLeft(self): # 定义向左移动的方法
if self.rect.left > 0: # 如果飞机左边界>0
self.rect.left -= self.speed # 将飞机的左边坐标大小减去速度
else: # 如果飞机左边界<0
self.rect.left = 0 # 将飞机的左边坐标大小设为0
def moveRight(self): # 定义向右移动的方法
if self.rect.right < self.width: # 如果飞机右边界坐标<屏幕宽度
self.rect.right += self.speed # 将飞机的右边坐标大小加上速度
else: # 如果飞机右边界坐标>屏幕宽度
self.rect.right = self.width # 将飞机的右边坐标大小设为屏幕宽度
def reset(self): # 定义重新生成飞机的方法
self.active = True # 将飞机的存活状态重新设为True
self.rect.left, self.rect.bottom = (self.width- self.rect.left)//2, self.height – 60 # 定义飞机重新生成的位置
enemy.py
'''
定义敌方飞机的对象,并在对象中定义飞机图像的矩形、位置、速度等特性值,以及定义敌方飞机移动的方法、重新生成的方法
敌方飞机包含小型飞机、中型飞机、大型飞机
'''
import pygame # 导入模块
from random import * # 导入随机模块
#定义小型敌机的对象
class SmallEnemy(pygame.sprite.Sprite): # 定义小型敌机的类
def __init__(self, screen_size): # 类初始化方法,添加属性(screen_size)
pygame.sprite.Sprite.__init__(self) # 动画精灵初始化
self.image = pygame.image.load("images/enemy1.png").convert_alpha() #加载小型敌机图片
#加载小型敌机坠毁动画图片,并保存到列表中,动画即几幅图片的顺序切换
self.destroy_images = [] #创建一个空列表用来放置我方飞机坠毁图片
# 这一步就是加载四张小型敌机坠毁图到刚才创建的空列表里
self.destroy_images.extend([\
pygame.image.load("images/enemy1_down1.png").convert_alpha(),\
pygame.image.load("images/enemy1_down2.png").convert_alpha(),\
pygame.image.load("images/enemy1_down3.png").convert_alpha(),\
pygame.image.load("images/enemy1_down4.png").convert_alpha()])
self.rect = self.image.get_rect() #获取我方飞机的rect对象
self.width, self.height = screen_size[0], screen_size[1] #定义窗口大小的内部参数
self.speed = 8 #可以通过修改速度来提高游戏的难度
self.active = True #敌机的状态标记
#小型敌机出现的位置是随机的
self.rect.left,self.rect.top=randint(0,self.width-self.rect.width),\randint(-5*self.height,0)
self.mask = pygame.mask.from_surface(self.image) #将图像非透明部分保存为mask,实现完美碰撞
#定义小型敌机移动的方法
def move(self):
if self.rect.top < self.height - 60: # 如果上边界<屏幕高度-飞机大小
self.rect.top += self.speed # 飞机的上边界大小+速度大小
else:
self.reset() #当某一个小型敌机飞出窗口后,重新生成
#定义重新生成小型敌机的方法,重新生成敌机的位置是随机的
def reset(self): # 重新生成飞机的方法
self.active = True #敌机重生时,状态标记重置为True
# 设置飞机的初始位置
self.rect.left, self.rect.top = randint(0, self.width - self.rect.width),\
randint(-5*self.height,0)
#定义中型敌机(注释与小型敌机相仿,参见小型敌机)
class MidEnemy(pygame.sprite.Sprite):
ENERGY = 10 #定义中型敌机的血量,使用类中的全局变量
def __init__(self,screen_size):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images/enemy2.png").convert_alpha()
#加载中型敌机坠毁动画图片,并保存到列表中
self.destroy_images = []
self.destroy_images.extend([\
pygame.image.load("images/enemy2_down1.png").convert_alpha(),\
pygame.image.load("images/enemy2_down2.png").convert_alpha(),\
pygame.image.load("images/enemy2_down3.png").convert_alpha(),\
pygame.image.load("images/enemy2_down4.png").convert_alpha()])
self.rect = self.image.get_rect()
self.width, self.height = screen_size[0], screen_size[1]
self.speed = 1
self.active = True #定义敌机状态标记
self.energy = MidEnemy.ENERGY
self.rect.left, self.rect.top = randint(0, self.width - self.rect.width),\
randint(-10*self.height, -self.height)
self.mask = pygame.mask.from_surface(self.image) #将图像非透明部分保存为mask,实现完美碰撞
def move(self):
if self.rect.top < self.height - 60:
self.rect.top += self.speed
else:
self.reset()
def reset(self):
self.active = True #重置敌机状态标记
self.energy = MidEnemy.ENERGY # 重置中型敌机血量
self.rect.left, self.rect.top = randint(0, self.width - self.rect.width),\
randint(-10*self.height,0)
#定义大型敌机
class BigEnemy(pygame.sprite.Sprite):
ENERGY = 20 #定义大型敌机的血量,使用类中的全局变量
def __init__(self,screen_size):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images/enemy3_n1.png").convert_alpha()
self.image2 = pygame.image.load("images/enemy3_n2.png").convert_alpha()
#加载小型敌机坠毁动画图片,并保存到列表中
self.destroy_images = []
self.destroy_images.extend([\
pygame.image.load("images/enemy3_down1.png").convert_alpha(),\
pygame.image.load("images/enemy3_down2.png").convert_alpha(),\
pygame.image.load("images/enemy3_down3.png").convert_alpha(),\
pygame.image.load("images/enemy3_down4.png").convert_alpha(),\
pygame.image.load("images/enemy3_down5.png").convert_alpha(),\
pygame.image.load("images/enemy3_down6.png").convert_alpha()])
self.rect = self.image.get_rect()
self.width, self.height = screen_size[0], screen_size[1]
self.speed = 1
self.active = True #定义敌机状态标记
self.energy = BigEnemy.ENERGY
self.rect.left, self.rect.top = randint(0, self.width - self.rect.width),\
randint(-15*self.height, -5*self.height)
self.mask = pygame.mask.from_surface(self.image) #将图像非透明部分保存为mask,实现完美碰撞
def move(self):
if self.rect.top < self.height - 60:
self.rect.top += self.speed
else:
self.reset()
def reset(self):
self.active = True # 重置敌机状态标记
self.energy = BigEnemy.ENERGY # 重置大型敌机血量
self.rect.left, self.rect.top = randint(0, self.width - self.rect.width),\
randint(-15*self.height, -5*self.height)
bullet.py
'''
定义我方飞机发射子弹的对象
'''
import pygame # 导入pygame模块
class Bullet1(pygame.sprite.Sprite): # 创建动画精灵的子类,命名为Bullet
def __init__(self,position):
pygame.sprite.Sprite.__init__(self) # 动画精灵初始化
# 加载子弹图片
self.image = pygame.image.load("images/bullet1.png").convert_alpha()
# 动画精灵初始化
self.rect = self.image.get_rect() # 获取子弹坐标
self.rect.left, self.rect.top = position #position应该为我方飞机中央机头位置
self.speed = 12 # 设置子弹速度为12
self.active = True # 设置子弹存活状态为True
self.mask = pygame.sprite.from_surface(self.image) # 完美碰撞检测
def move(self): # 定义移动方法
self.rect.top -= self.speed
if self.rect.top < 0: # 如果上边界<0
self.active = False # 子弹存活状态为False
def reset(self,position): # 定义子弹重生方法
self.rect.left, self.rect.top = position #重新生成子弹时,需要根据我方飞机最新的位置来生成
self.active = True # 将重新生成的子弹状态改为True