Python

2018-08-05 微信打飞机游戏

2018-08-05  本文已影响82人  这是何等的卧槽__

本文使用了sprite模块提供的碰撞检测函数

pygame.sprite.collide_circle_ratio(参数1)(sprite_1,sprite_2):检测两个精灵是否碰撞,两个精灵视为圆形。参数1指定检测圆形的百分比。

例:敌机与玩家飞机的碰撞

pygame.sprite.spritecollide(sprite,sprite_group,bool)。调用这个函数的时候,一个组中的所有精灵都会逐个地对另外一个单个精灵进行冲突检测,发生冲突的精灵会作为一个列表返回。

例:玩家飞机子弹与敌机的碰撞(因为有的飞机难以打死,就把敌机作为一个精灵而非精灵组)

pygame.sprite.groupcollide()。利用这个函数可以检测两个组之间的冲突,他返回一个字典。(键-值对)

例:玩家飞机子弹与敌机子弹的碰撞、玩家飞机与敌机组的碰撞

遇到的最大难点是敌方飞机死后,留在屏幕上的子弹应该继续移动直到屏幕底部,而非直接消失

步骤大约如下:

1、实现游戏窗口并显示
2、绘制背景图片到窗口
3、绘制一张飞机图片到界面上
4、移动飞机(通过键盘去控制)
5、实现飞机动画效果
6、实现飞机移动
7、绘制子弹并移动子弹
8、绘制敌方飞机1(随机生成,按一定频率生成)
9、实现敌方飞机1移动
10、实现子弹精灵组与敌机精灵组的碰撞
11、实现敌机精灵组与玩家精灵的碰撞(结束该游戏)
12、添加敌机2、敌机3(重复8-11)
13、敌机2、敌机3发射子弹(双方子弹碰撞检测、敌机子弹与玩家的碰撞检测)
14、绘制得分(给最高分存档)
15、加载各种音乐

all_class.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# @Time    : 2018/8/4 9:52
# @Author  : helei
# @Email   : 1982540042@qq.com
# @File    : all_class.py
# @Software: pycharm

import pygame

"""
此模块存放我方飞机、敌方飞机、以及双方子弹的类
"""


class Bullet(pygame.sprite.Sprite):
    """玩家飞机的子弹类,继承精灵类"""

    def __init__(self, bullet_image, init_pos):
        """第一个参数是子弹的图片,第二个参数是子弹出现的坐标"""
        super().__init__()
        self.image = bullet_image
        """创建一个子弹矩阵"""
        self.rect = self.image.get_rect()
        """子弹图片的中底部作为子弹的坐标"""
        self.rect.midbottom = init_pos
        self.speed = 10

    def move(self):
        self.rect.top -= self.speed


class Bullet2(pygame.sprite.Sprite):
    """敌方飞机的子弹类,继承精灵类"""

    def __init__(self, bullet_image, init_pos):
        """第一个参数是子弹的图片,第二个参数是子弹出现的坐标"""
        super().__init__()
        self.image = bullet_image
        """创建一个子弹矩阵"""
        self.rect = self.image.get_rect()
        """子弹图片的中底部作为子弹的坐标"""
        self.rect.midtop = init_pos
        self.speed = 3

    def move(self):
        self.rect.top += self.speed


