• Python基础:第012课——最小的程序框架(代码解析)


    参考:pygame详细教程
    参考案例:游戏模块
    Pygame 作为一个入门级的游戏开发库,其实并不难学,只要掌握 Python 编程的相关知识就能很轻松地掌握它。

    Pygame 语法简单、明了,秉持了 Python 语言一贯的风格。同时,它作为一个游戏开发库来说,具有图形编程的基本特点,如果您对于图形编程从未了解过,即使您有 Python 编程基础,也会略感迷茫。因此,在接下来的学习中会详细介绍 Pygame 的常用模块,以及图形编程中的相关概念,帮助您快速掌握 Pygame 的使用。

    屏幕坐标系

    在这里插入图片描述

    #导入所需的模块
    import pygame, sys
    
    # 使用pygame之前必须初始化
    pygame.init()
    
    # 设置主屏窗口
    screen = pygame.display.set_mode((600,400))
    
    # 设置窗口的标题,即游戏名称
    pygame.display.set_caption("小小工坊")
    
    # 加载图像,存储在ball变量中,ball是一个图像对象
    ball = pygame.image.load('pygame/images/ball.gif')
    
    #获得显示对象的rect区域坐标
    ball_rect = ball.get_rect()
    # 设置显示对象居中
    ball_rect.center = (300, 200)
    # 将准备好的图像绘制到主屏幕 Screen 上。
    screen.blit(ball, ball_rect)
    
    # 建立时钟对象
    fclock = pygame.time.Clock()
    
    # 固定代码段,实现点击关闭按钮退出游戏的功能,几乎所有的pygame都会使用该段代码
    while True :
    		# 循环获取事件,监听事件状态
    	    for event in pygame.event.get():
    		    	# 判断用户是否点了"X"关闭按钮,并执行if代码段
    		        if event.type == pygame.QUIT:
    			            #卸载所有模块
    			            pygame.quit()
    			            #终止程序,确保退出程序
    			            sys.exit()
    	    ball_rect = ball_rect.move(speed,speed)
    	    screen.fill((0,0,0))
    	    screen.blit(ball,ball_rect)
    		
    		#更新屏幕内容
    	    pygame.display.update()
    	    fclock.tick(60)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    12. 代码解析

    Python:pygame包的详细使用方法

    12.1 游戏的初始化和退出

    # 使用pygame之前必须初始化
    pygame.init()
    
    • 1
    • 2
    • 要使用pygame提供的所有功能之前,需要调用init 方法,它的作用是自动检测 Pygame 软件包是否正常可用,并检查电脑的硬件调用接口、基础功能是否存在问题,比如音频、光驱、声卡驱动等设备。同时,它会完成 Pygame 中所有模块的初始化操作,比如 display(显示模块)、font(字体模块)、mixer(声音控制模块)、cursors(光标控制模块)等。

    • 在游戏结束前需要调用一下quit方法

    12.1.1 方法说明

    pygame.init() 导入并初始化所有pygame模块,使用其他模块前,必须先调用iinit方法
    pygame.quit() 卸载所有pygame模块,在游戏结束之前调用

    12.2 Surface对象

    12.2.1 坐标系

    • 原点在左上角 (0,0)
    • x轴水平方向向右,逐渐增加
    • y轴垂直方向向下,逐渐增加

    如图:
    在这里插入图片描述

    • 在游戏中,所有可见的元素都是以矩形区域来描述位置的
    • 要描述一个矩形区域有四个要素: (x, y) (width, height)

    (x,y)是物体坐标,(width, height)是物体像素大小

    • pygame 专门提供了一个类pygame.Rect 用于描述矩形区域

    x, y
    left,top,bottom,right
    center,centerx,centery
    size,width,height

    12.2.2 如何创建Surface对象

    那么我们应该如何创建 Surface 对象呢?Pygame 提供了多种创建 Surface 对象的方法,这里先介绍以下几种方法。

    上述示例,使用如下方式创建了一个 surface 对象:

    #也叫screen对象,本质上是一个Surface,大小400*400
    screen = pygame.display.set_mode((400,400))
    
    • 1
    • 2

    screen 的本质上就是一个 Surface 对象,它是游戏的主窗口,也就是整个游戏中尺寸最大的“纸”,任何其他的 Surface 对象都需要附着在这张最大的“纸”上,比如创建一个图像的 Surface 对象,通过以下方法将它绘制在主屏幕上:

    # 加载图像,存储在ball变量中,ball是一个图像对象
    ball = pygame.image.load('pygame/images/ball.gif')
    
    #获得显示对象的rect区域坐标
    ball_rect = ball.get_rect()
    # 设置显示对象居中
    ball_rect.center = (300, 200)
    # 将准备好的图像绘制到主屏幕 Screen 上。
    screen.blit(ball, ball_rect)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    比如创建一个包含文本的 Surface 对象,通过以下方法将它绘制在主屏幕上:

    # 引入字体类型
    f = pygame.font.Font('C:/Windows/Fonts/simhei.ttf',50)
    
    #创建一个包含文字的Surface对象
    # 生成文本信息,第一个参数文本内容;第二个参数,字体是否平滑;
    # 第三个参数,RGB模式的字体颜色;第四个参数,RGB模式字体背景颜色;
    text = f.render("小小工坊",True,(255,0,0),(0,0,0))
    
    textRect =text.get_rect()
    
    #通过blit方法将其绘制在主屏幕上,这里的textRect表示位置坐标
    screen.blit(text,textRect)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    set_mode()方法

    set_ mode( resolution=(0,0),flags=0, depth=0) -> Surface(名字随意)

    • 作用:创建游戏显示窗口
    • 参数
      • resolution 指定屏幕的宽和高,默认创建的窗口大小和屏幕大小一致
      • flags参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递
      • depth参数表示颜色的位数,默认自动匹配
    • 返回值:Surface对象
      Surface对象是内存中的屏幕数据对象,可以理解为游戏的屏幕,游戏的元素都需要被绘制到游戏的屏幕上
      1. 在开发时,可能会需要使用固定的数值,例如屏幕的高度是700
      2. 这个时候,建议不要直接使用固定数值,而应该使用常量
      3. 当实验需求发生变化时,只需要修改常量的值就可,不需要在一个一个去找数值更改

    常量的命名方式:

    所有字母都使用大写,单词与单词之间使用下划线连接

    12.2.3 *Rect对象

    pygame.Rect是一个比较特殊的类,内部只是封装了一些数字计算

    实例:

    import pygame
    hero = pygame.Rect(100,200,50,120)
    print("英雄的x,y坐标分别是 %d, %d" % (hero.x, hero.y))
    print("英雄的宽高分别是:%d,%d" % (hero.width, hero.height))
    # Rect中的size属性是一个元组(宽,高)
    print("英雄的宽高分别是:%d,%d" % hero.size))
    # Rect中的bottom属性表示底部的纵坐标 y+height,top属性表示元素顶部纵坐标y
    print("英雄的底部y坐标为:%d,顶部y坐标为:%d" % (hero.bottom, hero.top))
    # Rect的right属性表示元素右边横坐标 x+width, left表示元素横坐标x
    print("英雄的最右边x坐标为%d,最左边x坐标为:%d" % (hero.right, hero.left))
    # Rect的center属性是一个元组(centerx,centery)
    print("英雄的中心点坐标为:%d,%d" % hero.center)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    12.3 图像绘制

    那么要在创建的窗口中按照指定要求显示图片,则需要三个步骤:

    1. 使用`pygame.image.load()`加载图像的数据
    2. 使用游戏屏幕对象,调用`blit`方法将图像绘制到指定位置
    3. 调用`pygame.display.update()`方法更新整个屏幕的显示
    
    • 1
    • 2
    • 3
    *
    *
    *
    *
    load
    -File 图像文件
    blit
    -image 图像对象
    +tuple 位置
    update
    -screen update

    注:如果不调用pygame.display.update()方法,则运行程序后图片并不会显示出来,在所有图像绘制完成后可放在最后统一更新

    12.4 事件监听

    游戏,在我们日常生活中经常接触到,无论是手游、还是电脑端游戏,已经成了信息社会中,不可或缺的一部分。

    游戏大致来讲是由动画和人机交互的体验两部分构成,其中动画则是由一系列连续静止的图片,经过一定频率的刷新构成的,这个频率被称为 FPS,如果频率值越大则画面越流畅;如果频率值越小则画面会出现卡顿的感,在游戏过程中一般人能接受的最低 FPS 约为 30Hz,如果想要画面流畅则 FPS 要大于 60 Hz。

    FPS 越高,细节越好,体验也越好,但是文件容量也越高

    动画保证了玩家的视觉体验,而人机交互则是操作上的体验。通过移动和点击鼠标、按下键盘上的技能键,或是滑动手机屏幕等操作来实现人机交互,这些与游戏程序交互的操作被称为事件(Event)。

    Pygame 作为一个游戏开发库,同样具有设置和监听事件的功能。它提供了一个 event 事件模块,这个模块中包含了所有常用到游戏事件。下面是退出游戏的代码示例(其他事件类型,后续会做介绍):

    # 循环获取事件,监听事件状态,使用get()获取事件
    for event in pygame.event.get():
    	# 判断事件类型,用户是否点了"X"关闭按钮    
    	# pygame.QUIT 指点击右上角窗口的"X"号
        if event.type == pygame.QUIT:
        	#点击后,卸载所有pygame模块
            pygame.quit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    12.5 游戏循环

    当打我们游戏时可能会触发游戏中的各种事件,比如鼠标事件、键盘按键事件、摄像拍照事件等等,因此游戏程序需要一直循环监听玩家的操作,只有当用户点击了游戏“关闭”按钮时,监听才会结束。如果想要达到“循环监听”目的,此时就需要设置一个游戏循环(Game Loop)也称为游戏的主循环,这样才能保证人机交互的体验感。代码示例如下:

    #游戏主循环(游戏循环)
    while True:
    		# 循环获取事件,监听事件
        	for event in pygame.event.get():
        		# 判断用户是否点了关闭按钮
    	        if event.type == pygame.QUIT:
    	        	# 当用户关闭游戏窗口时执行以下操作
    	            # 这里必须调用quit()方法,退出游戏
    	            pygame.quit()
    	            #终止系统
    	            sys.exit()
    		#更新并绘制屏幕内容
    		pygame.display.flip() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    游戏主循环是每个 Pygame 游戏程序中必不可少的一部分,它主要承担着以下三个重要任务:

    • 处理游戏事件
    • 更新游戏状态
    • 把更新后的游戏状态绘制到屏幕上

    pygame程序
    图2:主循环示意图

    游戏画面和游戏操作状态会因为动画效果和玩家的操作而改变,因此需要以循环的方式实时地更新主屏幕(screen)的显示内容。把下列代码放入游戏主循环中即可实现实时更新和绘制屏幕内容,如下所示:

    #刷新界面显示
    pygame.display.flip() 
    
    • 1
    • 2

    除了上述方法外,Pygame 还提供了另一个方法。如下所示:

    pygame.display.update() 
    
    • 1

    这两个方法的主要区别是:后者可以根据选定的区域来更新部分内容,而前者则是更新整个待显示的内容。如果后者没有提供区域位置参数时,其作用和 display.flip() 相同。

    12.6 关于动画实现的原理

    跟电影的原理类似,游戏中的动画效果,本质上是快速的在屏幕上绘制图像,电影是将多张静止的电影胶片连续、快速的播放,产生连贯的视觉效果!

    一般在电脑上每秒绘制60次,就能够达到非常连续高品质的动画效果,每次绘制的结果被称为帧Frame

    在每次调用pygame.display.update()方法产生的结果为一帧,也就是说需要每秒钟调用60次pygame.display.update()方法,就可以达到高品质动画效果

    如何实现每秒60帧?
    pygame专门提供了一个类pygame.time.Clock 可以非常方便的设置屏幕绘制速度- -刷新帧率

    要使用时钟对象需要两步:

    1. 在游戏初始化创建一个时钟对象
    2. 在游戏循环中让时钟对象调用tick(帧率) 方法,tick 方法会根据.上次被调用的时间, 自动设置游戏循环中的延时

    实现方法:

    # 创建时钟对象
    
    clock = pygame.time.Clock()
    
    while True:
    	# 在游戏循环内部调用tick方法,里面传入想要的帧数
    ​	clock.tick(60)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    动画实现案例:飞机向上飞行
    例 :

        import pygame
        
        pygame.init()
        
        # 创建游戏窗口
        
        screen = pygame.display.set_mode((480,700))
        
        # 加载游戏中需要的图像
        
        background = pygame.image.load("./pygame/images/xx.jpg")
        plane = pygame.image.load("./pygame/images/xxx.jpg)
        
        # 将图像显示到游戏初始化的位置
        
        screen.blit(background, (0, 0))
        screen.blit(plane, (120, 500))
        
        # 定义飞机显示的矩形区域
        
        plane_Rect = pygame.Rect(120, 500, 120, 90)
        
        # 创建时钟对象
        
        clock = pygame.time.Clock()
        while True:
            # 定义每秒60帧
            clock.tick(60)
            # 移动飞机显示矩形区域的位置
            plane_Rect.y = plane_Rect.y -5
        
            # 重绘背景图像,避免出现残影
            screen.blit(background, (0, 0))
        
            # 重新绘制图像
            screen.blit(plane, place_Rect)
        
            # 更新屏幕
            pygame.display.update()
        pygame.quit()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    12.7 针对键盘按键捕获的两种方式

    ●第一种方式判断event.type == pygame.KEYDOWN

    实现代码:

    if event.type == pygame. KEYDOWN and event.key == pygame.K RIGHT:
    	print("向右移动...")
    
    • 1
    • 2

    ●第二种方式(按住方向键不放可持续移动)

    1. 首先使用pygame. key.get_ pressed()返回所有按键元组
    2. 通过键盘常量,判断元组中某一个键是否被按下——如果被按下,对应数值为1

    实现代码:

    变量 = pygame.key.get_pressed()
    if 变量[pygame.K_RIGHT]:
    	print("向右移动")
    
    • 1
    • 2
    • 3

    ● 两种方式的区别

    第一种方式 event.type 用户必须抬起按键才算一次按键事件(利用列表也可实现持续向某一方向移动,具体见)
    第二种方式 用户可按键不放,能够实现持续向某一个方向移动

    *12.8 pygame中提供的高级类精灵和精灵组

    图像加载、位置变化、绘制图像都需要程序员编写代码分别处理,为了简化代码,避免过多类似重复的代码,pygame提供了精灵和精灵组类

    心得: 其根本就是,将需要创建的多个执行相同动作的元素通过精灵类统一规划到一起,再通过精灵组统一执行每个元素的动作并绘制到屏幕上,将多次重复的代码缩减成一次代码。

    • pygame.sprite.Sprite —— 存储图像数据image和位置rect 的对象
    • pygame.sprite.Group

    注:在开发时,如果子类的父类不是Object类,则需要通过super(),__init__()来调用父类的初始化方法,因为父类中的初始化方法中封装了许多属性,在继承父类后只有通过手动调用父类的初始化方法,才能在子类的初始化方法中使用父类初始化方法封装的属性

    ●精灵
    。封装图像image、位置rect
    。提供update() 方法,根据游戏需求,更新位置rect

        # 定义对象的属性
        self.image = pygame.image.load(image)
        # 得到图片的坐标和宽高像素
        self.rect = self.image.get_rect()
    
    • 1
    • 2
    • 3
    • 4

    ●精灵组
    。包含多个精灵对象
    。update 方法,让精灵组中的所有精灵调用update 方法更新位置
    。draw(游戏窗口对象) 方法,在游戏窗口上绘制精灵组中的所有精灵

    实例:

    #精灵类planeSprites:
    
    import pygame
    
    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
        
        def update(self, *args):
            # 使飞机斜着飞行
            self.rect.x += self.speed
            self.rect.y += self.speed
            # 杀死精灵,节约内存
            self.kill()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    主程序中:

    import pygame
    from plane_sprites import planeSprites
    pygame.init()
    
    # 创建敌机1,敌机2
    enemy1 = planeSprites("./飞机大战素材/敌机.png")
    enemy2 = planeSprites("./飞机大战素材/敌机.png")
    # 在精灵组中加入敌机1
    enemy_group = pygame.sprite.Group(enemy1, enemy2)
    while True:
    	# 调用精灵组的update方法
        enemy_group.update()
        # 将精灵组中的敌机绘制到屏幕上
        enemy_group.draw(screen)
        # ***一定记得更新视图,否则不会显示出任何图像
        pygame.display.update()
        
    pygame.quit()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    12.9 pygame中提供的两种精灵碰撞检测方法

    
    pygame.sprite.groupcolide()
    groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_ dict
    
    • 1
    • 2
    • 3

    group1和group2都是一个精灵组
    dokill1和dokill2都是布尔类型

    当把dokill1设置为True后,精灵组1和精灵组2碰撞时精灵组1会自动销毁
    当把dokill2设置为True后,精灵组1和精灵组2碰撞时精灵组2会自动销毁

    pygame.sprite.spritecollide()
    ●判断某个精灵和指定精灵组中的精灵的碰撞

    spritecollide(sprite, group, dokill, collided = None) -> Sprite_ list

    ●如果将dokill 设置为True,则指定精灵组中发生碰撞的精灵将被自动移除

    ● collided参数是用于计算碰捶的回调函数
    。如果没有指定,则每个精灵必须有一一个rect 属性

    ●返回精灵组中跟精灵发生碰撞的精灵列表

    注:这里是返回一个列表

    代码实现:

            enemies = pygame.sprite.spritecollide(self.hero, self.enemyGroup, True)
            if len(enemies) > 0:
                print("游戏结束,飞机受到损坏")
                pygame.quit()
                exit()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    12.10 背景交替滚动

    俗称跑步机模式

    在飞机大战中游戏背景不断变化产生向上飞行的视觉效果

    实现原理:

    实际上是两张尺寸与屏幕一样大小的背景图片向下移动,等第一张图片刚移除出屏幕后立马改变坐标移动到第二张图片之后

    代码实现:
    精灵类

    import pygame
    
    from plane_main import SCREEN_RECT
    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
        
        def update(self, *args):
            # 使精灵向下移动
            self.rect.y += self.speed
    
    
    # 当父类update更新方法已经无法满足某一精灵类的条件则可以创建心得精灵子类
    class background(planeSprites):
    
        def __init__(self, is_single=False):
            super().__init__("./飞机大战素材/游戏背景.jpg")
            if is_single:
            	#将第二张图片放在第一张图片的上面
                self.rect.y = - self.rect.height
        
        def update(self, *args):
            # 调用父类更新方法
            super().update()
            if self.rect.y == SCREEN_RECT.height:
                self.rect.y = - self.rect.height
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    主方法:

    import pygame
    from plane_sprites import *
    
    pygame.init()
    
    SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
    class main(object):
        def __init__(self):
            # 创建游戏屏幕
            self.screen = pygame.display.set_mode(SCREEN_RECT.size)
            # 创建游戏时钟
            self.clock = pygame.time.Clock()
            # 创建游戏精灵组
            self.__create_spirits()
    
        # 精灵创建
        def __create_spirits(self):
            bg1 = background()
            bg2 = background(True)
            self.backGroup = pygame.sprite.Group(bg1, bg2)  
             
        # 精灵更新处理
        def __update_spirits(self):
            self.backGroup.update()
            self.backGroup.draw(self.screen)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    12.11 定时器

    ●在 pygame中可以使用pygame.time.set.timer()来添加定时器

    ●所谓定时器,就是每隔一段时间,去执行些动作

    set_timer(eventid, milliseconds) -> None
    
    • 1

    ●set_timer 可以创建一个事件
    ●可以在游戏循环的事件监听方法中捕获到该事件

    ● 第1个参数事件代号需要基于常量pygame. USEREVENT 来指定

    USEREVENT 是一个整数,再增加的事件可以使用USEREVENT + 1指定,依次类推…

    ●第2个参数是事件触发间隔的毫秒值

    定时器事件的监听
    ●通过pygame.event.get() 可以获取当前时刻所有的事件列表
    ●遍历列表并且判断event.type 是否等于eventid, 如果相等,表示定时器事件发生

    实现方法:

    # 创建敌机的定时器,每隔1000ms发出一个事件
    pygame.time.set_timer(pygameUSEREVENT, 3000)
    # 事件监听
    for event in pygame.event.get():
    	if event.type == pygameUSEREVENT:
    		pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实例(敌机随机飞进屏幕中):

    精灵类

    import random
    import pygame
    # 指定屏幕格式大小
    SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
    CREATE_EVVENTID = pygame.USEREVENT
    
    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
            # 创建敌机的定时器,每隔1000ms发出一个事件
            pygame.time.set_timer(CREATE_EVVENTID, 3000)
    
    class enemy(planeSprites):
        """敌机精灵"""
    
        def __init__(self):
            super().__init__("./飞机大战素材/敌机.png")
            self.rect.bottom = 0
            # 飞机速度从1—3中任取
            self.speed = random.randint(1, 3)
            max_x = SCREEN_RECT.width - self.rect.width
            # 飞机的位置从0-屏幕右边任取
            self.rect.x = random.randint(0, max_x)
        
        def update(self, *args):
            super().update()
            # 判断精灵飞出屏幕后杀死精灵
            if self.rect.y >= SCREEN_RECT.height:
                self.kill()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    主方法:

    import pygame
    from plane_sprites import *
    pygame.init()
        # 精灵创建
        def __create_spirits(self):
            self.enemyGroup = pygame.sprite.Group()
        # 事件监听处理
        def __event_handler(self):
            for event in pygame.event.get():
                # 判断事件类型是否是定时器给出的
                if event.type == CREATE_EVVENTID:
                    # 新增精灵
                    oneEnemy = enemy()
                    # 向精灵组中添加精灵
                    self.enemyGroup.add(oneEnemy)
                    
        # 精灵更新处理
        def __update_spirits(self):
            self.enemyGroup.update()
            self.enemyGroup.draw(self.screen)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    12.12 音乐导入

    #导入音乐
    	pygame.mixer.init()
    	def background_music_load():
    	        global hero_fire_music # 导入函数外部变量
    	        pygame.mixer.music.load("./music/PlaneWarsBackgroundMusic.mp3")#游戏背景音乐
    	        pygame.mixer.music.set_volume(0.3)#设置音量(0-1)
    	        pygame.mixer.music.play(-1)#循环播放
    	        hero_fire_music = pygame.mixer.Sound("./music/hero_fire.wav")#飞机开火音乐
    	        hero_fire_music.set_volume(0.2)#设置音量(0-1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

  • 相关阅读:
    Mockito搭配junit单元测试
    HBase第二章:API操作(二)
    阿里云服务器如何关闭防火墙?阿里云安全组怎么设置端口?
    java并发编程 守护线程 用户线程 main
    bootstrap 主题
    JAVA反射机制详解
    【C++】命名空间
    Kafka入门二——SpringBoot连接Kafka示例
    Node.js 入门教程 11 Node.js 从命令行接收参数
    LeetCode50天刷题计划(Day 14—— 删除链表的倒数第 N 个结点(12.20-13.00)
  • 原文地址:https://blog.csdn.net/acktomas/article/details/125250370