二、飞机大战终极版-巩固面向对象设计项目的思想
上面一节主要介绍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、运行效果如下: