2020.10.13 Tuesday Rainy
经典Canny算法:此算法与HED网络基本上没有任何关联
图是由点组成的,而点是可以由黑白或者RGB三色组合而成。一般形象的来说,一个点可以把它看作是一个数字或三个数字,而一个数字可以理解为黑白图像,三个数字则可以理解为彩色图像。彩色图像有自己的通道数,除了最喜闻乐见RGB彩色通道之外,还有其他的颜色通道,如CMYK。将这些点组合,如28X28个点凑成的黑白图像,可以转化为28X28维的矩阵。
卷积滤波:图像都是有噪声的,那么要实现去噪,就得采用信号处理方法——滤波处理,如3X3区域与卷积核乘积加起来作为该像素值,不断滑动窗口,对整个图像作处理的方法。
(Question1:为什么这样做,这样去代替一个像素值,就可以达到去噪的目的呢?这个问题有待研究和解决)。有时,为了想让图像变亮,提高图像的亮度,可以采用所有元素均大于1的卷积核(Question2:这样撑乘起来再相加,像素值不会超过255吗?)。对于图像边缘的像素,由于卷积核无法改变该像素(通过中心元素替换),所以有两种解决办法:1.保持边缘像素不变,直接放入新图像;2.省略掉该像素,相当于缩小该图像的像素大小。
现在用图来表现出不同卷积核的效果:
原图:
1.空卷积核,如
处理得到的结果相当于原图。
2.低通滤波器卷积核:
处理得到的结果:
可以乍一看没什么区别,但是仔细看还是可以看出细微的出入的。
2.锐化滤波,如
处理得到:
得到的图像中心位置被加大,这个图的效果不够明显。请看下图:
卷积核的取值不重要,重要的是看效果:中心位置被加大。倘若锐化滤波的核被进一步加大,那么,得到的图像相比于锐化滤波来说,更精细。
3.边缘检测,如:
处理的结果:
4.浮雕滤波,如:处理的结果:
上图是黑白处理了的图像。
上图是彩色图像。
得到的图像把背景和目标几乎分开了,就像把目标雕上去的一样。
高斯滤波(高斯模糊):符合正态分布密度函数的规则(主要是二维正态分布),将权重卷积核变为:
这样去噪的目的就很明确且有效了,即过滤高频信号——噪声。(为什么卷积核的值定成这样就可以有效的去噪?“经验之谈”)
边缘检测:其实上面有边缘检测的结果。该方法就是标识数字图像中亮度变化明显的点,如二维码的识别,这当中第一步就是边缘检测。
Canny边缘检测的步骤:
1.高斯模糊(去除高频分量,即噪声);2.计算梯度幅值和方向(得到边缘):常用Sobel算子计算梯度,得到粗大明亮的边缘;3.非极大值抑制(边缘细化):保留局部最大梯度,抑制其他梯度值(即保留梯度变化中最锐利的位置像素);4.双阈值(区分边缘像素):大于高阈值,记为强边缘点,大于低阈值,小于高阈值,记为弱边缘点;5.滞后边界跟踪(整合弱边缘):强边缘即真正的边缘,但是弱边缘很可能是由噪声或颜色所引起的,本着这个原则,给出了一个简单的做法:搜索所有连通的弱边缘,如果一条连通的弱边缘的任何一个点和强边缘点连通,则保留这条弱边缘,否则抑制这条弱边缘。搜索的时候,可以采用别人的算法:广度优先/深度优先算法。
canny算法缺点:1. 算法的检测效果,依赖于几个阈值参数,而且这些阈值参数的选择,通常都是人为设置的经验值。这些参数只是一组或少数几组固定的组合,所以算法的鲁棒性又会打折扣,很容易遇到边缘检测效果不理想的场景。
调用python中的Canny函数,进行检测:
import cv2
import numpy as np
img = cv2.imread('image0.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src',img)
# canny: 1.将彩图转为灰度 2. 高斯 3.canny
# 灰度化
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 高斯滤波
# 参数一: 灰度图像数据 参数二: 模板大小 参数三: sigmaX
imgG = cv2.GaussianBlur(gray,(3,3),0)
# 参数一: 图片数据 参数二: 两个阈值
dst = cv2.Canny(img,50,50) # 图片卷积之后的值 大于 th 就认为是边缘点
cv2.imshow('dst',dst)
2020.10.14 Wednesday Rainy
各种代码:出结果:





2020.10.14 Wednesday Rainy
图像学习中的梯度直方图的计算:(一切从简)特征描述子:图像的表示,留下有用的信息,舍弃无用的信息。Usually,特征描述子会把wh3(Width and height is w,h respedtively,channel is 3)的图像transfer to a matrix of n length or n length vector.For instance, a 64x128x3 image, output image by transfering have 3780 length of vector(有3780向量长度).Question:What feature is useful?
Hypothesis:要预测体现出一张图像里面的扣子,可以利用边缘检测来去掉无关紧要的颜色特征,减少干扰,这样一来就可以检测并显示出带有几个洞的图像,那么就可以区分其他图形或形状,即这就利用了一个特征——两个洞,来进行区分。
在HOG梯度分布直方图中,梯度的方向被看作是特征。一般的方法都是沿着x或y轴方向进行检测梯度的。边缘和角的梯度值一般都很大,因为边缘和角点包含了很多形状信息。
计算梯度直方图的步骤:
1.预处理(hog_preprocess):
2.计算梯度图像(horizontal_vertical_gradient_kernel):
利用核计算x,y方向(水平/垂直)的梯度:
// C++ gradient calculation.
// Read image
Mat img = imread("bolt.png");
img.convertTo(img, CV_32F, 1/255.0);
// Calculate gradients gx, gy
Mat gx, gy;
Sobel(img, gx, CV_32F, 1, 0, 1);
Sobel(img, gy, CV_32F, 0, 1, 1);
# Python gradient calculation
# Read imageim = cv2.imread('bolt.png')
im = np.float32(im) / 255.0
# Calculate gradient
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=1)
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=1)
接着,用下面的公式来计算梯度的幅值g和方向theta:
可以用OpenCV的cartToPolar函数来计算:
// C++ Calculate gradient magnitude and direction (in degrees)
Mat mag, angle;
cartToPolar(gx, gy, mag, angle, 1);
# Python Calculate gradient magnitude and direction ( in degrees )
mag, angle = cv2.cartToPolar(gx, gy, angleInDegrees=True)
计算到的结果:
左边:x轴的梯度绝对值 中间:y轴的梯度绝对值 右边:梯度幅值
图像的梯度图去掉了其他特征,可以让人们一眼望穿其形状。
3.网络的计算:
一个图像被分成8x8的网格,所以图像有8x8x3=192个像素,又,每个像素有两个值(幅值&方向),幅值又是选取通道最大的值,所以有8x8x2=128个像素。然后利用9个框来表示,选用这几个框不仅是为了数据紧凑还是为了抗噪。一个梯度会受到信号的干扰。
上图靠下面那个矩阵图中的值之所以不是0-360,而是0-180,是因为这个范围(0-180是无符号梯度)检测效果好。
80方向这个位置对应2这个幅值,因为没有10这个方向,所以对半分0-20范围的幅值。倘若不能平分,那就按照比列计算幅值。
4.归一化:
目的:消除光线对图片的影响(源于梯度对图片的影响),有一种方法:像素点除2,那么幅值和直方图的值都会减半,无用。
上面的步骤中,创建了基于图片的梯度直方图,但是一个图片的梯度对于整张图片的光线会很敏感。如果把所有的像素点都除以2,那么梯度的幅值也会减半,直方图里面的值也会减半,所以这样并不能消除光线的影响。所以理想情况下,希望的特征描述子可以和光线变换无关,所以就想让直方图归一化从而不受光线变化影响。
先考虑对向量用l2归一化的步骤是:
v = [128, 64, 32]
[(128^2) + (64^2) + (32^2) ]^0.5=146.64
把v中每一个元素除以146.64得到[0.87,0.43,0.22]
考虑另一个向量2*v,归一化后可以得到向量依旧是[0.87, 0.43, 0.22]。显然,归一化是把scale给移除了。
Pygame:第094讲,飞机大战5:
写入函数:击毁敌机,标志并显示分数
检测MouseMotion函数:该函数用来判断是否在pause图片上按下了鼠标按钮。
难度的控制:达到一定分数——> 提高难度——>更改音效,同时增加敌机的数量和速度。
端代码:
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_image
self.me2_image = me2_image
self.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"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_1.png").convert_alpha() #自身飞机炸毁第1张图片
self.me_destory_2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_2.png").convert_alpha() #自身飞机炸毁第2张图片
self.me_destory_3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_3.png").convert_alpha() #自身飞机炸毁第3张图片
self.me_destory_4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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_image
self.enemy1 = pygame.image.load(enemy1_image).convert_alpha() #载入低级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy1_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down1.png").convert_alpha() #低级敌机撞到爆炸第1张图片
self.enemy1_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down2.png").convert_alpha() #低级敌机撞到爆炸第2张图片
self.enemy1_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down3.png").convert_alpha() #低级敌机撞到爆炸第3张图片
self.enemy1_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = 8
def __init__(self,bg_size,enemy2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy2_image = enemy2_image
self.enemy2 = pygame.image.load(enemy2_image).convert_alpha() #载入中级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy2_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down1.png").convert_alpha() #中级敌机撞到爆炸第1张图片
self.enemy2_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down2.png").convert_alpha() #中级敌机撞到爆炸第2张图片
self.enemy2_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down3.png").convert_alpha() #中级敌机撞到爆炸第3张图片
self.enemy2_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down4.png").convert_alpha() #中级敌机撞到爆炸第4张图片
self.enemy2_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 8
self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
randint(-10*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机
class BigEnemy(pygame.sprite.Sprite): #定义我的大敌机类,继承自动画精灵
energy = 20
def __init__(self,bg_size,enemy3_n1_image,enemy3_n2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy3_n1_image = enemy3_n1_image
self.enemy3_n1 = pygame.image.load(enemy3_n1_image).convert_alpha() #载入高级敌机照片
self.enemy3_n2_image = enemy3_n1_image
self.enemy3_n2 = pygame.image.load(enemy3_n2_image).convert_alpha() #载入高级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy3_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down1.png").convert_alpha() #高级敌机撞到爆炸第1张图片
self.enemy3_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down2.png").convert_alpha() #高级敌机撞到爆炸第2张图片
self.enemy3_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down3.png").convert_alpha() #高级敌机撞到爆炸第3张图片
self.enemy3_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down4.png").convert_alpha() #高级敌机撞到爆炸第4张图片
self.enemy3_down5_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down5.png").convert_alpha() #高级敌机撞到爆炸第5张图片
self.enemy3_down6_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down6.png").convert_alpha() #高级敌机撞到爆炸第6张图片
self.enemy3_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 20
self.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 = position
self.active = True
def main() :
pygame.init() #初始化
pygame.mixer.init() #混音器初始化
clock = pygame.time.Clock() #设置一个计时器
transform = False #设置一个是否改变的变量
delay = 100 #类似于单片机,设置一个延时变量,让飞机的改变看起来更加的顺滑
switch_image = True # 用于切换图片
running = True
#创建字体的标志
font = pygame.font.Font(r'C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf',35)
#初始化分数
score = 0
#设置难度等级
level = 1
black = ([0,0,0]) #黑色
green = ([0,255,0]) #绿色
red = ([255,0,0]) #红色
white = ([255,255,255]) #白色
"""载入音乐文件"""
#背景音乐
pygame.mixer.music.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\game_music.ogg") #设置背景音乐
pygame.mixer.music.set_volume(1) #设置音量
#游戏音效
bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\bullet.wav") #子弹特效
bullet_sound.set_volume(0.5)
button_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\button.wav") #按键特效
button_sound.set_volume(0.5)
enemy1_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy1_down.wav") #低等敌机被击毁音效
enemy1_down_sound.set_volume(0.5)
enemy2_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy2_down.wav") #中等敌机被击毁音效
enemy2_down_sound.set_volume(0.5)
enemy3_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_down.wav") #高等敌机被击毁音效
enemy3_down_sound.set_volume(0.5)
enemy3_fly_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_flying.wav") #高等敌机出现音效
enemy3_fly_sound.set_volume(0.5)
get_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bomb.wav") #获得全屏炸弹补给音效
get_bomb_sound.set_volume(0.5)
get_bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bullet.wav") #获得双倍子弹补给音效
get_bullet_sound.set_volume(0.5)
myself_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\me_down.wav") #自身飞机被击毁(死亡)音效
myself_down_sound.set_volume(0.5)
supply_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\supply.wav") #补给产生音效
supply_sound.set_volume(0.5)
upgrade_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\upgrade.wav") #升级音效
upgrade_sound.set_volume(0.5)
use_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\use_bomb.wav") #使用全屏炸弹音效
use_bomb_sound.set_volume(0.5)
"""图片文件路径"""
again_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\again.png" #重新开始图片路径
background_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\background.png" #背景图的路径
bomb_supply_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb_supply.png" #全屏炸弹补给图
bullet_supply_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet_supply.png" #补给子弹图
bullet1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet1.png" #第一种子弹图
bullet2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet2.png" #第二种子弹图
enemy1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1.png" #低级敌机图片
enemy2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2.png" #中级敌机图片
enemy3_n1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n1.png" #高级敌机图片1
enemy3_n2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n2.png" #高级敌机图片2
gameover_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\gameover.png" #游戏结束图片
life_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\life.png" #表示生命值的图片
me1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me1.png" #自身飞机第一张图片
me2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
pause_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_nor.png" ).convert_alpha() #暂停的时候图片
pause_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_pressed.png" ).convert_alpha() #暂停到继续的中间变换图
resume_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_nor.png").convert_alpha() #继续的时候的图片
resume_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_pressed.png" ).convert_alpha() #继续到暂停的中间变换图
paused_rect = pause_nor_image.get_rect()
paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
paused_image = pause_nor_image
# 全屏炸弹
bomb_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb.png").convert_alpha()
bomb_rect = bomb_image.get_rect()
bomb_font = pygame.font.Font(r'C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf', 48)
bomb_num = 3
#中弹图片索引
e1_destroy_index = 0
e2_destroy_index = 0
e3_destroy_index = 0
myself_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标志键变为True
if paused_rect.collidepoint(event.pos): #让暂停图标在鼠标按下时立即改变
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
screen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮
elif event.type == MOUSEMOTION: #鼠标是否移动到暂停照片上显示不同的图片
if paused_rect.collidepoint(event.pos):
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
elif event.type == KEYDOWN :
if event.key == K_SPACE: #如果按下空格键,投放超级炸弹
if bomb_num : #如果还有超级炸弹,那么炸弹数量-1
bomb_num -= 1
use_bomb_sound.play()
for each in enemies:
if each.rect.bottom > 0:
each.active = False
screen.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 = 2
upgrade_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 = 3
upgrade_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 = 4
upgrade_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 = 5
upgrade_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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 6
if 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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 4
if 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) % 4
if 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) % 4
if 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 #生命值-1
if e.energy == 0 : #如果生命值变为0
e.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那么重新调回100
delay = 100
delay -= 1
#检查双方飞机是否发生碰撞
enemies_down = pygame.sprite.spritecollide(myself, enemies, False,collided=pygame.sprite.collide_mask) #将所有与我们的飞机发生碰撞的敌方飞机都加入到组中
if enemies_down: #如果组中有成员,说明又发生碰撞
#myself.active = False #我放飞机存活状态变成False
for 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: #这是按下 × 的异常,直接忽略
pass
except:
traceback.print_exc()
pygame.quit()
input()
介个代码运行之后,飞机不能撞毁,这个问题有待考究。
监督学习方式:根据之前的数据预测给出准确的输出值;也称作回归问题,另一种监督学习方式(分类问题),即离散的输出,0/1输出问题。在监督学习下的数据集就是训练集。
训练集如下表:
代表学习算法的解决方案或函数:
假设:
2.代价函数:
选择合适的参数,参数直接决定了拟合曲线相对于数据集/训练集的准确程度,预测值与模型实际值之间差距就是建模误差。如下图:
代价函数的目标是选择出使建模误差平方和最小的模型参数,即代价函数(平方误差函数,平方误差代价函数,解决回归问题有力手段)最小。
m是训练集中实例的数量。
则可以看出在三维空间中存在一个使得代价函数最小的点。
5.求代价函数的方法:
Ex1:直接求二次函数最小值:
Ex2:利用等高线图,求出二次函数最小值点:
Ex3:梯度下降法,“下山”:
思想:
公式:
aphar是学习率,“决定下迈的步子有多大”
梯度下降法的流程图:
该方法的缺陷是:无法判断输出是否是最小值,可能只输出局部最小值。
Ex5:梯度下降的线性回归方法:
Ex6:正规方程法.
如果数据量大的话,还是选用梯度下降的线性回归方法较好。
线性回归python的例子1:
from sklearn.linear_model import LinearRegression
import numpy as np
# 1).模拟数据
X = np.random.rand(100, 1)
Y = 4 + 2 * X + np.random.randn(100, 1)
# 2). 调用sklearn拟合数据, 把theta0 theta1求出来
# 导入线性回归类
lin_reg = LinearRegression()
# 让线性回归类做训练
lin_reg.fit(X, Y)
# 输出theta0 theta1; intercept_是截距, coef_是斜率系数;
print("\ntheat0, theta1:", lin_reg.intercept_, lin_reg.coef_)
# 3). 预测
X_new = np.array([[0], [1]])
print("\nx=0, x=1预测结果:\n", lin_reg.predict(X_new))
线性回归python的例子1:
"""
线性回归实现梯度下降的批处理(batch_gradient_descent )
"""
import numpy as np
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# print(X_b)
learning_rate = 0.1
# 通常在做机器学习的时候,一般不会等到他收敛,因为太浪费时间,所以会设置一个收敛次数
n_iterations = 100000
m = 100
# 1.初始化theta, w0...wn
theta = np.random.randn(2, 1)
count = 0
# 4. 不会设置阈值,之间设置超参数,迭代次数,迭代次数到了,我们就认为收敛了
for iteration in range(n_iterations):
count += 1
# 2. 接着求梯度gradient
gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
# 3. 应用公式调整theta值, theta_t + 1 = theta_t - grad * learning_rate
theta = theta - learning_rate * gradients
print(count)
print(theta)
Pygame:第095讲,飞机大战6:
实现补给:新建类
实例化补给包(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_image
self.me2_image = me2_image
self.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"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_1.png").convert_alpha() #自身飞机炸毁第1张图片
self.me_destory_2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_2.png").convert_alpha() #自身飞机炸毁第2张图片
self.me_destory_3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_3.png").convert_alpha() #自身飞机炸毁第3张图片
self.me_destory_4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 - 30) : #如果我方飞机没有飞出 上方边界
self.rect.bottom += 10 #那么我方飞机朝下飞10个像素
else : #飞出 下方边界
self.rect.bottom = (self.height - 10) #锁定在底边界上方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_image
self.enemy1 = pygame.image.load(enemy1_image).convert_alpha() #载入低级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy1_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down1.png").convert_alpha() #低级敌机撞到爆炸第1张图片
self.enemy1_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down2.png").convert_alpha() #低级敌机撞到爆炸第2张图片
self.enemy1_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down3.png").convert_alpha() #低级敌机撞到爆炸第3张图片
self.enemy1_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = 8
def __init__(self,bg_size,enemy2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy2_image = enemy2_image
self.enemy2 = pygame.image.load(enemy2_image).convert_alpha() #载入中级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy2_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down1.png").convert_alpha() #中级敌机撞到爆炸第1张图片
self.enemy2_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down2.png").convert_alpha() #中级敌机撞到爆炸第2张图片
self.enemy2_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down3.png").convert_alpha() #中级敌机撞到爆炸第3张图片
self.enemy2_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down4.png").convert_alpha() #中级敌机撞到爆炸第4张图片
self.enemy2_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 8
self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
randint(-10*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机
class BigEnemy(pygame.sprite.Sprite): #定义我的大敌机类,继承自动画精灵
energy = 20
def __init__(self,bg_size,enemy3_n1_image,enemy3_n2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy3_n1_image = enemy3_n1_image
self.enemy3_n1 = pygame.image.load(enemy3_n1_image).convert_alpha() #载入高级敌机照片
self.enemy3_n2_image = enemy3_n1_image
self.enemy3_n2 = pygame.image.load(enemy3_n2_image).convert_alpha() #载入高级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy3_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down1.png").convert_alpha() #高级敌机撞到爆炸第1张图片
self.enemy3_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down2.png").convert_alpha() #高级敌机撞到爆炸第2张图片
self.enemy3_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down3.png").convert_alpha() #高级敌机撞到爆炸第3张图片
self.enemy3_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down4.png").convert_alpha() #高级敌机撞到爆炸第4张图片
self.enemy3_down5_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down5.png").convert_alpha() #高级敌机撞到爆炸第5张图片
self.enemy3_down6_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down6.png").convert_alpha() #高级敌机撞到爆炸第6张图片
self.enemy3_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 20
self.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 = position
self.active = True
class Bullet2(pygame.sprite.Sprite):
def __init__(self,bullet2_image,position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(bullet2_image).convert_alpha()
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
self.speed = 14
self.active = False
self.mask = pygame.mask.from_surface(self.image)
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 = position
self.active = True
"""\/\/\/\/\/\/\/\/------补给类------\/\/\/\/\/\/\/\/"""
class Bullet_Supply(pygame.sprite.Sprite):
def __init__(self,bg_size) :
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet_supply.png").convert_alpha() #补给子弹图
self.rect = self.image.get_rect()
self.width , self.height = bg_size[0] ,bg_size[1]
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100 #随机生成补给的位置
self.speed = 5 #补给下落的速度
self.active = False #补给是否激活
self.mask = pygame.mask.from_surface(self.image)
def move (self) : #运动函数
if self.rect.top < self.height :
self.rect.top += self.speed
else :
self.active = False
def reset(self): #重置函数
self.active = True
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100
class Bomb_Supply(pygame.sprite.Sprite):
def __init__(self,bg_size) :
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb_supply.png").convert_alpha() #全屏炸弹补给图
self.rect = self.image.get_rect()
self.width , self.height = bg_size[0] ,bg_size[1]
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100 #随机生成补给的位置
self.speed = 5 #补给下落的速度
self.active = False #补给是否激活
self.mask = pygame.mask.from_surface(self.image)
def move (self) : #运动函数
if self.rect.top < self.height :
self.rect.top += self.speed
else :
self.active = False
def reset(self): #重置函数
self.active = True
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100
def main() :
pygame.init() #初始化
pygame.mixer.init() #混音器初始化
clock = pygame.time.Clock() #设置一个计时器
transform = False #设置一个是否改变的变量
delay = 100 #类似于单片机,设置一个延时变量,让飞机的改变看起来更加的顺滑
switch_image = True # 用于切换图片
running = True
#创建字体的标志
font = pygame.font.Font(r'C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf',35)
#初始化分数
score = 0
#设置难度等级
level = 1
black = ([0,0,0]) #黑色
green = ([0,255,0]) #绿色
red = ([255,0,0]) #红色
white = ([255,255,255]) #白色
"""载入音乐文件"""
#背景音乐
pygame.mixer.music.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\game_music.ogg") #设置背景音乐
pygame.mixer.music.set_volume(1) #设置音量
#游戏音效
bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\bullet.wav") #子弹特效
bullet_sound.set_volume(0.5)
button_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\button.wav") #按键特效
button_sound.set_volume(0.5)
enemy1_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy1_down.wav") #低等敌机被击毁音效
enemy1_down_sound.set_volume(0.5)
enemy2_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy2_down.wav") #中等敌机被击毁音效
enemy2_down_sound.set_volume(0.5)
enemy3_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_down.wav") #高等敌机被击毁音效
enemy3_down_sound.set_volume(0.5)
enemy3_fly_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_flying.wav") #高等敌机出现音效
enemy3_fly_sound.set_volume(0.5)
get_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bomb.wav") #获得全屏炸弹补给音效
get_bomb_sound.set_volume(0.5)
get_bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bullet.wav") #获得双倍子弹补给音效
get_bullet_sound.set_volume(0.5)
myself_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\me_down.wav") #自身飞机被击毁(死亡)音效
myself_down_sound.set_volume(0.5)
supply_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\supply.wav") #补给产生音效
supply_sound.set_volume(0.5)
upgrade_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\upgrade.wav") #升级音效
upgrade_sound.set_volume(0.5)
use_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\use_bomb.wav") #使用全屏炸弹音效
use_bomb_sound.set_volume(0.5)
"""图片文件路径"""
again_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\again.png" #重新开始图片路径
background_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\background.png" #背景图的路径
bullet1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet1.png" #第一种子弹图
bullet2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet2.png" #第二种子弹图
enemy1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1.png" #低级敌机图片
enemy2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2.png" #中级敌机图片
enemy3_n1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n1.png" #高级敌机图片1
enemy3_n2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n2.png" #高级敌机图片2
gameover_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\gameover.png" #游戏结束图片
life_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\life.png" #表示生命值的图片
me1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me1.png" #自身飞机第一张图片
me2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me2.png" #自身飞机第二张图片
#设置背景
bg_size = width , height = 480 , 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 = False
pause_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_nor.png" ).convert_alpha() #暂停的时候图片
pause_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_pressed.png" ).convert_alpha() #暂停到继续的中间变换图
resume_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_nor.png").convert_alpha() #继续的时候的图片
resume_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_pressed.png" ).convert_alpha() #继续到暂停的中间变换图
paused_rect = pause_nor_image.get_rect()
paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
paused_image = pause_nor_image
#补给包
bullet_supply = Bullet_Supply(bg_size)
bomb_supply = Bomb_Supply(bg_size)
supply_timer = USEREVENT
pygame.time.set_timer(supply_timer,30000) #设定自定义事件每隔30s返回一个用户自定义事件属性
#超级子弹定时器
double_bullet_timer = USEREVENT + 1
# 标志是否使用超级子弹
is_double_bullet = False
# 全屏炸弹
bomb_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb.png").convert_alpha()
bomb_rect = bomb_image.get_rect()
bomb_font = pygame.font.Font(r"C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf", 48)
bomb_num = 3
#中弹图片索引
e1_destroy_index = 0
e2_destroy_index = 0
e3_destroy_index = 0
myself_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)) #使用子弹类生成子弹
# 生成超级子弹
bullet2 = []
bullet2_index = 0
bullet2_num = 8
for i in range(bullet2_num//2):
bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx-33, myself.rect.centery)))
bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx+30, myself.rect.centery)))
#生成敌机组
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标志键变为True
if paused_rect.collidepoint(event.pos): #让暂停图标在鼠标按下时立即改变
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
screen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮
if paused : #如果暂停了
pygame.time.set_timer(supply_timer,0)
pygame.mixer.music.pause()
pygame.mixer.pause()
else :
pygame.time.set_timer(supply_timer,30000)
pygame.mixer.music.unpause()
pygame.mixer.unpause()
elif event.type == MOUSEMOTION: #鼠标是否移动到暂停照片上显示不同的图片
if paused_rect.collidepoint(event.pos):
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
elif event.type == KEYDOWN :
if event.key == K_SPACE: #如果按下空格键,投放超级炸弹
if bomb_num : #如果还有超级炸弹,那么炸弹数量-1
bomb_num -= 1
use_bomb_sound.play()
for each in enemies:
if each.rect.bottom > 0:
each.active = False
elif event.type == supply_timer : #响应补给包事件
supply_sound.play() #播放补给的声音
if choice([True,False]) : #随机生成子弹补给或者炸药补给
bullet_supply.reset()
else :
bomb_supply.reset()
elif event.type == double_bullet_timer: #响应超级子弹事件
is_double_bullet = False
pygame.time.set_timer(double_bullet_timer, 0)
screen.blit(background,(0,0)) #绘制背景
#如果没有暂停
if not paused:
pygame.mixer.music.unpause() #暂停背景音乐s
# 根据用户的得分增加难度
if level == 1 and score > 50000:
level = 2
upgrade_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 = 3
upgrade_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(middleenemies, 1)
elif level == 3 and score > 600000:
level = 4
upgrade_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(middleenemies, 1)
elif level == 4 and score > 1000000:
level = 5
upgrade_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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 6
if 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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 4
if 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) % 4
if 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) % 4
if myself_destroy_index == 0:
print("Game Over!")
running = False
#绘制从飞机中出现的子弹
if not (delay % 10) : #设置每10帧射出一个子弹
bullet_sound.play()
if is_double_bullet:
bullets = bullet2
bullets[bullet2_index].reset((myself.rect.centerx-33, myself.rect.centery))
bullets[bullet2_index+1].reset((myself.rect.centerx+30, myself.rect.centery))
bullet2_index = (bullet2_index + 2) % bullet2_num
else:
bullets = bullet1
bullet1[bullet1_index].reset(myself.rect.midtop) #将子弹的坐标初放到飞机的前面
bullet1_index = (bullet1_index + 1) % bullet1_num #使子弹的下标始终处于0-4间不断循环
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))
#检测子弹是否击中敌机
for b in bullets: #对于列表中的的所有子弹
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 #生命值-1
if e.energy == 0 : #如果生命值变为0
e.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那么重新调回100
delay = 100
delay -= 1
#检查双方飞机是否发生碰撞
enemies_down = pygame.sprite.spritecollide(myself, enemies, False,collided=pygame.sprite.collide_mask) #将所有与我们的飞机发生碰撞的敌方飞机都加入到组中
if enemies_down: #如果组中有成员,说明又发生碰撞
#myself.active = False #我放飞机存活状态变成False
for e in enemies_down:
e.active = False #对于与我相撞的飞机的也设为False
#绘制全屏炸弹补给并检测是否发生碰撞
if bomb_supply.active : #如果炸弹补给是激活的
bomb_supply.move() #补给移动
supply_sound.play() #播放炸弹补给出现音乐
screen.blit(bomb_supply.image,bomb_supply.rect) #绘制补给图片
if pygame.sprite.collide_mask(bomb_supply,myself): #检测补给和我放飞机是否发送碰撞
bomb_supply.active = False #如果发生碰撞,那么补给变为未激活状态
get_bomb_sound.play()#播放得到补给的音效
if bomb_num < 3: #如果炸弹数小于3
bomb_num += 1 #炸弹数+1
#绘制子弹补给并检测是否发生碰撞
if bullet_supply.active : #如果子弹补给是激活的
bullet_supply.move() #补给移动
screen.blit(bullet_supply.image,bullet_supply.rect) #绘制补给图片
if pygame.sprite.collide_mask(bullet_supply,myself): #检测补给和我放飞机是否发送碰撞
bullet_supply.active = False #如果发生碰撞,那么补给变为未激活状态
get_bullet_sound.play()#播放得到补给的音效
# 绘制超级子弹补给并检测是否获得
if bullet_supply.active:
bullet_supply.move()
screen.blit(bullet_supply.image, bullet_supply.rect)
if pygame.sprite.collide_mask(bullet_supply, myself):
get_bullet_sound.play()
#发射超级子弹18秒
is_double_bullet = True
pygame.time.set_timer(double_bullet_timer, 18 * 1000)
bullet_supply.active = 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: #这是按下 × 的异常,直接忽略
pass
except:
traceback.print_exc()
pygame.quit()
input()
2020.10.17 Saturday Sunny
多元线性回归算法。
增加单个变量到多个变量,顺势推广至多元:


特征缩放:
取十分近的特征值(不是相差过大的),做归一化处理,为了让梯度下降的更快,更早收敛。
现在的问题即求解此方程,稍微推了下正规方程怎么来的,由于X可能并不是方阵,应该说大多数情况下都不是,所以两边先同时左乘一个XT,再求解。
仍可能存在问题:XTX不可逆,可通过正则化去掉线性相关变量等操作继续实现。
两个列子:
text文件,数据集
密码:czai
import numpy as np
import matplotlib.pyplot as plt
# 梯度下降求y=θ0+θ1x
def getθ(x, y, α):
θ0 ,θ1 = 0,0
m = len(x)
for i in range(1000):
sum1=0
for j in range(m):
sum1 += (θ0+θ1*x[j]-y[j])
θ0 -= α/m*sum1
sum2 = 0
for j in range(m):
sum2 += ((θ0+θ1*x[j]-y[j])*x[j])
θ1 -= α/m*sum2
return [θ0 ,θ1 ]
# 正规方程求y=θ0+θ1x
def getθ2(x, y):
x_list = []
for i in range(len(x)):
x_list.append([1, x[i]])
x_matrix = np.matrix(x_list)
y_matrix = np.matrix(y)
θ = ((x_matrix.T*x_matrix).I*x_matrix.T*(y_matrix.T)).tolist() # matrix.T求转置,matrix.I求逆,*矩阵相乘,tolist()转为列表
return [θ[0][0],θ[1][0]]
x, y = [],[]
for sample in open(r"C:\Users\96326\Desktop\ALL\Dataset\prices.txt" , "r"):
_x, _y = sample.split(",")
x.append(float(_x))
y.append(float(_y))
x, y = np.array(x), np.array(y) # 转化为Numpy数组待处理
x = (x - x.mean()) / x.std() # 标准化,Mean表示取均值,std()为标准差,var()是方差
plt.figure()
plt.xlabel("x轴")
plt.ylabel("y轴")
plt.scatter(x, y, c="g", s=6) #s是点的大小,c是颜色‘b’blue‘g’green‘r’red‘c’cyan‘m’magenta‘y’yellow‘k’black‘w’white
list = getθ(x,y,0.2)
x0 = np.linspace(-2, 4 ,100) # 在-2到4上取点绘制直线
y0 = list[0]+list[1]*x0
print("梯度下降实现:y="+str(list[0])+"+"+str(list[1])+"*x")
plt.plot(x0, y0,"g")
plt.show()
plt.figure()
plt.xlabel("x轴")
plt.ylabel("y轴")
plt.scatter(x, y, c="g", s=6) #s是点的大小,c是颜色‘b’blue‘g’green‘r’red‘c’cyan‘m’magenta‘y’yellow‘k’black‘w’white
list2 = getθ2(x, y)
x1 = np.linspace(-2, 4 ,100) # 在-2到4上取点绘制直线
y1 = list2[0]+list2[1]*x1
print("正规方程实现:y="+str(list2[0])+"+"+str(list2[1])+"*x")
plt.plot(x1, y1,"r")
plt.show()
Pygame:第96讲:飞机大战7(完结撒花):
记录分数,增加炸弹数量及作弊按钮
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_image
self.me2_image = me2_image
self.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"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_1.png").convert_alpha() #自身飞机炸毁第1张图片
self.me_destory_2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_2.png").convert_alpha() #自身飞机炸毁第2张图片
self.me_destory_3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me_destroy_3.png").convert_alpha() #自身飞机炸毁第3张图片
self.me_destory_4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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#设置飞机是否生存的状态
self.invincible = 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 #锁定在底边界的位置,不再发生变化
def reset(self):
self.active = True#设置飞机是否生存的状态
self.invincible = True #重新设置飞机处于无敌状态
self.rect.left , self.rect.top = [ (self.width - self.rect.width) // 2 , \
(self.height - self.rect.height - 60) ] #设置我方飞机出现的位置
"""\/\/\/\/\/\/\/\/------敌机类------\/\/\/\/\/\/\/\/"""
"""本来这里其实可以使用类的继承,然后三种敌机分别继承这个敌机类生成新的敌机,但是在这里、
没有这样做的必要,因为三个类的差别并不是很大,所以不用那么繁杂"""
class SmallEnemy(pygame.sprite.Sprite): #定义我的低敌机类,继承自动画精灵
def __init__(self,bg_size,enemy1_image):
pygame.sprite.Sprite.__init__(self)
self.enemy1_image = enemy1_image
self.enemy1 = pygame.image.load(enemy1_image).convert_alpha() #载入低级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy1_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down1.png").convert_alpha() #低级敌机撞到爆炸第1张图片
self.enemy1_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down2.png").convert_alpha() #低级敌机撞到爆炸第2张图片
self.enemy1_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1_down3.png").convert_alpha() #低级敌机撞到爆炸第3张图片
self.enemy1_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = 8
def __init__(self,bg_size,enemy2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy2_image = enemy2_image
self.enemy2 = pygame.image.load(enemy2_image).convert_alpha() #载入中级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy2_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down1.png").convert_alpha() #中级敌机撞到爆炸第1张图片
self.enemy2_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down2.png").convert_alpha() #中级敌机撞到爆炸第2张图片
self.enemy2_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down3.png").convert_alpha() #中级敌机撞到爆炸第3张图片
self.enemy2_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2_down4.png").convert_alpha() #中级敌机撞到爆炸第4张图片
self.enemy2_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 8
self.rect.left , self.rect.top = [ randint(0 , self.width - self.rect.width ) ,\
randint(-10*self.height , 0) ] #在窗口的5倍之上的距离中产生飞机
class BigEnemy(pygame.sprite.Sprite): #定义我的大敌机类,继承自动画精灵
energy = 20
def __init__(self,bg_size,enemy3_n1_image,enemy3_n2_image):
pygame.sprite.Sprite.__init__(self)
self.enemy3_n1_image = enemy3_n1_image
self.enemy3_n1 = pygame.image.load(enemy3_n1_image).convert_alpha() #载入高级敌机照片
self.enemy3_n2_image = enemy3_n1_image
self.enemy3_n2 = pygame.image.load(enemy3_n2_image).convert_alpha() #载入高级敌机照片
#添加坠机图片
self.destroy_images = []
self.enemy3_down1_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down1.png").convert_alpha() #高级敌机撞到爆炸第1张图片
self.enemy3_down2_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down2.png").convert_alpha() #高级敌机撞到爆炸第2张图片
self.enemy3_down3_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down3.png").convert_alpha() #高级敌机撞到爆炸第3张图片
self.enemy3_down4_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down4.png").convert_alpha() #高级敌机撞到爆炸第4张图片
self.enemy3_down5_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down5.png").convert_alpha() #高级敌机撞到爆炸第5张图片
self.enemy3_down6_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_down6.png").convert_alpha() #高级敌机撞到爆炸第6张图片
self.enemy3_hit_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
self.energy = 20
self.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 = position
self.active = True
class Bullet2(pygame.sprite.Sprite):
def __init__(self,bullet2_image,position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(bullet2_image).convert_alpha()
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = position
self.speed = 14
self.active = False
self.mask = pygame.mask.from_surface(self.image)
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 = position
self.active = True
"""\/\/\/\/\/\/\/\/------补给类------\/\/\/\/\/\/\/\/"""
class Bullet_Supply(pygame.sprite.Sprite):
def __init__(self,bg_size) :
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet_supply.png").convert_alpha() #补给子弹图
self.rect = self.image.get_rect()
self.width , self.height = bg_size[0] ,bg_size[1]
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100 #随机生成补给的位置
self.speed = 5 #补给下落的速度
self.active = False #补给是否激活
self.mask = pygame.mask.from_surface(self.image)
def move (self) : #运动函数
if self.rect.top < self.height :
self.rect.top += self.speed
else :
self.active = False
def reset(self): #重置函数
self.active = True
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100
class Bomb_Supply(pygame.sprite.Sprite):
def __init__(self,bg_size) :
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb_supply.png").convert_alpha() #全屏炸弹补给图
self.rect = self.image.get_rect()
self.width , self.height = bg_size[0] ,bg_size[1]
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100 #随机生成补给的位置
self.speed = 5 #补给下落的速度
self.active = False #补给是否激活
self.mask = pygame.mask.from_surface(self.image)
def move (self) : #运动函数
if self.rect.top < self.height :
self.rect.top += self.speed
else :
self.active = False
def reset(self): #重置函数
self.active = True
self.rect.left ,self.rect.top = randint(0,self.width-self.rect.width) , -100
def main() :
pygame.init() #初始化
pygame.mixer.init() #混音器初始化
clock = pygame.time.Clock() #设置一个计时器
transform = False #设置一个是否改变的变量
delay = 100 #类似于单片机,设置一个延时变量,让飞机的改变看起来更加的顺滑
switch_image = True # 用于切换图片
running = True
#创建字体的标志
font = pygame.font.Font(r"C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf",35)
#初始化分数
score = 0
score_font = pygame.font.Font(r"C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf", 36)
#初始化我方飞机数量,生命为3条
life_num = 3
#设置难度等级
level = 1
black = ([0,0,0]) #黑色
green = ([0,255,0]) #绿色
red = ([255,0,0]) #红色
white = ([255,255,255]) #白色
"""载入音乐文件"""
#背景音乐
pygame.mixer.music.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\game_music.ogg") #设置背景音乐
pygame.mixer.music.set_volume(1) #设置音量
#游戏音效
bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\bullet.wav") #子弹特效
bullet_sound.set_volume(0.5)
button_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\button.wav") #按键特效
button_sound.set_volume(0.5)
enemy1_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy1_down.wav") #低等敌机被击毁音效
enemy1_down_sound.set_volume(0.5)
enemy2_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy2_down.wav") #中等敌机被击毁音效
enemy2_down_sound.set_volume(0.5)
enemy3_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_down.wav") #高等敌机被击毁音效
enemy3_down_sound.set_volume(0.5)
enemy3_fly_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\enemy3_flying.wav") #高等敌机出现音效
enemy3_fly_sound.set_volume(0.5)
get_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bomb.wav") #获得全屏炸弹补给音效
get_bomb_sound.set_volume(0.5)
get_bullet_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\get_bullet.wav") #获得双倍子弹补给音效
get_bullet_sound.set_volume(0.5)
myself_down_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\me_down.wav") #自身飞机被击毁(死亡)音效
myself_down_sound.set_volume(0.5)
supply_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\supply.wav") #补给产生音效
supply_sound.set_volume(0.5)
upgrade_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\upgrade.wav") #升级音效
upgrade_sound.set_volume(0.5)
use_bomb_sound = pygame.mixer.Sound( r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\sound\use_bomb.wav") #使用全屏炸弹音效
use_bomb_sound.set_volume(0.5)
"""图片文件路径"""
background_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\background.png" #背景图的路径
bullet1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet1.png" #第一种子弹图
bullet2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bullet2.png" #第二种子弹图
enemy1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy1.png" #低级敌机图片
enemy2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy2.png" #中级敌机图片
enemy3_n1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n1.png" #高级敌机图片1
enemy3_n2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\enemy3_n2.png" #高级敌机图片2
me1_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\me1.png" #自身飞机第一张图片
me2_image = r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\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 = False
pause_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_nor.png" ).convert_alpha() #暂停的时候图片
pause_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\pause_pressed.png" ).convert_alpha() #暂停到继续的中间变换图
resume_nor_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_nor.png").convert_alpha() #继续的时候的图片
resume_pressed_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\resume_pressed.png" ).convert_alpha() #继续到暂停的中间变换图
paused_rect = pause_nor_image.get_rect()
paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10
paused_image = pause_nor_image
#补给包
bullet_supply = Bullet_Supply(bg_size)
bomb_supply = Bomb_Supply(bg_size)
supply_timer = USEREVENT
pygame.time.set_timer(supply_timer,30000) #设定自定义事件每隔30s返回一个用户自定义事件属性
#超级子弹定时器
double_bullet_timer = USEREVENT + 1
# 标志是否使用超级子弹
is_double_bullet = False
# 全屏炸弹
bomb_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\bomb.png").convert_alpha()
bomb_rect = bomb_image.get_rect()
bomb_font = pygame.font.Font(r"C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf", 48)
bomb_num = 3
#载入生命图片
life_image =pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\life.png").convert_alpha() #表示生命值的图片
life_image_rect = life_image.get_rect()
#中弹图片索引
e1_destroy_index = 0
e2_destroy_index = 0
e3_destroy_index = 0
myself_destroy_index = 0
#生成自己飞机
myself = MyPlane(bg_size,me1_image,me2_image)
#无敌时间计时器
myself_invincible_timer = USEREVENT + 2
pygame.time.set_timer(myself_invincible_timer, 3*1000) #3秒
#创建子弹
bullet1 = [] #创建一个子弹列表
bullet1_index = 0 #创建一个搜索子弹的下标
bullet1_num = 4 #一次性创建子弹的数量
for i in range (bullet1_num) : #循环生成子弹
bullet1.append(Bullet1(bullet1_image,myself.rect.midtop)) #使用子弹类生成子弹
# 生成超级子弹
bullet2 = []
bullet2_index = 0
bullet2_num = 8
for i in range(bullet2_num//2):
bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx-33, myself.rect.centery)))
bullet2.append(Bullet2(bullet2_image,(myself.rect.centerx+30, myself.rect.centery)))
#生成敌机组
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) #生成大型飞机
# 用于阻止重复打开记录文件
recorded = False
#结束的全部东西
gameover_font = pygame.font.Font(r"C:\Users\96326\Desktop\ALL\Code\python_code\font\font.ttf", 48)
again_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\again.png" ).convert_alpha()
again_rect = again_image.get_rect()
gameover_image = pygame.image.load(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\images\gameover.png").convert_alpha()
gameover_rect = gameover_image.get_rect()
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标志键变为True
if paused_rect.collidepoint(event.pos): #让暂停图标在鼠标按下时立即改变
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
screen.blit(paused_image,(width - paused_rect.width,5)) #绘制此时的暂停按钮
if paused : #如果暂停了
pygame.time.set_timer(supply_timer,0)
pygame.mixer.music.pause()
pygame.mixer.pause()
else :
pygame.time.set_timer(supply_timer,30000)
pygame.mixer.music.unpause()
pygame.mixer.unpause()
elif event.type == MOUSEMOTION: #鼠标是否移动到暂停照片上显示不同的图片
if paused_rect.collidepoint(event.pos):
if paused:
paused_image = resume_pressed_image
else:
paused_image = pause_pressed_image
else:
if paused:
paused_image = resume_nor_image
else:
paused_image = pause_nor_image
elif event.type == KEYDOWN :
if event.key == K_SPACE: #如果按下空格键,投放超级炸弹
if bomb_num : #如果还有超级炸弹,那么炸弹数量-1
bomb_num -= 1
use_bomb_sound.play()
for each in enemies:
if each.rect.bottom > 0:
each.active = False
if event.key == K_0 : #如果按下0键
bomb_num += 1
elif event.type == supply_timer : #响应补给包事件
supply_sound.play() #播放补给的声音
if choice([True,False]) : #随机生成子弹补给或者炸药补给
bullet_supply.reset()
else :
bomb_supply.reset()
elif event.type == double_bullet_timer: #响应超级子弹事件
is_double_bullet = False
pygame.time.set_timer(double_bullet_timer, 0)
elif event.type == myself_invincible_timer: #响应无敌事件
myself.invincible = False
# 根据用户的得分增加难度
if level == 1 and score > 50000:
level = 2
upgrade_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 = 3
upgrade_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(middleenemies, 1)
elif level == 3 and score > 600000:
level = 4
upgrade_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(middleenemies, 1)
elif level == 4 and score > 1000000:
level = 5
upgrade_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) # 根据用户的得分增加难度
if level == 1 and score > 50000:
level = 2
upgrade_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 = 3
upgrade_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(middleenemies, 1)
elif level == 3 and score > 600000:
level = 4
upgrade_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(middleenemies, 1)
elif level == 4 and score > 1000000:
level = 5
upgrade_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)
#如果没有暂停
if life_num and not paused:
screen.blit(background,(0,0)) #绘制背景
#检查是否有上下左右或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() #飞船向右飞行
#绘制暂停和继续按钮
screen.blit(paused_image,(width - paused_rect.width,5)) #绘制暂停按钮
#绘制我方飞机
if life_num :
# 绘制大型敌机
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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 6
if 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.energy
if energy_remain > 0.2:
energy_color = green
else:
energy_color = red
pygame.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) % 4
if 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) % 4
if 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) % 4
if myself_destroy_index == 0:
life_num -= 1
myself.reset()
#绘制从飞机中出现的子弹
if not (delay % 10) : #设置每10帧射出一个子弹
bullet_sound.play()
if is_double_bullet:
bullets = bullet2
bullets[bullet2_index].reset((myself.rect.centerx-33, myself.rect.centery))
bullets[bullet2_index+1].reset((myself.rect.centerx+30, myself.rect.centery))
bullet2_index = (bullet2_index + 2) % bullet2_num
else:
bullets = bullet1
bullet1[bullet1_index].reset(myself.rect.midtop) #将子弹的坐标初放到飞机的前面
bullet1_index = (bullet1_index + 1) % bullet1_num #使子弹的下标始终处于0-4间不断循环
score_text = font.render('score = %s' %str(score),True,white) #绘制分数
screen.blit(score_text,(10,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 life_num :
for i in range(life_num):
screen.blit(life_image,(width-((i+1)*life_image_rect.width) , height - 5- life_image_rect.height))
#检测子弹是否击中敌机
for b in bullets: #对于列表中的的所有子弹
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 #生命值-1
if e.energy == 0 : #如果生命值变为0
e.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那么重新调回100
delay = 100
delay -= 1
#检查双方飞机是否发生碰撞
if not myself.invincible :
enemies_down = pygame.sprite.spritecollide(myself, enemies, False,collided=pygame.sprite.collide_mask) #将所有与我们的飞机发生碰撞的敌方飞机都加入到组中
if enemies_down: #如果组中有成员,说明又发生碰撞
myself.active = False #我放飞机存活状态变成False
for e in enemies_down:
e.active = False #对于与我相撞的飞机的也设为False
#绘制全屏炸弹补给并检测是否发生碰撞
if bomb_supply.active : #如果炸弹补给是激活的
bomb_supply.move() #补给移动
supply_sound.play() #播放炸弹补给出现音乐
screen.blit(bomb_supply.image,bomb_supply.rect) #绘制补给图片
if pygame.sprite.collide_mask(bomb_supply,myself): #检测补给和我放飞机是否发送碰撞
bomb_supply.active = False #如果发生碰撞,那么补给变为未激活状态
get_bomb_sound.play()#播放得到补给的音效
if bomb_num < 3: #如果炸弹数小于3
bomb_num += 1 #炸弹数+1
#绘制子弹补给并检测是否发生碰撞
if bullet_supply.active : #如果子弹补给是激活的
bullet_supply.move() #补给移动
screen.blit(bullet_supply.image,bullet_supply.rect) #绘制补给图片
if pygame.sprite.collide_mask(bullet_supply,myself): #检测补给和我放飞机是否发送碰撞
bullet_supply.active = False #如果发生碰撞,那么补给变为未激活状态
get_bullet_sound.play()#播放得到补给的音效
# 绘制超级子弹补给并检测是否获得
if bullet_supply.active:
bullet_supply.move()
screen.blit(bullet_supply.image, bullet_supply.rect)
if pygame.sprite.collide_mask(bullet_supply, myself):
get_bullet_sound.play()
#发射超级子弹18秒
is_double_bullet = True
pygame.time.set_timer(double_bullet_timer, 18 * 1000)
bullet_supply.active = False
elif life_num and paused : #如果暂停了
pygame.mixer.music.pause() #暂停背景音乐
screen.blit(background,(0,0)) #绘制背景
#绘制暂停和继续按钮
screen.blit(paused_image,(width - paused_rect.width,5)) #绘制暂停按钮
# 绘制游戏结束画面
elif life_num == 0:
# 背景音乐停止
pygame.mixer.music.stop()
# 停止全部音效
pygame.mixer.stop()
# 停止发放补给
pygame.time.set_timer(supply_timer, 0)
if not recorded:
recorded = True
# 读取历史最高得分
with open(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\record.txt", "r") as f:
record_score = int(f.read())
# 如果玩家得分高于历史最高得分,则存档
if score > record_score:
with open(r"C:\Users\96326\Desktop\ALL\Code\python_code\我自己写的代码.QAQ\plane\record.txt", "w") as f:
f.write(str(score))
screen.blit(background,(0,0)) #绘制背景
# 绘制结束画面
record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255))
screen.blit(record_score_text, (50, 50))
gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255))
gameover_text1_rect = gameover_text1.get_rect()
gameover_text1_rect.left, gameover_text1_rect.top = \
(width - gameover_text1_rect.width) // 2, height // 3
screen.blit(gameover_text1, gameover_text1_rect)
gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255))
gameover_text2_rect = gameover_text2.get_rect()
gameover_text2_rect.left, gameover_text2_rect.top = \
(width - gameover_text2_rect.width) // 2, \
gameover_text1_rect.bottom + 10
screen.blit(gameover_text2, gameover_text2_rect)
again_rect.left, again_rect.top = \
(width - again_rect.width) // 2, \
gameover_text2_rect.bottom + 50
screen.blit(again_image, again_rect)
gameover_rect.left, gameover_rect.top = \
(width - again_rect.width) // 2, \
again_rect.bottom + 10
screen.blit(gameover_image, gameover_rect)
# 检测用户的鼠标操作
# 如果用户按下鼠标左键
if pygame.mouse.get_pressed()[0]:
# 获取鼠标坐标
pos = pygame.mouse.get_pos()
# 如果用户点击“重新开始”
if again_rect.left < pos[0] < again_rect.right and \
again_rect.top < pos[1] < again_rect.bottom:
# 调用main函数,重新开始游戏
main()
# 如果用户点击“结束游戏”
elif gameover_rect.left < pos[0] < gameover_rect.right and \
gameover_rect.top < pos[1] < gameover_rect.bottom:
# 退出游戏
pygame.quit()
sys.exit()
pygame.display.flip() #不停的刷新画面,不停的绘画
clock.tick(60) #设置帧率
if __name__ == "__main__":
# 这样做的好处是双击打开时如果出现异常可以报告异常,而不是一闪而过!
try:
main()
except SystemExit: #这是按下 × 的异常,直接忽略
pass
except:
traceback.print_exc()
pygame.quit()
input()