python游戏制作

游戏开发过程
学习参考网站:https://www.pygame.org/news
常用函数总结:

# ----------窗口相关操作-----------  
# 创建窗口  
scene = pygame.display.set_mode([屏幕宽,屏幕高])  
# 设置窗口标题  
pygame.display.set_caption("标题")  
# 设置窗口图标  
pygame.display.set_icon(image)  
# 将图片绘制到窗口  
scene.blit(image, (0, 0))  
  
# ----------图像相关操作-----------  
# 加载图片  
image = pygame.image.load("图片路径")  
# 获得图片矩形 -> Rect(x, y, width, height)  
rect =  image.get_rect()  
# 移动矩形坐标  
rect.move_ip(x, y)  
# 判断两个矩形是否相交 -> bool  
flag = pygame.Rect.colliderect(rect1,rect2)  
 
# ----------事件相关操作-----------  
# 获得所有事件列表  
event_list = pygame.event.get()  
# 常见事件类型  
# QUIT 关闭窗口  
# MOUSEMOTION 鼠标拖动  
# KEYDOWN 键盘按键  
# 获得当前所有持续按键 bools_tuple  
bool_list = pygame.key.get_pressed()  
  
  
# ----------音效相关操作-----------  
# 加载背景音乐  
pygame.mixer.music.load("./res/bg2.ogg")  
# 播放背景音乐,-1表示循环播放  
pygame.mixer.music.play(-1)  
# 加载音效  
self.bomb = pygame.mixer.Sound("./res/baozha.ogg")  
# 播放音效  
pygame.mixer.Sound.play(self.bomb) 

1.用pygame建立一个游戏界面

# 建立一个界面
import pygame
import sys

pygame.init()  # pygame 初始化

pygame.display.set_caption("我的第一个游戏")         # 窗口的标题
screen = pygame.display.set_mode( (500, 500) )    # 创建一个窗口对象 设置参数以元组传入

while True:
    pygame.display.update()                       # 不断重新刷新界面
    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()

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

2.基本图形的绘制


import pygame
import sys

pygame.init()  # pygame 初始化

size = width, height = 300, 300
pygame.display.set_caption("图形绘制")        # 窗口的名称
screen = pygame.display.set_mode(size)           # 创建一个窗口对象 设置参数以元组传入

# 定义颜色变量
WHITE = pygame.color.Color(255, 255, 255)        # 定义白色常量
BLACK = pygame.color.Color(0, 0, 0, a=255)       # 定义黑色常量 alpha通道默认255,不透明
RED = "#FF0000"                                  # 定义红色        十六进制
GREEN = "0x00FF00"                               # 定义绿色
BLUE = (0, 0, 255)                               # 定义蓝色 也可以是列表[0, 0, 255]

screen.fill(WHITE)                               # 窗口填充白色


while True:
    # 画线 蓝色 起点(150,130) 终点(130,170)
    pygame.draw.line(screen, BLUE, (150, 130), (130, 170))
    # 画线 蓝色 起点(150,130) 终点(170,170)
    pygame.draw.line(screen, BLUE, (150, 130), (170, 170))
    # 画线 蓝色 起点(130,170) 终点(170,170)
    pygame.draw.line(screen, GREEN, (130, 170), (170, 170))
    # 画圆 黑色 圆心:(100,50) ,半径 30
    pygame.draw.circle(screen, BLACK, (100, 50), 30)
    # 画圆 黑色 圆心:(200,50) ,半径 30
    pygame.draw.circle(screen, BLACK, (200, 50), 30)
    # 画正方形 红色 左上方(100,200) 宽 100 高50 边框宽度为2的空心矩形
    pygame.draw.rect(screen, RED, (100, 200, 100, 50), 2)

    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()
    pygame.display.update()                       # 不断重新刷新界面

绘制图形:
在这里插入图片描述

3.实现小车的运动
方式一:

import pygame
import sys

pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("图像绘制")
screen = pygame.display.set_mode(size)

background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面
player = pygame.image.load("Player.png")
x, y = 178, 504                                        # player的位置

FPS = 30                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象


while True:

    screen.blit(background, (0, 0))               # 将图片渲染在指定的位置
    screen.blit(player, (x, y))
    y -= 1


    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()
    pygame.display.update()                       # 不断重新刷新界面
    clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

方式二:类的封装:

# -*- codeing = utf-8 -*-
# @Time : 2021/8/8 21:25
# @Author : chao
# @File : 图像运动-类封装.py
# @Software : PyCharm

import pygame
import sys

pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("图像绘制")
screen = pygame.display.set_mode(size)

# 对游戏角色封装
class Player():
    def __init__(self):
        x, y = (width/2, height/2)                   # 屏幕的中心距离
        self.image = pygame.image.load("Player.png")   # 将图片素材加载到内存
        self.rect = self.image.get_rect(center = (x, y))  # 将rect对象的中心点,定位在(x,y)处
        #self.rect = self.image.get_rect(top = 200, left = 200)   # 默认是定位在(0,0),还可以结合其他rect的属性定位显示位置

    def move(self):
        #self.rect.y -= 1                               # 直接修改rect对象的y坐标
        #self.rect = self.rect.move(0, -1)              # 使用 rect对象的move方法,设定移动增长量,返回移动后的rect对象
        self.rect.move_ip(0, -2)                       # 直接对当前rect对象移动指定数值的位移 负数表示x向左,y向上

background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面

FPS = 30                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象

player = Player()                                      # 创建Player的对象,改变图像的所在的位置

while True:

    screen.blit(background, (0, 0))               # 将图片渲染在指定的位置
    screen.blit(player.image, player.rect)        # 将player对象的image 渲染到player中指定的rect区域
    player.move()                                 # 不断的调用move()方法,


    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()
    pygame.display.update()                       # 不断重新刷新界面
    clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

图片展现:
在这里插入图片描述

4.事件处理
4.1 键盘处理:通过获取键盘列表,判断他们的状态,并执行相应的操作

# -*- codeing = utf-8 -*-
# @Time : 2021/8/9 14:07
# @Author : chao
# @File : 事件处理--键盘.py
# @Software : PyCharm


import pygame
import sys
from pygame.locals import*
pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("图像绘制")
screen = pygame.display.set_mode(size)
background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面
FPS = 30                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象


# 对游戏角色封装
class Player():
    def __init__(self):
        x, y = (178, 504)                   # 屏幕的中心距离
        self.image = pygame.image.load("Player.png")   # 将图片素材加载到内存
        self.rect = self.image.get_rect(center = (x, y))  # 将rect对象的中心点,定位在(x,y)处
        #self.rect = self.image.get_rect(top = 200, left = 200)   # 默认是定位在(0,0),还可以结合其他rect的属性定位显示位置

    def move(self):
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_UP]:
            self.rect.move_ip(0, -5)

        if pressed_keys[pygame.K_DOWN]:
            self.rect.move_ip(0, 5)

        if pressed_keys[K_LEFT]:
            self.rect.move_ip((-5), 0)

        if pressed_keys[K_RIGHT]:
            self.rect.move_ip(5, 0)



player = Player()                                      # 创建Player的对象,改变图像的所在的位置

while True:

    # 绘制图像
    screen.blit(background, (0, 0))               # 将图片渲染在指定的位置
    screen.blit(player.image, player.rect)        # 将player对象的image 渲染到player中指定的rect区域

    # 角色移动
    player.move()


    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()
    pygame.display.update()                       # 不断重新刷新界面
    clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

4.2 鼠标处理
使用mouse对象获取鼠标的位置,并根据鼠标位置进行动作响应。可以通过rect对象的属性,控制鼠标在图片上的定位点。

# -*- codeing = utf-8 -*-
# @Time : 2021/8/9 14:07
# @Author : chao
# @File : 事件处理--键盘.py
# @Software : PyCharm


import pygame
import sys
from pygame.locals import*
pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("图像绘制")
screen = pygame.display.set_mode(size)
background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面
FPS = 60                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象


# 对游戏角色封装
class Player():
    def __init__(self):
        x, y = (178, 504)                   # 屏幕的中心距离
        self.image = pygame.image.load("Player.png")   # 将图片素材加载到内存
        self.rect = self.image.get_rect(center = (x, y))  # 将rect对象的中心点,定位在(x,y)处
        #self.rect = self.image.get_rect(top = 200, left = 200)   # 默认是定位在(0,0),还可以结合其他rect的属性定位显示位置

    def move(self):
        mouseX, mouseY = pygame.mouse.get_pos()        # 获取鼠标的位置
        # 小车不能超出边界
        if player.rect.width/2 <= mouseX <= width-player.rect.width/2 and player.rect.height/2 <= mouseY <= height-player.rect.height/2:
            player.rect.center = (mouseX, mouseY)         # 鼠标的默认位置在小车的左上方 这里设置为中心


player = Player()                                      # 创建Player的对象,改变图像的所在的位置