class Player(pygame.sprite.Sprite):
    """我方飞机类,继承精灵类"""

    def __init__(self, player_list, init_pos):
        """
        第一个参数是存放飞机的列表,
        第二个参数是飞机的初始坐标
        """
        super().__init__()
        self.images = player_list  # 飞机的各种图片的列表
        """创建一个飞机的矩阵"""
        self.rect = player_list[0].get_rect()
        """飞机的左上角作为飞机的坐标"""
        self.rect.topleft = init_pos

        self.speed = 10  # 初始化玩家飞机速度,这里是一个确定的值
        self.img_index = 0  # 第一张图片作为飞机的初始状态
        self.is_hit = False  # 默认玩家飞机是存活状态
        self.bullets = pygame.sprite.Group()  # 玩家飞机所发射的子弹的集合

    def shoot(self, bullet_image):
        """发射子弹就是创建一个子弹对象"""
        bullet = Bullet(bullet_image, self.rect.midtop)
        bullet2 = Bullet(bullet_image, self.rect.midleft)
        bullet3 = Bullet(bullet_image, self.rect.midright)
        """第一个参数是加载子弹图片,第二个参数是把让子弹出现在飞机的中上\中左\中右"""
        self.bullets.add(bullet)
        self.bullets.add(bullet2)
        self.bullets.add(bullet3)

    """飞机的移动以及边界检测"""

    def moveup(self):
        """向上移动"""
        if self.rect.top <= 0:
            self.rect.top = 0  # 如果飞机移到顶部,则令飞机的纵坐标为0
        else:
            self.rect.top -= self.speed

    def movedown(self):
        """向下移动"""
        if self.rect.top >= 700 - self.rect.height:
            self.rect.top = 700 - self.rect.height  # 如果飞机移到底部,则飞机的纵坐标= 屏幕高度 - 飞机本身的高
        else:
            self.rect.top += self.speed

    def moveleft(self):
        """向左移动"""
        if self.rect.left <= 0:
            self.rect.left = 0  # 如果飞机移到最左端,则令飞机的横坐标为0
        else:
            self.rect.left -= self.speed

    def moveright(self):
        """向右移动"""
        if self.rect.left >= 480 - self.rect.width:
            self.rect.left = 480 - self.rect.width  # 如果飞机移到最右端,则飞机的横坐标= 屏幕宽度 - 飞机本身的宽
        else:
            self.rect.left += self.speed


class Enemy(pygame.sprite.Sprite):
    """
   enemy_image  敌机图片
   enemy_down_imgs    敌机被摧毁的图片
   init_pos    敌机的初始位置
   """

    def __init__(self, enemy_image, enemy_down_images, init_pos):
        super().__init__()
        self.image = enemy_image
        """创建敌机的矩阵"""
        self.rect = self.image.get_rect()
        """以敌机的左上部作为敌机的初始坐标"""
        self.rect.topleft = init_pos  # 敌机初始坐标
        self.down_images = enemy_down_images  # 存放动画效果
        self.speed = 5
        self.down_index = 0  # 对应动画图片的索引,从0开始

        # self.is_hit = False
        self.bullets = pygame.sprite.Group()  # 敌机所发射的子弹的集合

    def shoot(self, bullet_image):
        """发射子弹就是创建一个子弹对象"""
        bullet = Bullet2(bullet_image, self.rect.midbottom)
        """第一个参数是加载子弹图片,第二个参数是让子弹出现在敌机的中下方"""
        self.bullets.add(bullet)


    def move(self):
        self.rect.top += self.speed

if __name__ == '__main__':
    pass

all_data.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# @Time    : 2018/8/4 19:39
# @Author  : helei
# @Email   : 1982540042@qq.com
# @File    : all_data.py
# @Software: pycharm

"""该模块存放的是准备工作"""
import pygame
from all_class import *
pygame.init()
pygame.mixer.init()    # 初始化音乐环境

"""加载音乐"""
pygame.mixer.music.load(r"..\周末作业素材\微信打飞机资源\sound\game_music.mp3")  # 背景音乐
pygame.mixer.music.set_volume(0.3)  # 设置音量
pygame.mixer.music.play()

shoot_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\bullet.wav")      # 发射子弹的音乐
shoot_music.set_volume(0.2)
enemy1_down_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\enemy1_down.wav") # 敌机1被毁时的音乐
enemy1_down_music.set_volume(0.2)
enemy2_down_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\enemy2_down.wav") # 敌机2被毁时的音乐
enemy2_down_music.set_volume(0.3)
enemy3_down_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\enemy3_down.wav") # 敌机3被毁时的音乐
enemy1_down_music.set_volume(0.4)
game_over_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\game_over.wav")   # 游戏结束时的音乐
enemy1_down_music.set_volume(0.2)
break_record_music = pygame.mixer.Sound(r"..\周末作业素材\微信打飞机资源\sound\achievement.wav") # 打破记录后的音乐
break_record_music.set_volume(0.4)



