二、飞机大战终极版-巩固面向对象设计项目的思想

上面一节主要介绍pygame入门,这一节是利用面向对象完成整个项目设计:子弹射击敌机,战机碰撞敌机,用户左右控制战机移动等等

 

1、知识点:pygame中提供了俩个非常强大的类精灵类和精灵组类:

          精灵类可以创建很多对象,例如:创建多个敌机,是用精灵类创建方便快速,代码简洁

   精灵组可以接受多个精灵类创建的对象,并且可以一次性将多个对象一次性绘制到屏幕

首先创建一个plane_sprites模块,所有创建的敌机精灵,战机精灵,子弹精灵等类都写在此文件:
import pygame
import random

"""pygame中提供了俩个非常强大的类精灵类和精灵组类
   精灵类可以创建很多对象,例如:创建多个敌机,是用精灵类创建方便快速,代码简洁
   精灵组可以接受多个精灵类创建的对象,并且可以一次性将多个对象一次性绘制到屏幕
"""
SCREEN=pygame.Rect(0,0,480,700)  # 屏幕大小常量
CREAT_EVENT=pygame.USEREVENT  # 定时器常量,这个用于向屏幕定时添加敌机
BULLET_EVENT = pygame.USEREVENT+1 # 这也是定时器常量,用于定时发射子弹。


class PlaneSprites(pygame.sprite.Sprite):
    """创建精灵类"""
    def __init__(self, image, speed=1):
        super().__init__()
        self.image = pygame.image.load(image)
        self.rect = self.image.get_rect()
        self.speed = speed



     #  重写update方法
    def update(self):
        self.rect.y += self.speed


"""制作背景滚动:方法就是需要俩张一摸一样的图片,一张位置放在覆盖屏幕,另外一张放在屏幕上方,一起向下移动时,
当第一张刚好移到屏幕最下方,第二张刚好覆盖屏幕,此时将第一张再放到屏幕上方,如此循环,看到的效果就是背景滚动了
提示:rect设置的矩形对象,xy值默认的是(0,0)
"""
class BackGround(PlaneSprites):
    def __init__(self,is_flag=False):
        super().__init__('./images/background.png')
        if is_flag:
            self.rect.y =-self.rect.height

    def update(self):
        super().update()
        if self.rect.y >= SCREEN.height:  # 判断图片是否滚出屏幕,如果背景图片rect对象的y值大于屏幕的高度
            self.rect.y =-self.rect.height  # 将背景图的y值设置为背景图高度的负值,这张图片就在屏幕上方

# 创建敌机类
class CreatPlane(PlaneSprites):
    def __init__(self):
        super().__init__('./images/enemy1.png')
        self.speed = random.randint(1,3)  # 利用随机数控制敌机飞行速度
        self.rect.y = -self.rect.height
        self.rect.x = random.randint(0, SCREEN.width-self.rect.width)

    def update(self):
        super().update()
        if self.rect.y >= SCREEN.height:
            self.kill()

    def __del__(self):
        print('敌机消失.....')

# 创建战机类
class CreatHero(PlaneSprites):
    def __init__(self):
        super().__init__('./images/me1.png', speed=0)
        self.rect.centerx = SCREEN.centerx
        self.rect.bottom = SCREEN.bottom-120
        self.bullet_gruop = pygame.sprite.Group()

    def update(self):
        self.rect.x += self.speed
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.right > SCREEN.right:
            self.rect.right = SCREEN.right

    # 发射子弹
    def fire(self):
        for i in (0, 1, 2):
            bullt = CreatBullet()
            bullt.rect.bottom = self.rect.y-i*20
            bullt.rect.centerx = self.rect.centerx
            self.bullet_gruop.add(bullt)


# 创建子弹精灵类
class CreatBullet(PlaneSprites):
    def __init__(self):
        super().__init__('./images/bullet1.png', speed=-2)

    def update(self):
        super().update()
        if self.rect.y < SCREEN.y:
            self.kill()

    def __del__(self):
        print('子弹消失......')

2、创建一个plane_main模块,这个是运行的主程序入口:
import pygame
from plane_sprites import *


class GamePlay(object):
    def __init__(self):
        self.screen = pygame.display.set_mode(SCREEN.size)
        self.clock = pygame.time.Clock()
        self.__creat_sprite()
        pygame.time.set_timer(CREAT_EVENT, 1000)  # 定时器:第一个参数是定时事件发生的,第二是每隔多少毫秒发生一次,这里是每个1秒触发这个定时器
        pygame.time.set_timer(BULLET_EVENT, 500)

    def start_game(self):
        while True:
            self.clock.tick(60)
            self.__update()
            pygame.display.update()
            self.__event()
            self.__chenck()

    def __chenck(self):
        # 子弹摧毁敌机
        pygame.sprite.groupcollide(self.hero.bullet_gruop,self.enemy_group,True,True)
        # 敌机碰撞战机
        bullet_list = pygame.sprite.spritecollide(self.hero,self.enemy_group, True)
        if len(bullet_list) != 0:
            self.hero.kill()
            GamePlay.game_over()

    def __creat_sprite(self):
        # hero1=BackGround('./images/background.png')
        # hero2=BackGround('./images/background.png')
        # hero2.rect.y =-hero2.rect.height
        # 创建背景精灵和精灵组
        bg1 = BackGround()
        bg2 = BackGround(is_flag=True)
        self.bg_group = pygame.sprite.Group(bg1,bg2)
        # 创建敌机精灵组
        self.enemy_group = pygame.sprite.Group()
        # 创建战机精灵和精灵组
        self.hero = CreatHero()
        self.hero_group = pygame.sprite.Group(self.hero)
        self.hero.bullet_gp = pygame.sprite.Group()

    #  更新精灵的位置
    def __update(self):
        # 更新背景图片位置
        self.bg_group.update()
        self.bg_group.draw(self.screen)
        # 更新敌机位置
        self.enemy_group.update()
        self.enemy_group.draw(self.screen)
        # 更新战机位置
        self.hero_group.update()
        self.hero_group.draw(self.screen)
        #  更新子弹位置
        self.hero.bullet_gruop.update()
        self.hero.bullet_gruop.draw(self.screen)

    # 事件监听
    def __event(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  # 当监听事件为退出事件,则退出游戏
                print('游戏退出....')
                pygame.quit()  # 卸载所有模块
                exit()  # 退出整个系统
            elif event.type == CREAT_EVENT:  # 当监听事件为定时器发生的,则创建一个敌机
                enemy1 = CreatPlane()
                self.enemy_group.add(enemy1)
            elif event.type == BULLET_EVENT:
                self.hero.fire()
        keys_press = pygame.key.get_pressed()
        # 键盘操作战机左右移动
        if keys_press[pygame.K_RIGHT]:  # 按下右键,
            self.hero.speed = 2
        elif keys_press[pygame.K_LEFT]:  # 按下左键
            self.hero.speed = -2
        else:
            self.hero.speed = 0

    @staticmethod
    def game_over():
        pygame.quit()

if __name__ == '__main__':
    game = GamePlay()
    game.start_game()

 

3、运行效果如下:

 



posted @ 2018-07-15 21:27  上海小盖伦  阅读(2266)  评论(0编辑  收藏  举报