while True:

    # 绘制图像
    screen.blit(background, (0, 0))               # 将图片渲染在指定的位置
    screen.blit(player.image, player.rect)        # 将player对象的image 渲染到player中指定的rect区域

    # 角色移动
    player.move()


    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()
    pygame.display.update()                       # 不断重新刷新界面
    clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

4.3 自定义事件
用户自定义事件及处理有3步:
定义用户事件类型名称及编码
定义用户事件触发条件
定义用户事件处理过程

# -*- codeing = utf-8 -*-
# @Time : 2021/8/9 14:07
# @Author : chao
# @File : 事件处理--键盘.py
# @Software : PyCharm


import pygame
import sys
from pygame.locals import*
pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("图像绘制")
screen = pygame.display.set_mode(size)
background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面
FPS = 60                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象


# - 定义用户事件类型名称及编码
# - 定义用户事件触发条件
# - 定义用户事件处理过程

# 添加用户自定义事件
OUT_OF_RANGE = pygame.USEREVENT + 1                    # USEREVENT = 32847 理论上比这个数大都不会与系统常量冲突





# 对游戏角色封装
class Player():
    def __init__(self):
        x, y = (178, 504)                   # 屏幕的中心距离
        self.image = pygame.image.load("Player.png")   # 将图片素材加载到内存
        self.rect = self.image.get_rect(center = (x, y))  # 将rect对象的中心点,定位在(x,y)处
        #self.rect = self.image.get_rect(top = 200, left = 200)   # 默认是定位在(0,0),还可以结合其他rect的属性定位显示位置

    def move(self):
        mouseX, mouseY = pygame.mouse.get_pos()        # 获取鼠标的位置

        # 触发用户自定义事件 如果小车超出黄色的线条
        if self.rect.left <40 or self.rect.right >360:
            pygame.event.post(pygame.event.Event(OUT_OF_RANGE))


        # 小车不能超出边界
        if player.rect.width/2 <= mouseX <= width-player.rect.width/2 and player.rect.height/2 <= mouseY <= height-player.rect.height/2:
            player.rect.center = (mouseX, mouseY)         # 鼠标的默认位置在小车的左上方 这里设置为中心



if __name__ == "__main__":

    player = Player()                                      # 创建Player的对象,改变图像的所在的位置

    while True:

        # 绘制图像
        screen.blit(background, (0, 0))               # 将图片渲染在指定的位置
        screen.blit(player.image, player.rect)        # 将player对象的image 渲染到player中指定的rect区域

        # 角色移动
        player.move()


        for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
            if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
                pygame.quit()                         # pygame退出,和pygame.init()对应
                sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()

            # 对自定义事件的处理
            if event.type == OUT_OF_RANGE:
                print("超出范围了")
        pygame.display.update()                       # 不断重新刷新界面
        clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

5.碰撞检测
pygame的sprite(精灵)对象封装了对于实体碰撞的检测方法。但要使用spite对象的方法,需要让我们定义的角色先继承Sprite类。Sprite默认包含image和rect属性。可以通过图像或图形获取surface对象和rect对象来赋值。
碰撞检测需要3步:
角色类继承Sprite,应用父类__init__方法初始化对象
定义精灵组
碰撞检测及处理
spritecollide方法中的参数:
第一个参数:玩家对象,需要是Sprite类的子类
第二个参数:敌人精灵组对象
第三个参数:碰撞后,是否将碰撞到的敌人精灵从“全部”精灵组中移除

注意:从精灵组中移除,并不会影响到精灵的状态。还可以重新添加到精灵组中,继续参与后续的显示与碰撞检测。
# -*- codeing = utf-8 -*-
# @Time : 2021/8/9 14:07
# @Author : chao
# @File : 事件处理--键盘.py
# @Software : PyCharm


import pygame
import sys
from pygame.locals import*

pygame.init()

size = width, height = (400, 600)

pygame.display.set_caption("逆行飙车")
screen = pygame.display.set_mode(size)
background = pygame.image.load("AnimatedStreet.png")   # 将图片保持在内存中 绘制背景图面
FPS = 30                                               # 设置每秒刷新的次数 图像的帧数率
clock = pygame.time.Clock()                            # 返回一个时钟对象

# 1.角色类继承Sprite
# 2.应用父类__init__方法初始化对象
# 3.定义精灵组
# 4.碰撞检测及处理

# 定义敌人类
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()          # 调用父类的初始化对象
        self.image = pygame.image.load("Enemy.png")
        self.rect = self.image.get_rect(left = width/2 - 22, top = 0)

    def move(self):
        self.rect.move_ip(0, 5)