screen_width = 480
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))  # 绘制屏幕大小
pygame.display.set_caption('微信打飞机!')
# 加载背景图片
back_ground = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\background.png')
# 加载 gameover 背景图片
game_over = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\game_over.png')

"""图片专用组"""
# 加载我方飞机的各种图片
hero1_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero1.png')
hero2_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero2.png')
hero_blowup_n1_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero_blowup_n1.png')
hero_blowup_n2_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero_blowup_n2.png')
hero_blowup_n3_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero_blowup_n3.png')
hero_blowup_n4_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\hero_blowup_n4.png')

# 存放我方飞机的各种图片,用于实现动画效果
hero_list = []
hero_list.append(hero1_image)
hero_list.append(hero2_image)
hero_list.append(hero_blowup_n1_image)
hero_list.append(hero_blowup_n2_image)
hero_list.append(hero_blowup_n3_image)
hero_list.append(hero_blowup_n4_image)


# 加载敌方飞机1的各种图片
enemy1_5 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy1_5.png')
enemy1_4 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy1_4.png')
enemy1_3 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy1_3.png')
enemy1_2 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy1_2.png')
enemy1_1 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy1_1.png')

# 存放敌机1的爆炸效果所对应的图片
enemy1_down_images = []
enemy1_down_images.append(enemy1_4)
enemy1_down_images.append(enemy1_3)
enemy1_down_images.append(enemy1_2)
enemy1_down_images.append(enemy1_1)

# 加载敌方飞机2的各种图片
enemy2_live =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2.png')
enemy2_hit =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2_hit.png')
enemy2_down1 =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2_down1.png')
enemy2_down2 =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2_down2.png')
enemy2_down3 =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2_down3.png')
enemy2_down4 =pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy2_down4.png')

# 存放敌机2的爆炸效果所对应的图片
enemy2_down_images = []
enemy2_down_images.append(enemy2_hit)
enemy2_down_images.append(enemy2_down1)
enemy2_down_images.append(enemy2_down2)
enemy2_down_images.append(enemy2_down3)
enemy2_down_images.append(enemy2_down4)

# 加载敌方飞机3的各种图片
enemy3_n1 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_n1.png')
enemy3_n2 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_n2.png')
enemy3_down1 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down1.png')
enemy3_down2 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down2.png')
enemy3_down3 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down3.png')
enemy3_down4 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down4.png')
enemy3_down5 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down5.png')
enemy3_down6 = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\enemy3_down6.png')

# 存放敌机3的爆炸效果图片
enemy3_down_images = []
enemy3_down_images.append(enemy3_down1)
enemy3_down_images.append(enemy3_down2)
enemy3_down_images.append(enemy3_down3)
enemy3_down_images.append(enemy3_down4)
enemy3_down_images.append(enemy3_down5)
enemy3_down_images.append(enemy3_down6)

"""子弹专用组"""
# 加载我方飞机子弹图片
bullet1_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\bullet1.png')
bullet2_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\bullet2.png')
bullet3_image = pygame.image.load(r'..\周末作业素材\微信打飞机资源\image\bomb.png')


"""敌机矩阵专用组 目的是绘制敌机随机出现的坐标范围,然后创建敌机的对象"""
enemy1_rect = enemy1_5.get_rect() # 创建一个敌机1的矩阵
enemy2_rect = enemy2_down1.get_rect() # 创建一个敌机2的矩阵
enemy3_rect = enemy3_down1.get_rect() # 创建一个敌机3的矩阵


"""这里是精灵专用组"""

"""敌机1精灵组 该精灵组是用来存放所有生成的敌机1"""
enemies1_goup = pygame.sprite.Group()
"""敌机1被毁精灵组 该精灵组是存储被玩家击中的飞机1用来渲染爆炸效果"""
enemies1_down_goup = pygame.sprite.Group()


"""敌机2精灵组 该精灵组是用来存放所有生成的敌机2"""
enemies2_goup = pygame.sprite.Group()
"""敌机2被毁精灵组 该精灵组是存储被玩家击中的飞机1用来渲染爆炸效果"""
enemies2_down_goup = pygame.sprite.Group()

"""敌机3精灵组 该精灵组是用来存放所有生成的敌机3"""
enemies3_goup = pygame.sprite.Group()
"""敌机3被毁精灵组 该精灵组是存储被玩家击中的飞机1用来渲染爆炸效果"""
enemies3_down_goup = pygame.sprite.Group()


"""这是当玩家飞机被击中,或者撞毁时开始计算动画效果的下标"""
player_down_index = 16  # 从下标为2(也就是第3张图片)开始取一共取到下标为5(第6张图片)

if __name__ == '__main__':
    pass

maingame.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# @Time    : 2018/8/4 8:58
# @Author  : helei
# @Email   : 1982540042@qq.com
# @File    : maingame.py
# @Software: pycharm

import pygame
import random
from pygame.locals import *
from all_class import *
from all_data import *

"""这里是精灵专用  目的是若击毁了敌机,但是目前正在屏幕上的敌机子弹依然会移动,直到屏幕后才消失"""
e2_bullets_group = pygame.sprite.Group()
e3_bullets_group = pygame.sprite.Group()

"""这里是频率专用组"""
# 记录飞机的闪动状态
plane_count = 0

# 记录玩家飞机子弹的发射频率
player_shoot_frequency = 0
# 记录敌机2子弹的发射频率
enemy2_shoot_frequency = 0
# 记录敌机3子弹的发射频率
enemy3_shoot_frequency = 0

# 记录敌机1的生成频率
enemy1_frequency = 0
# 记录敌机2的生成频率
enemy2_frequency = 0
# 记录敌机3的生成频率
enemy3_frequency = 0

# 飞机的初始坐标
plane_pos = [200, 400]
# 创建一个玩家飞机对象
player = Player(hero_list, plane_pos)

"""初始化分数"""
score = 0
"""读取历史最高分数"""
try:
    with open('highestscore.txt', 'r', encoding='utf-8') as f_object:
        highest_score = f_object.read()
except FileNotFoundError:
    with open('highestscore.txt', 'w', encoding='utf-8') as f_object:
        highest_score = 0
        f_object.write(str(highest_score))
else:
    highest_score = int(highest_score)

