第094讲: Pygame:飞机大战5 | 学习记录(小甲鱼零基础入门学习Python)
我们接下来在游戏界面的左上角设置一个得分显示区域,实时显示玩家得分,我们的规则如下:
击落小中大敌机分别可以获得1000,6000,10000分。
我们现在main 函数中添加一个 score 变量统计用户的得分,并设置显示分数的字体,我们已经放在素材库的 font 文件夹中了。
(这里要注意的是,你的字体所放的文件路径中,不能出现中文!!!)
然后在大型敌机坠机要重建之前加10000分,中小型敌机同理。
然后在绘制我方飞机时把分数绘制到界面上。
#创建字体的标志font = pygame.font.Font(r'D:\Code\Python\Pygame\font\font.ttf',35)#初始化分数score = 0......font_screen = font.render('score = %s' %str(score),True,white) #绘制分数screen.blit(font_screen,(10,5)) #绘制分数
接下来,我们在界面右上角添加一个暂停符。
这里总共有4张图片,左边两张表示要暂停,右边两个表示要恢复游戏。两组各有一张深色的和浅色的,当鼠标移到图像上方时(并没有点击鼠标),图片会加深,起到一个提示的效果。
我们通过响应 MOUSEBUTTONDOWN 的事件可以知道用户是否点下鼠标,在点下鼠标那一刹那,我们去获得鼠标的位置,就可以知道玩家是否点下了暂停按钮。通过响应 MOUSEMOTION 事件,我们可以改变按钮的样式。
在main函数里加一个 pause 变量作为判断暂停的标志。
# 标志是否暂停游戏paused = Falsepause_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_nor.png" ).convert_alpha() #暂停的时候图片pause_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_pressed.png" ).convert_alpha() #暂停到继续的中间变换图resume_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_nor.png").convert_alpha() #继续的时候的图片resume_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_pressed.png" ).convert_alpha() #继续到暂停的中间变换图paused_rect = pause_nor_image.get_rect()paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10paused_image = pause_nor_image
接下来我们响应 MOUSEBUTTONDOWN 事件 和 MOUSEMOTION 事件:
另外如果按照小甲鱼的方法,在点击一次暂停按钮后必须要移动鼠标才会进行更改,这里我进行了改变,使鼠标在图标在点下的时候能立即更改
elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): #如果检测到鼠标在暂停位置按下点击按钮paused = not paused #puase标志键变为Trueif paused_rect.collidepoint(event.pos): #让暂停图标在鼠标按下时立即改变if paused:paused_image = resume_pressed_imageelse:paused_image = pause_pressed_imageelse:if paused:paused_image = resume_nor_imageelse:paused_image = pause_nor_imagescreen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮elif event.type == MOUSEMOTION: #鼠标是否移动到暂停照片上显示不同的图片if paused_rect.collidepoint(event.pos):if paused:paused_image = resume_pressed_imageelse:paused_image = pause_pressed_imageelse:if paused:paused_image = resume_nor_imageelse:paused_image = pause_nor_image
接下来我们来谈一下难度的控制:
因为敌人一成不变的慢慢的出现,对于玩家来说是无法忍受的,玩家希望的游戏体验是刺激。我们要让游戏的难度随着玩家的得分增加而增加,这里将游戏难度划分为 5 个级别,每提升一个级别,就会增加一些敌机或者说增加敌机的移动速度。
设置难度等级:
# 设置难度级别level = 1
if level == 1 and score > 50000:level = 2upgrade_sound.play()# 增加3架小型敌机、2架中型敌机和1架大型敌机add_smallenemies(smallenemies, enemies, 3)add_middleenemies(middleenemies, enemies, 2)add_bigenemies(bigenemies, enemies, 1)# 提升小型敌机的速度inc_speed(smallenemies, 1)elif level == 2 and score > 300000:level = 3upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middleenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(midenemies, 1)elif level == 3 and score > 600000:level = 4upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middleenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(midenemies, 1)elif level == 4 and score > 1000000:level = 5upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middlenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(middleenemies, 1)
但是考虑到,如果 level 到 5 的时候,敌机的密集度就会很大,玩家就很容易陷入不利的局面,这就需要给玩家提供大杀招:全屏爆炸。
这个大杀招的触发是通过空格键来触发的,初始化情况下,我们带着3颗全屏炸弹,我们可以通过每30秒一次的补给获得,但是最多你的飞机只能装载3颗。
由于触发全屏炸弹是属于偶然事件,因此我们通过响应 KEYDOWN事件,再检测 event.key 是否为 K_SPACE 就可以了。
我们首先定义全屏炸弹:
# 全屏炸弹bomb_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bomb.png").convert_alpha()bomb_rect = bomb_image.get_rect()bomb_font = pygame.font.Font(r"D:\Code\Python\Pygame\font\font.ttf", 48)bomb_num = 3
然后实现 空格触发全屏炸弹
elif event.type == KEYDOWN : if event.key == K_SPACE: #如果按下空格键,投放超级炸弹if bomb_num : #如果还有超级炸弹,那么炸弹数量-1bomb_num -= 1use_bomb_sound.play()for each in enemies:if each.rect.bottom > 0:each.active = False
在界面左下角绘制全屏炸弹数量
# 绘制全屏炸弹数量bomb_text = bomb_font.render("× %d" % bomb_num, True, white)text_rect = bomb_text.get_rect()screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))
今天的任务就到这里为止了,在全屏炸弹用完之后,我们可以通过每30秒一次的补给来获得,这个在下节课讲解。
接下来是今天实现的全部代码:
from pygame.locals import *
from random import *
import traceback
import tkinter as tk
import pygame
import math
import sys"""\/\/\/\/\/\/\/\/------我的飞机类------\/\/\/\/\/\/\/\/"""
class MyPlane (pygame.sprite.Sprite): #定义我的飞机类,继承动画精灵类(因为之后要进行碰撞检测)def __init__(self,bg_size,me1_image,me2_image) :pygame.sprite.Sprite.__init__(self)self.me1_image = me1_imageself.me2_image = me2_imageself.image1 = pygame.image.load(me1_image).convert_alpha() #第一张飞机图片self.image2 = pygame.image.load(me2_image).convert_alpha() #第二张飞机图片 两张图片是为了做出飞机喷气的效果#添加坠机图片self.destroy_images = []self.me_destory_1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_1.png").convert_alpha() #自身飞机炸毁第1张图片self.me_destory_2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_2.png").convert_alpha() #自身飞机炸毁第2张图片self.me_destory_3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_3.png").convert_alpha() #自身飞机炸毁第3张图片self.me_destory_4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me_destroy_4.png" ).convert_alpha() #自身飞机炸毁第4张图片self.destroy_images.extend([self.me_destory_1_image,self.me_destory_2_image,self.me_destory_3_image,self.me_destory_4_image])self.rect = self.image1.get_rect() #获得飞机图片的尺寸self.width , self.height = bg_size[0] , bg_size[1] #设置飞机允许活动地点self.rect.left , self.rect.top = [ (self.width - self.rect.width) // 2 , \(self.height - self.rect.height - 60) ] #设置我方飞机出现的位置self.mask = pygame.mask.from_surface(self.image1) #给类添加上mask属性,之后可以按照完美碰撞self.speed = 10 #设置飞机出现的速度self.active = True#设置飞机是否生存的状态def moveup(self): #飞机向上飞的函数if self.rect.top > 0: #如果我方飞机没有飞出 上方边界self.rect.top -= 10 #那么我方飞机朝上飞10个像素else : #飞出 上方边界self.rect.top = 0 #锁定在0的位置,不再发生变化def movedown(self): #飞机向下飞的函数if self.rect.bottom < (self.height - 60) : #如果我方飞机没有飞出 上方边界self.rect.bottom += 10 #那么我方飞机朝下飞10个像素else : #飞出 下方边界self.rect.bottom = (self.height - 60) #锁定在底边界上方60的位置,不再发生变化def moveleft(self): #飞机向左飞的函数if self.rect.left > 0 : #如果我方飞机没有飞出 左方边界self.rect.left -= 10 #那么我方飞机朝下左10个像素else : #飞出 左方边界self.rect.left = 0 #锁定在左边界的位置,不再发生变化def moveright(self): #飞机向下飞的函数if self.rect.right < self.width : #如果我方飞机没有飞出 上方边界self.rect.right += 10 #那么我方飞机朝下飞10个像素else : #飞出 下方边界self.rect.right = self.width #锁定在底边界的位置,不再发生变化"""\/\/\/\/\/\/\/\/------敌机类------\/\/\/\/\/\/\/\/"""
"""本来这里其实可以使用类的继承,然后三种敌机分别继承这个敌机类生成新的敌机,但是在这里、没有这样做的必要,因为三个类的差别并不是很大,所以不用那么繁杂"""
class SmallEnemy(pygame.sprite.Sprite): #定义我的低敌机类,继承自动画精灵def __init__(self,bg_size,enemy1_image):pygame.sprite.Sprite.__init__(self)self.enemy1_image = enemy1_imageself.enemy1 = pygame.image.load(enemy1_image).convert_alpha() #载入低级敌机照片#添加坠机图片self.destroy_images = []self.enemy1_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down1.png").convert_alpha() #低级敌机撞到爆炸第1张图片self.enemy1_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down2.png").convert_alpha() #低级敌机撞到爆炸第2张图片self.enemy1_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down3.png").convert_alpha() #低级敌机撞到爆炸第3张图片self.enemy1_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1_down4.png").convert_alpha() #低级敌机撞到爆炸第4张图片self.destroy_images.extend([self.enemy1_down1_image,self.enemy1_down2_image,self.enemy1_down3_image,self.enemy1_down4_image])self.width ,self.height = bg_size[0] , bg_size[1] #获取生成低级敌机的活动范围self.rect = self.enemy1.get_rect() #获得低级敌机的尺寸self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-5*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机self.mask = pygame.mask.from_surface(self.enemy1) #给类添加上mask属性,之后可以按照完美碰撞self.speed = 3 #设置小敌机移动的速度self.active = True #设置飞机是否生存的状态def move(self) : #小敌机的移动函数if self.rect.top < self.height : #如果小飞机的底超出窗口的下边框self.rect.top += self.speed #小飞机向下移动他的速度else : #如果小飞机已经超出窗口的下边界框self.reset() #重置小飞机def reset(self) : #重置小飞机函数self.active = True#设置飞机是否生存的状态self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-5*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机class MiddleEnemy(pygame.sprite.Sprite): #定义我的中敌机类,继承自动画精灵energy = 8def __init__(self,bg_size,enemy2_image):pygame.sprite.Sprite.__init__(self)self.enemy2_image = enemy2_imageself.enemy2 = pygame.image.load(enemy2_image).convert_alpha() #载入中级敌机照片#添加坠机图片self.destroy_images = []self.enemy2_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down1.png").convert_alpha() #中级敌机撞到爆炸第1张图片self.enemy2_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down2.png").convert_alpha() #中级敌机撞到爆炸第2张图片self.enemy2_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down3.png").convert_alpha() #中级敌机撞到爆炸第3张图片self.enemy2_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_down4.png").convert_alpha() #中级敌机撞到爆炸第4张图片self.enemy2_hit_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2_hit.png").convert_alpha() #中级敌机被子弹打到后图片self.destroy_images.extend([self.enemy2_down1_image,self.enemy2_down2_image,self.enemy2_down3_image,self.enemy2_down4_image])self.width ,self.height = bg_size[0] , bg_size[1] #获取生成低级敌机的活动范围self.rect = self.enemy2.get_rect() #获得中级敌机的尺寸self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-10*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机self.mask = pygame.mask.from_surface(self.enemy2) #给类添加上mask属性,之后可以按照完美碰撞self.speed = 2 #设置中敌机移动的速度self.active = True #设置飞机是否生存的状态self.energy = MiddleEnemy.energy #设置敌机的生命值self.hit = False #敌机是否被撞的状态def move(self) : #中敌机的移动函数if self.rect.top < self.height : #如果中飞机的底超出窗口的下边框self.rect.top += self.speed #中飞机向下移动他的速度else : #如果中飞机已经超出窗口的下边界框self.reset() #重置中飞机def reset(self) : #重置中飞机函数self.active = True#设置飞机是否生存的状态self.hit = Falseself.energy = 8self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-10*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机class BigEnemy(pygame.sprite.Sprite): #定义我的大敌机类,继承自动画精灵energy = 20def __init__(self,bg_size,enemy3_n1_image,enemy3_n2_image):pygame.sprite.Sprite.__init__(self)self.enemy3_n1_image = enemy3_n1_imageself.enemy3_n1 = pygame.image.load(enemy3_n1_image).convert_alpha() #载入高级敌机照片self.enemy3_n2_image = enemy3_n1_imageself.enemy3_n2 = pygame.image.load(enemy3_n2_image).convert_alpha() #载入高级敌机照片#添加坠机图片self.destroy_images = []self.enemy3_down1_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down1.png").convert_alpha() #高级敌机撞到爆炸第1张图片self.enemy3_down2_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down2.png").convert_alpha() #高级敌机撞到爆炸第2张图片self.enemy3_down3_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down3.png").convert_alpha() #高级敌机撞到爆炸第3张图片self.enemy3_down4_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down4.png").convert_alpha() #高级敌机撞到爆炸第4张图片self.enemy3_down5_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down5.png").convert_alpha() #高级敌机撞到爆炸第5张图片self.enemy3_down6_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_down6.png").convert_alpha() #高级敌机撞到爆炸第6张图片self.enemy3_hit_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_hit.png").convert_alpha() #高级敌机被子弹打到后图片self.destroy_images.extend([self.enemy3_down1_image,self.enemy3_down1_image,self.enemy3_down3_image,self.enemy3_down4_image,\self.enemy3_down5_image,self.enemy3_down6_image ])self.width ,self.height = bg_size[0] , bg_size[1] #获取生成低级敌机的活动范围self.rect = self.enemy3_n1.get_rect() #获得低级敌机的尺寸self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-15*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机self.mask = pygame.mask.from_surface(self.enemy3_n1) #给类添加上mask属性,之后可以按照完美碰撞self.speed = 1 #设置大敌机移动的速度self.active = True#设置飞机是否生存的状态self.energy = BigEnemy.energy #设置敌机的生命值self.hit = False #敌机是否被撞的状态def move(self) : #大敌机的移动函数if self.rect.top < self.height : #如果大飞机的底超出窗口的下边框self.rect.top += self.speed #大飞机向下移动他的速度else : #如果大飞机已经超出窗口的下边界框self.reset() #重置大飞机def reset(self) : #重置大飞机函数self.active = True#设置飞机是否生存的状态self.hit = Falseself.energy = 20self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\randint(-15*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机"""\/\/\/\/\/\/\/\/------子弹类------\/\/\/\/\/\/\/\/"""
class Bullet1 (pygame.sprite.Sprite): #定义子弹类,继承动画精灵类(因为之后要进行碰撞检测)def __init__(self,bullet1_image,position) :pygame.sprite.Sprite.__init__(self)self.bullet1_image = bullet1_image #子弹1图的路径self.image = pygame.image.load(bullet1_image).convert_alpha() #加载子弹1图self.rect = self.image.get_rect() #获得子弹1图的尺寸self.rect.left , self.rect.top = position #把飞机的位置传给子弹self.speed = 12 #子弹运动的速度self.active = True #用来表示这颗子弹是或否失效self.mask = pygame.mask.from_surface(self.image) #给类添加上mask属性def move(self) :self.rect.top -= self.speed #子弹的运动if self.rect.top < 0: #射出屏幕外 self.active = False #将子弹设置为失效def reset(self, position):self.rect.left, self.rect.top = positionself.active = Truedef main() :pygame.init() #初始化pygame.mixer.init() #混音器初始化clock = pygame.time.Clock() #设置一个计时器transform = False #设置一个是否改变的变量delay = 100 #类似于单片机,设置一个延时变量,让飞机的改变看起来更加的顺滑switch_image = True # 用于切换图片running = True#创建字体的标志font = pygame.font.Font(r'D:\Code\Python\Pygame\font\font.ttf',35)#初始化分数score = 0#设置难度等级level = 1black = ([0,0,0]) #黑色green = ([0,255,0]) #绿色red = ([255,0,0]) #红色white = ([255,255,255]) #白色"""载入音乐文件"""#背景音乐pygame.mixer.music.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\game_music.ogg") #设置背景音乐pygame.mixer.music.set_volume(1) #设置音量#游戏音效bullet_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\bullet.wav") #子弹特效bullet_sound.set_volume(0.5)button_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\button.wav") #按键特效button_sound.set_volume(0.5)enemy1_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy1_down.wav") #低等敌机被击毁音效enemy1_down_sound.set_volume(0.5)enemy2_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy2_down.wav") #中等敌机被击毁音效enemy2_down_sound.set_volume(0.5)enemy3_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy3_down.wav") #高等敌机被击毁音效enemy3_down_sound.set_volume(0.5)enemy3_fly_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\enemy3_flying.wav") #高等敌机出现音效enemy3_fly_sound.set_volume(0.5)get_bomb_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\get_bomb.wav") #获得全屏炸弹补给音效get_bomb_sound.set_volume(0.5)get_bullet_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\get_bullet.wav") #获得双倍子弹补给音效get_bullet_sound.set_volume(0.5)myself_down_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\me_down.wav") #自身飞机被击毁(死亡)音效myself_down_sound.set_volume(0.5)supply_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\supply.wav") #补给产生音效supply_sound.set_volume(0.5)upgrade_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\upgrade.wav") #升级音效upgrade_sound.set_volume(0.5)use_bomb_sound = pygame.mixer.Sound( r"D:\Code\Python\Pygame\pygame11:飞机大战\sound\use_bomb.wav") #使用全屏炸弹音效use_bomb_sound.set_volume(0.5)"""图片文件路径"""again_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\again.png" #重新开始图片路径background_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\background.png" #背景图的路径bomb_supply_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bomb_supply.png" #全屏炸弹补给图bullet_supply_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bullet_supply.png" #补给子弹图bullet1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bullet1.png" #第一种子弹图bullet2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bullet2.png" #第二种子弹图enemy1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy1.png" #低级敌机图片enemy2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy2.png" #中级敌机图片enemy3_n1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_n1.png" #高级敌机图片1enemy3_n2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\enemy3_n2.png" #高级敌机图片2gameover_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\gameover.png" #游戏结束图片life_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\life.png" #表示生命值的图片me1_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me1.png" #自身飞机第一张图片me2_image = r"D:\Code\Python\Pygame\pygame11:飞机大战\images\me2.png" #自身飞机第二张图片#设置背景bg_size = width , height = 430 , 700 #背景大小screen = pygame.display.set_mode(bg_size) #这是背景大小background = pygame.image.load(background_image).convert_alpha() #画背景pygame.mixer.music.set_volume(1) #设置音量pygame.mixer.music.play(-1) #播放背景音乐,-1 表示无限循环播放# 标志是否暂停游戏paused = Falsepause_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_nor.png" ).convert_alpha() #暂停的时候图片pause_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\pause_pressed.png" ).convert_alpha() #暂停到继续的中间变换图resume_nor_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_nor.png").convert_alpha() #继续的时候的图片resume_pressed_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\resume_pressed.png" ).convert_alpha() #继续到暂停的中间变换图paused_rect = pause_nor_image.get_rect()paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10paused_image = pause_nor_image# 全屏炸弹bomb_image = pygame.image.load(r"D:\Code\Python\Pygame\pygame11:飞机大战\images\bomb.png").convert_alpha()bomb_rect = bomb_image.get_rect()bomb_font = pygame.font.Font(r"D:\Code\Python\Pygame\font\font.ttf", 48)bomb_num = 3#中弹图片索引e1_destroy_index = 0e2_destroy_index = 0e3_destroy_index = 0myself_destroy_index = 0#生成自己飞机myself = MyPlane(bg_size,me1_image,me2_image) #创建子弹bullet1 = [] #创建一个子弹列表bullet1_index = 0 #创建一个搜索子弹的下标bullet1_num = 4 #一次性创建子弹的数量for i in range (bullet1_num) : #循环生成子弹bullet1.append(Bullet1(bullet1_image,myself.rect.midtop)) #使用子弹类生成子弹#生成敌机组def add_smallenemies(group1, group2, num):for i in range(num):e1 = SmallEnemy(bg_size,enemy1_image)group1.add(e1)group2.add(e1)def add_middleenemies(group1, group2, num):for i in range(num):e2 = MiddleEnemy(bg_size,enemy2_image)group1.add(e2)group2.add(e2)def add_bigenemies(group1, group2, num):for i in range(num):e3 = BigEnemy(bg_size,enemy3_n1_image,enemy3_n2_image)group1.add(e3)group2.add(e3)#提升所有飞机的速度def inc_speed(group,addspeed):for each in group :each.speed += addspeed#生成敌机组enemies = pygame.sprite.Group() #生成整个飞机组smallenemies = pygame.sprite.Group() #生成小飞机组add_smallenemies(smallenemies,enemies,20) #生成小型飞机middleenemies = pygame.sprite.Group() #生成中飞机组add_middleenemies(middleenemies,enemies,10) #生成中型飞机bigenemies = pygame.sprite.Group() #生成大飞机组add_bigenemies(bigenemies,enemies,4) #生成大型飞机while running :for event in pygame.event.get() :if event.type == QUIT :sys.exit()elif event.type == MOUSEBUTTONDOWN: if event.button == 1 and paused_rect.collidepoint(event.pos): #如果检测到鼠标在暂停位置按下点击按钮paused = not paused #puase标志键变为Trueif paused_rect.collidepoint(event.pos): #让暂停图标在鼠标按下时立即改变if paused:paused_image = resume_pressed_imageelse:paused_image = pause_pressed_imageelse:if paused:paused_image = resume_nor_imageelse:paused_image = pause_nor_imagescreen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮elif event.type == MOUSEMOTION: #鼠标是否移动到暂停照片上显示不同的图片if paused_rect.collidepoint(event.pos):if paused:paused_image = resume_pressed_imageelse:paused_image = pause_pressed_imageelse:if paused:paused_image = resume_nor_imageelse:paused_image = pause_nor_imageelif event.type == KEYDOWN : if event.key == K_SPACE: #如果按下空格键,投放超级炸弹if bomb_num : #如果还有超级炸弹,那么炸弹数量-1bomb_num -= 1use_bomb_sound.play()for each in enemies:if each.rect.bottom > 0:each.active = Falsescreen.blit(background,(0,0)) #绘制背景font_screen = font.render('score = %s' %str(score),True,white) #绘制分数screen.blit(font_screen,(10,5)) #绘制分数#绘制暂停和继续按钮screen.blit(paused_image,(width - paused_rect.width,5)) #绘制暂停按钮# 绘制全屏炸弹数量bomb_text = bomb_font.render("× %d" % bomb_num, True, white)text_rect = bomb_text.get_rect()screen.blit(bomb_image, (10, height - 10 - bomb_rect.height))screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height))#如果没有暂停if not paused:pygame.mixer.music.unpause() #暂停背景音乐s# 根据用户的得分增加难度if level == 1 and score > 50000:level = 2upgrade_sound.play()# 增加3架小型敌机、2架中型敌机和1架大型敌机add_smallenemies(smallenemies, enemies, 3)add_middleenemies(middleenemies, enemies, 2)add_bigenemies(bigenemies, enemies, 1)# 提升小型敌机的速度inc_speed(smallenemies, 1)elif level == 2 and score > 300000:level = 3upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middleenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(midenemies, 1)elif level == 3 and score > 600000:level = 4upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middleenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(midenemies, 1)elif level == 4 and score > 1000000:level = 5upgrade_sound.play()# 增加5架小型敌机、3架中型敌机和2架大型敌机add_smallenemies(smallenemies, enemies, 5)add_middlenemies(middleenemies, enemies, 3)add_bigenemies(bigenemies, enemies, 2)# 提升小型敌机的速度inc_speed(smallenemies, 1)inc_speed(middleenemies, 1) # 绘制大型敌机for each in bigenemies:if each.active: #如果大型敌机为生存状态each.move()pygame.draw.line(screen, black, \(each.rect.left, each.rect.top - 5), \(each.rect.right, each.rect.top - 5), \2)# 当生命大于20%显示绿色,否则显示红色energy_remain = each.energy / BigEnemy.energyif energy_remain > 0.2:energy_color = greenelse:energy_color = redpygame.draw.line(screen, energy_color, \(each.rect.left, each.rect.top - 5), \(each.rect.left + each.rect.width * energy_remain, \each.rect.top - 5),2) if each.hit : #如果被撞screen.blit(each.enemy3_hit_image,each.rect) each.hit = False else : #如果没有被撞if switch_image: #判断是否交换图片screen.blit(each.enemy3_n1, each.rect)else:screen.blit(each.enemy3_n2, each.rect)# 即将出现在画面中,播放音效if each.rect.bottom == -50:enemy3_fly_sound.play()else: #如果大型敌机为撞毁状态if not (delay % 3) :if e3_destroy_index == 0: #当索引再次变为0时enemy3_down_sound.play() #播放声音screen.blit(each.destroy_images[e3_destroy_index], each.rect)e3_destroy_index = (e3_destroy_index + 1) % 6if e3_destroy_index == 0: #当索引再次变为0时enemy3_down_sound.stop()score += 10000 #打掉大型飞机+10000分each.reset() #重置飞机# 绘制中型敌机:for each in middleenemies:if each.active : #如果此敌机的为存活状态each.move()if each.hit : #如果被撞screen.blit(each.enemy2_hit_image,each.rect) each.hit = False else : #如果没有被撞screen.blit(each.enemy2, each.rect)pygame.draw.line(screen, black, \(each.rect.left, each.rect.top - 5), \(each.rect.right, each.rect.top - 5), \2)# 当生命大于20%显示绿色,否则显示红色energy_remain = each.energy / MiddleEnemy.energyif energy_remain > 0.2:energy_color = greenelse:energy_color = redpygame.draw.line(screen, energy_color, \(each.rect.left, each.rect.top - 5), \(each.rect.left + each.rect.width * energy_remain, \each.rect.top - 5),2) else :#敌机撞毁if not (delay % 3) :if e2_destroy_index == 0: #当索引再次变为0时enemy2_down_sound.play() #播放声音screen.blit(each.destroy_images[e2_destroy_index], each.rect)e2_destroy_index = (e2_destroy_index + 1) % 4if e2_destroy_index == 0: #当索引再次变为0时score += 6000 #打掉大型飞机+6000分each.reset() #重置飞机# 绘制小型敌机:for each in smallenemies:if each.active : #如果此敌机的为存活状态each.move()screen.blit(each.enemy1, each.rect)else :#敌机撞毁if not (delay % 3) :if e1_destroy_index == 0: #当索引再次变为0时enemy1_down_sound.play() #播放声音screen.blit(each.destroy_images[e1_destroy_index], each.rect)e1_destroy_index = (e1_destroy_index + 1) % 4if e1_destroy_index == 0: #当索引再次变为0时score += 1000 #打掉小型飞机+1000分each.reset() #重置飞机#绘制我方飞机if myself.active : #如果我方飞机active的属性为真,即未和其他飞机发生碰撞if transform : #如果改变属性为真 画第一张飞机图screen.blit(myself.image1,myself.rect) #绘制第一张飞机图 else : #如果改变属性为假 画第二张飞机图screen.blit(myself.image2,myself.rect) #绘制第二张飞机图else:#我方飞机撞毁myself_down_sound.play()if not (delay % 3) :screen.blit(myself.destroy_images[myself_destroy_index], myself.rect)myself_destroy_index = (myself_destroy_index + 1) % 4if myself_destroy_index == 0:print("Game Over!")running = False#绘制从飞机中出现的子弹if not (delay % 10) : #设置每10帧射出一个子弹bullet1[bullet1_index].reset(myself.rect.midtop) #将子弹的坐标初放到飞机的前面bullet1_index = (bullet1_index + 1) % bullet1_num #使子弹的下标始终处于0-4间不断循环#检测子弹是否击中敌机for b in bullet1: #对于列表中的的所有子弹if b.active : #如果子弹有效b.move() #子弹移动screen.blit(b.image,b.rect) #把子弹绘制在背景上enemies_hit = pygame.sprite.spritecollide(b,enemies,False,collided=pygame.sprite.collide_mask) #将所有与子弹发生碰撞的敌方飞机都加入到组中if enemies_hit : #如果有敌机与子弹相碰b.active = False #将碰撞后在子弹设置为未激活,使其消失,不再继续存在在画面中for e in enemies_hit : #对于所有相撞的敌机if (e in middleenemies) or (e in bigenemies) : #如果敌机是中型飞机或者大型飞机e.hit = True #将敌机的撞击属性设置为已碰撞e.energy -= 1 #生命值-1if e.energy == 0 : #如果生命值变为0e.active = False #将敌机的生命属性设置为死亡e.hit = False #重新降低及的撞击属性变为未撞击else : #小型敌机 e.active = False #将他们的状态设置为死亡if not (delay % 5) :transform = not transform #改变transform的属性来打到改变图片的效果switch_image = not switch_image #改变switch_image 来改变大型飞机的图片if not delay : #如果delay值变为0那么重新调回100delay = 100delay -= 1#检查双方飞机是否发生碰撞enemies_down = pygame.sprite.spritecollide(myself, enemies, False,collided=pygame.sprite.collide_mask) #将所有与我们的飞机发生碰撞的敌方飞机都加入到组中if enemies_down: #如果组中有成员,说明又发生碰撞#myself.active = False #我放飞机存活状态变成Falsefor e in enemies_down: e.active = False #对于与我相撞的飞机的也设为False#检查是否有上下左右或wsad按下,如有则对飞机进行相应的控制key_press = pygame.key.get_pressed()if key_press[K_w] or key_press[K_UP] : #如果按下上键或者↑myself.moveup() #飞船向上飞行elif key_press[K_s] or key_press[K_DOWN] : #如果按下下键或者↓myself.movedown() #飞船向下飞行elif key_press[K_a] or key_press[K_LEFT] : #如果按下左键或者←myself.moveleft() #飞船向左飞行elif key_press[K_d] or key_press[K_RIGHT] : #如果按下右键或者→myself.moveright() #飞船向右飞行else : #如果暂停了pygame.mixer.music.pause() #暂停背景音乐pygame.display.flip() #不停的刷新画面,不停的绘画clock.tick(60) #设置帧率if __name__ == "__main__":# 这样做的好处是双击打开时如果出现异常可以报告异常,而不是一闪而过!try:main()except SystemExit: #这是按下 × 的异常,直接忽略passexcept:traceback.print_exc()pygame.quit()input()
第094讲: Pygame:飞机大战5 | 学习记录(小甲鱼零基础入门学习Python)相关推荐
- 小甲鱼零基础入门学习python--课后作业(更新至第19讲,持续更新)
本章内容: 小甲鱼零基础入门学习python--课后作业 1.基础部分的作业 2.函数部分的作业 3.字典.集合.文件部分作业 4.异常 5.EasyGui 6.类.对象.魔法方法 7.模块 8.爬虫 ...
- 零基础入门python小甲鱼-小甲鱼零基础入门学习Python百度云下载 | 宅男君
Python编程语言可以在不同平台上使用,比如Windows.MAC.Linux操作系统.通常情况下,一个Python程序在你自己的Windows系统上运行,也可以在别人的MAC系统上运行.Pytho ...
- python零基础入门教程百度云-小甲鱼零基础入门学习Python百度云下载 | 宅男君
Python编程语言可以在不同平台上使用,比如Windows.MAC.Linux操作系统.通常情况下,一个Python程序在你自己的Windows系统上运行,也可以在别人的MAC系统上运行.Pytho ...
- 小甲鱼python教程视频怎么样-小甲鱼零基础入门学习Python视频教程全套96集
资源介绍 教程名称: 小甲鱼零基础入门学习Python视频教程全套96集 课程简介: xa0 xa0 Python具有跨平台特点,Python可以在各种不同类型的计算机上运行,Windows.MAC. ...
- 小甲鱼零基础入门学习Python(绝对干货,值得学习)
小甲鱼零基础入门学习Python(绝对干货,值得学习) 链接: https://pan.baidu.com/s/1jJmIrlk 密码: ktp2
- 第031讲:永久存储,腌制一缸美味的泡菜 | 学习记录(小甲鱼零基础入门学习Python)
(标答出处: 鱼C论坛) <零基础入门学习Python> 测试题: 0.pickle的实质是什么? pickle的实质是利用一些算法,将你的数据对象腌制成二进制文件,存储在磁盘上,也可以放 ...
- 第023、024讲:这帮小兔崽子汉诺塔 | 学习记录(小甲鱼零基础入门学习Python)
(标答出处: 鱼C论坛) <零基础入门学习Python> 测试题: 0.使用递归编写一个十进制转换为二进制的函数(要求采用'取2取余'的方式,结果与调用bin()函数一样返回字符串形式) ...
- 第019讲:我的地盘听我的 | 学习记录(小甲鱼零基础入门学习Python)
(标答出处: 鱼C论坛) <零基础入门学习Python> 测试题: 0.下边程序会输入什么? def next():print('我在next()函数里...')pre()def pre( ...
- 小甲鱼python课件免费_小甲鱼零基础入门学习Python+全套源码课件-资源共享吧收集整理...
游客,如果您要查看本帖隐藏内容请回复 第000讲 愉快的开始(视频+课件) 第001讲 我和Python的第一次亲密接触(视频+课件) 第002讲 用Python设计第一个游戏(视频+课件+源代码) ...
最新文章
- Ubuntu12.10编译openwrt遇到的错误
- 【408预推免复习】计算机组成原理之计算机系统概论
- 解决devenv.exe应用程序错误,应用程序发生异常
- html5绘制矩形动画,HTML5下绘制矩形教程
- FAST20 论文学习
- 磁盘阵列(RAID) 级别
- 使用LitePal查询数据
- 4G标准LTE FDD与LTE TDD的不同
- vue 项目 跨域问题
- touch触摸事件以及常用触摸功能
- 100php等于多少RMB,100000 CNY
- Raspberry Pi 3B学习笔记
- WinRAR(5.70)去广告
- (46)改变占空比与相移
- hdu3018解题报告--也是白话几笔画学习总结
- c语言 pow和sqrt注意
- cgb2110-day10
- 使用.net core ABP和Angular模板构建博客管理系统(实现博客列表页面)
- Next.js---一个轻量级的 React SSR应用框架
- d强制访问位置服务器的数据库w,基于WEB的分布式数据库系统的研究与设计-软件工程专业论文.docx...
热门文章
- springboot 整合mysql clickhouse 多数据源
- SpringBoot打包部署成Windows服务的详细步骤
- 如何备份服务器win2008r2系统,数据保护:Win2008 R2 中的备份基础
- 小米盒子系统统计服务器,小米盒子还有这个功能,90%的人肯定不知道!
- 如何高效地利用通达信数据接口?
- OSS brower js SDK
- Client/Server 和 Browser/Server 模式的区别
- iOS备忘录之mac常用命令行
- php yii2 sns,GitHub - szhsh/iisns: 基于 yii2 的 sns 社区系统,一站式解决社区建站
- php怎么实现模拟登陆,php模拟登陆的实现方法_PHP教程