# 定义玩家类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()                    # 调用父类的初始化对象
        x, y = (width/2, height/2)                   # 屏幕的中心距离
        self.image = pygame.image.load("Player.png")   # 将图片素材加载到内存
        self.rect = self.image.get_rect(center = (x, y))  # 将rect对象的中心点,定位在(x,y)处


    def move(self):
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_UP]:
            self.rect.move_ip(0, -5)

        if pressed_keys[pygame.K_DOWN]:
            self.rect.move_ip(0, 5)

        if pressed_keys[K_LEFT]:
            self.rect.move_ip((-5), 0)

        if pressed_keys[K_RIGHT]:
            self.rect.move_ip(5, 0)


# 定义玩家对象
player = Player()                                      # 创建Player的对象,改变图像的所在的位置
enemy = Enemy()

# 定义敌人组对象
enemies = pygame.sprite.Group()
enemies.add(enemy)

# 将所有精灵放到一个组
all_sprites = pygame.sprite.Group()
all_sprites.add(enemy)
all_sprites.add(player)

while True:

    # 绘制图像
    screen.blit(background, (0, 0))               # 将图片渲染在指定的位置

    # 统一对所有精灵进行图像绘制,和角色移动的方法调用
    for sprite in all_sprites:
        screen.blit(sprite.image, sprite.rect)
        sprite.move()


    for event in pygame.event.get():              # 从pygame的事件队列中获取事件对象
        if event.type == pygame.QUIT:             # pygame.QUIT是一个常量,数值为256,表示事件类型为退出pygame
            pygame.quit()                         # pygame退出,和pygame.init()对应
            sys.exit()                            # 如果系统在pygame.quit()前终止,IDLE会挂起,一般最后调用sys.exit()

    # 敌人和玩家都存在
   # if pygame.sprite.spritecollide(player, enemies, False):
   #     print("撞车了......")


    # 敌人消失
    # if pygame.sprite.spritecollide(player, enemies, True):   # True表示将敌人从精灵组中删除
    #     print("撞车了")

    # 玩家和敌人消失
    # if pygame.sprite.spritecollide(player, enemies, True):
    #     player.kill()                                            # 单独控制某个精灵 是从精灵组中删除 还存在内存中
    #     print("都死光了...")


    # 玩家消失
    if pygame.sprite.spritecollideany(player, enemies):  # 该方法只有俩个参数
        player.kill()
        #enemy.kill()
        print("游戏结束")

    # 从每个组中删除精灵。不影响精灵的状态,还可以重新添加到Group中。
    if player not in all_sprites:
        all_sprites.add(player)

    pygame.display.update()                       # 不断重新刷新界面
    clock.tick(FPS)                               # 按照指定的更新速率来属性界面,没到时间就让它循环等待

6.字体和音乐

#设置字体和文字
font_big = pygame.font.SysFont("华文彩云",60)                # 定义字体类型和大小
font_small = pygame.font.SysFont("Verdana",20)             # 定义字体类型和大小
game_over = font_big.render("游戏结束",True,BLACK)           # 将文字内容和字体内容绑定

#播放背景音乐
pygame.mixer.Sound("background.wav").play(-1)     #背景音乐默认执行1遍,参数loop默认为0,-1表示无限循环

7.打包
安装pyinstaller库
执行指令:
pyinstaller -F -w -i E:\Pycharm\Project\游戏制作\car.ico E:\Pycharm\Project\游戏制作\GAME.py

使用命令:pyinstaller -F [-w] [-i ico_name.ico] XXXX.py
pyinstaller-F-w -i car.icoGame.py
-F:表示生成单个可执行文件
-w:表示生成GUI文件,去掉控制台窗口
-i:表示可执行文件的图标logo
[ ]是可选的。使用图标的时候必须加上图标文件名,且图标放在工程目录下
执行命令后,会在当前项目文件夹下生成dist文件夹以及其他过程中所需的文件及文件夹。将所需资源复制到dist文件夹内。直接运行产生的exe格式的文件。即可运行游戏。dist文件夹可以作为整体复制到其他电脑上,运行当前程序。

# @Time: 2020/11/26 11:48
# @Author: chao
# @File :事件处理_键盘.py
# @Software: PyCharm

import pygame
import sys
from pygame.locals import *
import time
import random



class Constant():
    # 定义窗口的大小
    SIZE = WIDTH, HEIGHT = (400, 600)
    # 定义颜色
    BLACK = (0, 0, 0)
    RED = "#FF0000"
    # 得分
    SCORE = 0
    # 设置图像的帧速率
    FPS = 60
    # 敌人的速度
    SPEED = 5