"""敌机的状态"""
is_enemy1 = True
is_enemy2 = False
is_enemy3 = False
break_record = False  # 判断是否打破记录
clock = pygame.time.Clock()  # 设置帧率
isrunning = True
while isrunning:

    # 绘制背景 相当于重新取一张画板
    screen.blit(back_ground, (0, 0))

    """这里是频率专用组"""
    plane_count += 1
    """控制各种飞机发射子弹的频率"""
    player_shoot_frequency += 1
    enemy2_shoot_frequency += 1
    enemy3_shoot_frequency += 1
    """敌机出现的频率"""
    enemy1_frequency += 1
    enemy2_frequency += 1
    enemy3_frequency += 1

    # 1.--------------------------------------------------------------------------------------------------------------------------
    """第一阶段"""
    if is_enemy1:
        """随机生成敌机1"""
        if enemy1_frequency > 99:
            enemy1_frequency = 0
        if enemy1_frequency % 50 == 0:  # 控制敌机1的出现频率
            enemy1_pos = (random.randint(enemy1_rect.width, 480 - enemy1_rect.width), 0)
            # 创建敌机1的对象
            enemy1 = Enemy(enemy1_5, enemy1_down_images, enemy1_pos)
            enemies1_goup.add(enemy1)

        """敌机1移动"""
        for enemy1 in enemies1_goup:
            enemy1.move()
            """消除屏幕之外的敌机"""
            if enemy1.rect.top > 700:
                enemies1_goup.remove(enemy1)
            # 敌机与玩家飞机碰撞效果处理
            """敌机1与玩家的碰撞检测"""
            """敌机精灵与玩家精灵的碰撞"""
            # if pygame.sprite.collide_circle(enemy1, player):
            if pygame.sprite.collide_circle_ratio(0.8)(enemy1, player):
                enemies1_down_goup.add(enemy1)  # 放入敌机被击毁精灵组
                enemies1_goup.remove(enemy1)  # 敌机精灵组移除该精灵
                player.is_hit = True
                break

    # 2.-----------------------------------------------------------------------------------------------------------------------------
    """第二阶段"""
    if is_enemy2:
        """随机生成敌机2"""
        if enemy2_frequency > 590:
            enemy2_frequency = 0
        if enemy2_frequency % 200 == 0:  # 控制敌机2的出现频率
            enemy2_pos = (random.randint(enemy2_rect.width, 480 - enemy2_rect.width), 0)
            # 创建敌机2的对象
            enemy2 = Enemy(enemy2_live, enemy2_down_images, enemy2_pos)
            """设置敌机2的速度"""
            enemy2.speed = 2
            enemy2.is_live = True  # 设置敌机2的存活状态
            enemy2.hit_count = 0  # 设置敌机2的被击次数
            enemy2.score = 1000  # 飞机2的分值
            enemies2_goup.add(enemy2)

        """敌机2移动"""
        for enemy2 in enemies2_goup:

            """控制敌机2的射击频率"""
            if enemy2_shoot_frequency > 100:
                enemy2_shoot_frequency = 0
            if enemy2_shoot_frequency % 60 == 0:  # 控制敌机2的射击频率
                enemy2.shoot(bullet2_image)
            enemy2.move()
            """消除屏幕之外的敌机"""
            if enemy2.rect.top > 700:
                enemies2_goup.remove(enemy2)

            # 敌机与玩家飞机碰撞效果处理
            """敌机2与玩家的碰撞检测"""
            """敌机精灵与玩家精灵的碰撞"""
            # if pygame.sprite.collide_circle(enemy2, player):
            if pygame.sprite.collide_circle_ratio(0.7)(enemy2, player):
                enemies2_down_goup.add(enemy2)  # 放入敌机被击毁精灵组
                enemies2_goup.remove(enemy2)  # 敌机精灵组移除该精灵
                player.is_hit = True  # 玩家被撞毁

            for bullet in enemy2.bullets:
                # 以固定速度移动子弹
                bullet.move()
                # 移动出屏幕后删除子弹
                if bullet.rect.top > 700:
                    enemy2.bullets.remove(bullet)
            enemy2.bullets.draw(screen)

            # 玩家飞机被敌机2击中的效果:
            if pygame.sprite.spritecollide(player, enemy2.bullets, True):
                player.is_hit = True  # 玩家被撞毁

            # 敌机2子弹与玩家飞机子弹的碰撞效果处理
            pygame.sprite.groupcollide(enemy2.bullets, player.bullets, 1, 1)
    # 3 -------------------------------------------------------------------------------------------------------------------------------
    """第三阶段"""
    if is_enemy3:
        """随机生成敌机3"""
        if enemy3_frequency > 1790:
            enemy3_frequency = 0
        if enemy3_frequency % 600 == 0:  # 控制敌机3的出现频率
            enemy3_pos = (random.randint(enemy3_rect.width, 480 - enemy3_rect.width), 0)
            # 创建敌机2的对象
            enemy3 = Enemy(enemy3_n1, enemy3_down_images, enemy3_pos)
            """设置敌机3的速度"""
            enemy3.speed = 1
            enemy3.is_live = True  # 设置敌机3的存活状态
            enemy3.hit_count = 0  # 设置敌机3的被击次数
            enemy3.score = 2000  # 飞机3的分值
            enemies3_goup.add(enemy3)

        """敌机3移动"""
        for enemy3 in enemies3_goup:
            """控制敌机3的射击频率"""
            if enemy3_shoot_frequency > 300:
                enemy3_shoot_frequency = 0
            if enemy3_shoot_frequency % 200 == 0:  # 控制敌机3的射击频率
                enemy3.shoot(bullet3_image)
            enemy3.move()
            """消除屏幕之外的敌机"""
            if enemy3.rect.top > 700:
                enemies3_goup.remove(enemy3)

            # 敌机与玩家飞机碰撞效果处理
            """敌机3与玩家的碰撞检测"""
            """敌机精灵与玩家精灵的碰撞"""
            # if pygame.sprite.collide_circle(enemy2, player):
            if pygame.sprite.collide_circle_ratio(0.7)(enemy3, player):
                enemies3_down_goup.add(enemy3)  # 放入敌机被击毁精灵组
                enemies3_goup.remove(enemy3)  # 敌机精灵组移除该精灵
                player.is_hit = True  # 玩家被撞毁

            # 玩家飞机被敌机3击中的效果:
            if pygame.sprite.spritecollide(player, enemy3.bullets, True):
                player.is_hit = True  # 玩家被撞毁

            # 敌机3子弹与玩家飞机子弹的碰撞效果处理
            pygame.sprite.groupcollide(enemy3.bullets, player.bullets, 1, 1)

            for bullet in enemy3.bullets:
                # 以固定速度移动子弹
                bullet.move()
                # 移动出屏幕后删除子弹
                if bullet.rect.top > 700:
                    enemy3.bullets.remove(bullet)
            enemy3.bullets.draw(screen)

    # end ------------------------------------------------------------------------------------------------------------------

    if plane_count >= 15:  # 控制玩家飞机的闪动频率
        plane_count = 0
    """判断玩家是否存活"""
    if not player.is_hit:
        """将玩家飞机绘制上去"""
        screen.blit(player.images[player.img_index], player.rect)
        # 更换图片索引使飞机有动画效果
        player.img_index = plane_count // 8

        """控制玩家飞机的射击频率"""
        if player_shoot_frequency > 100:
            player_shoot_frequency = 0
        if player_shoot_frequency % 15 == 0:  # 控制玩家飞机的射击频率
            player.shoot(bullet1_image)
            shoot_music.play()
    # 若玩家飞机被毁灭
    else:
        # 玩家飞机被击中后的效果处理
        """不用for是为了延缓玩家飞机的爆炸效果动图"""
        player.img_index = player_down_index // 8
        screen.blit(player.images[player.img_index], player.rect)
        player_down_index += 1
        if player_down_index > 47:
            # 击中效果处理完成后游戏结束
            game_over_music.play()  # 游戏结束音乐
            isrunning = False

    """将这个循环放在外面是因为飞机死了但是屏幕中剩余的子弹应该继续移动"""
    for bullet in player.bullets:
        # 以固定速度移动子弹
        bullet.move()
        # 移动出屏幕后删除子弹
        if bullet.rect.bottom < 0:
            player.bullets.remove(bullet)

    """碰撞检测专用组:"""
    # 1.--------------------------------------------------------------------------------------------------------------------------
    # 碰撞检测1
    # 敌机1被子弹击中效果处理
    # 将被击中的敌机1对象添加到击毁敌机 Group 中,用来渲染击毁动画
    """敌机1精灵组与玩家子弹精灵组的碰撞"""
    enemies1_down = pygame.sprite.groupcollide(enemies1_goup, player.bullets, 1, 1)
    for enemy_down in enemies1_down:
        enemies1_down_goup.add(enemy_down)  # 敌机1被击毁的精灵组
        score += 1000
        enemy1_down_music.play()  # 加载敌机1被击毁的音乐

    # 敌机被子弹击中动画效果显示
    for enemy1_down in enemies1_down_goup:  # 精灵组中的每个飞机依旧是一个对象,有爆炸效果组的属性
        if enemy1_down.down_index == len(enemy1_down.down_images):  # 如果取到了爆炸效果的最后一张图片预示爆炸效果结束,就移除该飞机
            enemies1_down_goup.remove(enemy1_down)
            continue
        screen.blit(enemy1_down.down_images[enemy1_down.down_index], enemy1_down.rect)  # 绘制每张爆炸图,形成爆炸效果
        enemy1_down.down_index += 1

    # 2.-------------------------------------------------------------------------------------------------------------------------
    # 碰撞检测2
    # 敌机2被子弹击中效果处理
    # 将被击中的敌机2对象添加到击毁敌机 Group 中,用来渲染击毁动画
    """敌机2精灵组与玩家子弹精灵组的碰撞"""

    for enemy2_hited in enemies2_goup:
        if pygame.sprite.spritecollide(enemy2_hited, player.bullets, True):
            enemy2_hited.hit_count += 1
        if enemy2_hited.hit_count >= 3:
            enemies2_goup.remove(enemy2_hited)
            score += enemy2_hited.score
            enemy2_down_music.play()  # 加载敌机2被击毁的音乐
            enemies2_down_goup.add(enemy2_hited)  # 敌机2被击毁的精灵组
        for bullet in enemy2_hited.bullets:
            e2_bullets_group.add(bullet)

    # 玩家飞机被敌机2击中的效果:
    if pygame.sprite.spritecollide(player, e2_bullets_group, True):
        """这是敌机2死后仍然存在的子弹"""
        player.is_hit = True  # 玩家被撞毁

    # 敌机2子弹与玩家飞机子弹的碰撞效果处理
    pygame.sprite.groupcollide(e2_bullets_group, player.bullets, 1, 1)

    # 敌机被子弹击中动画效果显示
    for enemy2_down in enemies2_down_goup:  # 精灵组中的每个飞机依旧是一个对象,有爆炸效果组的属性
        if enemy2_down.down_index == len(enemy2_down.down_images):  # 如果取到了爆炸效果的最后一张图片预示爆炸效果结束,就移除该飞机
            enemies2_down_goup.remove(enemy2_down)
            continue
        screen.blit(enemy2_down.down_images[enemy2_down.down_index], enemy2_down.rect)  # 绘制每张爆炸图,形成爆炸效果
        enemy2_down.down_index += 1

    # 3---------------------------------------------------------------------------------------------------------------------------
    # 碰撞检测3
    # 敌机3被子弹击中效果处理
    # 将被击中的敌机3对象添加到击毁敌机 Group 中,用来渲染击毁动画
    """敌机3精灵组与玩家子弹精灵组的碰撞"""

    for enemy3_hited in enemies3_goup:
        if pygame.sprite.spritecollide(enemy3_hited, player.bullets, True):
            enemy3_hited.hit_count += 1
        if enemy3_hited.hit_count >= 10:
            enemies3_goup.remove(enemy3_hited)
            score += enemy3_hited.score
            enemy3_down_music.play()  # 加载敌机3被击毁的音乐
            enemies3_down_goup.add(enemy3_hited)  # 敌机3被击毁的精灵组
        for bullet in enemy3_hited.bullets:
            e3_bullets_group.add(bullet)

    if pygame.sprite.spritecollide(player, e3_bullets_group, True):
        """这是敌机3死后仍然存在的子弹的碰撞检测"""
        player.is_hit = True  # 玩家被撞毁

    # 敌机3子弹与玩家飞机子弹的碰撞效果处理
    pygame.sprite.groupcollide(e3_bullets_group, player.bullets, 1, 1)


    # 敌机被子弹击中动画效果显示
    for enemy3_down in enemies3_down_goup:  # 精灵组中的每个飞机依旧是一个对象,有爆炸效果组的属性
        if enemy3_down.down_index == len(enemy3_down.down_images):  # 如果取到了爆炸效果的最后一张图片预示爆炸效果结束,就移除该飞机
            enemies3_down_goup.remove(enemy3_down)
            continue
        screen.blit(enemy3_down.down_images[enemy3_down.down_index], enemy3_down.rect)  # 绘制每张爆炸图,形成爆炸效果
        enemy3_down.down_index += 1

    # end ----------------------------------------------------------------------------------------------------------------------

    for bullet in e2_bullets_group:
        # 以固定速度移动子弹
        bullet.move()
        # 移动出屏幕后删除子弹
        if bullet.rect.top > 700:
            e2_bullets_group.remove(bullet)

    for bullet in e3_bullets_group:
        # 以固定速度移动子弹
        bullet.move()
        # 移动出屏幕后删除子弹
        if bullet.rect.top > 700:
            e3_bullets_group.remove(bullet)

    # 将所有子弹画到屏幕上去
    player.bullets.draw(screen)
    e2_bullets_group.draw(screen)
    e3_bullets_group.draw(screen)
    """将所有飞机一次性绘制到屏幕上去"""
    enemies1_goup.draw(screen)
    enemies2_goup.draw(screen)
    enemies3_goup.draw(screen)

    if score >= 10000:
        is_enemy2 = True
    if score >= 20000:
        is_enemy3 = True

    """绘制得分"""
    score_font = pygame.font.Font(r'..\font\HYShangWeiShouShuW.ttf', 36)
    score_text = score_font.render(str(score), True, (0, 0, 128))  # 第一个参数:显示的内容 第二个参数:是否开启抗锯齿 第三个参数:字体颜色
    text_rect = score_text.get_rect()
    text_rect.topleft = [480 - text_rect.width, 10]  # 得分情况显示在右上角
    screen.blit(score_text, text_rect)

    if score > highest_score:
        if not break_record:
            break_record_music.play()  # 打破记录时播放一次音乐
            break_record = True


    """绘制历史最高分"""
    highest_score_font = pygame.font.Font(r'..\font\HYShangWeiShouShuW.ttf', 36)
    highest_score_text = score_font.render(str(highest_score), True, (128, 0, 0))  # 第一个参数:显示的内容 第二个参数:是否开启抗锯齿 第三个参数:字体颜色
    highest_text_rect = highest_score_text.get_rect()
    highest_text_rect.topleft = [10, 10]  # 得分情况显示在右上角
    screen.blit(highest_score_text, highest_text_rect)

    #####################################################################
    #                                                                   #
    #                                                                   #
    #                                                                   #
    # ----------------------------霸屏--------------------------------- #
    #                                                                   #
    #                                                                   #
    #                                                                   #
    ######################################################################

    clock.tick(300)  # 设置屏幕的刷新速度(帧率)
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    # 键盘监听(控制飞机移动)
    key_pressed = pygame.key.get_pressed()
    if key_pressed[K_w] or key_pressed[K_UP]:
        player.moveup()
        pass
    if key_pressed[K_s] or key_pressed[K_DOWN]:
        player.movedown()
        pass
    if key_pressed[K_a] or key_pressed[K_LEFT]:
        player.moveleft()
        pass
    if key_pressed[K_d] or key_pressed[K_RIGHT]:
        # x += 10
        player.moveright()
        pass

# 游戏 Game Over 后显示最终得分
font = pygame.font.Font(r'..\font\HYShangWeiShouShuW.ttf', 50)
text = font.render('Score: ' + str(score), True, (0, 0, 255))
text_rect = text.get_rect()
# 最终得分的坐标
text_rect.centerx = screen.get_rect().centerx
text_rect.centery = screen.get_rect().centery + 50
screen.blit(game_over, (0, 0))
screen.blit(text, text_rect)

"""绘制历史最高分"""
if score > highest_score:
    highest_score = score
pygame.mixer.music.stop() # 结束音乐
font = pygame.font.Font(r'..\font\HYShangWeiShouShuW.ttf', 50)
highest_score_text = font.render('Score: ' + str(highest_score), True, (255, 0, 0))
highest_score_text_rect = highest_score_text.get_rect()
screen.blit(highest_score_text, (150, 20))
"""把历史最高分存档"""
with open('highestscore.txt', 'w') as f_object:
    f_object.write(str(highest_score))

# 显示得分并处理游戏退出
Game_over = True
while Game_over:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    pygame.display.update()  # 展示并更新画板上的内容

if __name__ == '__main__':
    pass

运行效果:

video1.gif
上一篇下一篇

猜你喜欢

热点阅读