class Enemy(pygame.sprite.Sprite):

    def __init__(self):
        x, y = (random.randint(25, 370), 0)
        super(Enemy, self).__init__()       # 调用父类的__init__方法初始化对象
        self.surf = pygame.Surface((42, 70))     # 自定义一个比物体小的Surface对象
        self.image = pygame.image.load("Enemy.png")
        self.rect = self.surf.get_rect(center = (x, y))  # 根据自定义的surf创建rect

    def move(self):
        global SCORE                              # 引用全局变量
        self.rect.move_ip(0, Constant.SPEED)
        if self.rect.top > Constant.HEIGHT:                # 躲过小车加一分
            Constant.SCORE += 1
            self.rect = self.image.get_rect(top = 0, left =random.randint(22, 378))    # 超出边界重头开始 利用随机数,位置不定



#定义玩家类
class Player(pygame.sprite.Sprite):

    def __init__(self):
      #调用父类的__init__方法初始化对象
        super().__init__()
        self.image =  pygame.image.load("Player.png")
        self.surf = pygame.Surface((42, 70))  # 自定义一个比物体小的Surface对象
        self.rect = self.surf.get_rect(left =178, bottom = Constant.HEIGHT - 21)

    def move(self):
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[pygame.K_UP] and self.rect.top >= 0:      # 顶部不能超过y
            self.rect.move_ip(0, -5)
        if pressed_keys[pygame.K_DOWN] and self.rect.bottom <= Constant.HEIGHT-21:
            self.rect.move_ip(0, 5)
        if pressed_keys[K_LEFT] and self.rect.left >= 0:
            self.rect.move_ip(-5, 0)
        if pressed_keys[K_RIGHT] and self.rect.right <= Constant.WIDTH-4:
            self.rect.move_ip(5, 0)



class Game():
    def __init__(self):
        pygame.init()
        pygame.display.set_caption("逆行飙车")
        self.screen = pygame.display.set_mode(Constant.SIZE)
        # 加载背景图片
        self.background = pygame.image.load("AnimatedStreet.png")
        # 播放背景音乐
        pygame.mixer.Sound("background.wav").play(-1)         # 背景音乐默认执行1遍,参数loop默认为0,-1表示无限循环
        # 设置字体和文字
        self.font_big = pygame.font.SysFont("华文彩云", 60)         # 定义字体类型和大小
        self.font_small = pygame.font.SysFont("Verdana", 20)       # 定义字体类型和大小
        self.game_over = self.font_big.render("游戏结束", True, Constant.BLACK)   # 将文字内容和字体内容绑定
        # 用户自定义事件
        self.SPEED_UP = pygame.USEREVENT + 1
        pygame.time.set_timer(self.SPEED_UP, 1000)                 # 每隔1s将事件放在队列一次
        self.clock = pygame.time.Clock()

    def run(self):
        # 定义玩家对象
        player = Player()
        enemy = Enemy()

        #定义敌人精灵组
        enemies = pygame.sprite.Group()
        enemies.add(enemy)

        #将所有精灵放到一个组中
        all_sprites = pygame.sprite.Group()
        all_sprites.add(player)
        all_sprites.add(enemy)

        while True:
            # 绘制图像
            self.screen.blit(self.background, (0, 0))
            self.scores = self.font_small.render(str(Constant.SCORE), True, Constant.BLACK)
            self.screen.blit(self.scores, (10, 10))  # 将分数显示出来

            # 统一对所有的精灵进行图像绘制,角色移动的方法调用
            for sprite in all_sprites:
                self.screen.blit(sprite.image, sprite.rect)
                sprite.move()


            # 从事件队列中取出事件对象,根据类型进行事件处理
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == self.SPEED_UP:
                    Constant.SPEED += 0.5

            # 撞击后,游戏结束
            if pygame.sprite.spritecollideany(player, enemies):
                pygame.mixer.Sound("crash.wav").play()  # 播放一次
                time.sleep(1)

                self.screen.fill(Constant.RED)  # 红色填充
                self.screen.blit(self.game_over, (80, 150))

                pygame.display.update()
                time.sleep(2)

                pygame.quit()
                sys.exit()

            pygame.display.update()
            self.clock.tick(Constant.FPS)  # 按照指定的更新速率CLOCK来刷新画面,没到时间就让循环等待






if __name__ == "__main__":
    game = Game()
    game.run()

效果:
在这里插入图片描述

在这里插入图片描述

  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值