pygame游戏play_the_ball版本二(多模块版)

简介: pygame游戏play_the_ball版本二(多模块版)

版本一和素材看另外一篇博客:


https://blog.csdn.net/qq_39236499/article/details/107848795


版本二


6个模块版本


main.py, game_functions.py, all_events.py, glass.py, ball.py, settings.py


main.py


import pygame
import traceback                                                           # 运行那里用到了
"""自建模块"""
from glass import Glass                                                    # 摩擦板和摩擦手模块
from settings import Settings                                              # 设置模块
import game_functions as gf                                                # 功能模块
import all_events                                                          # 事件模块
ai_settings = Settings()                                                   # 导入设置
motion = 0                                                                 # 2、创建一个motion 变量来记录每一秒钟产生事件数量
def main():                                                                # 主函数,把一群东西封装起来了
    pygame.init()                                                          # 初始化
    ai_settings.play_bg_music()                                            # 播放背景音乐
    screen = pygame.display.set_mode(ai_settings.bg_size)                  # 绘制窗口
    pygame.display.set_caption("小游戏")                                    # 窗口名
    background = ai_settings.bg_image.convert_alpha()                      # 加载背景图片
    """set_endevent是什么"""
    pygame.mixer.music.set_endevent(ai_settings.GAMEOVER)                  # 音乐结束游戏结束
    """group是什么"""
    group = pygame.sprite.Group()                                          # 精灵组合吗
    clock = pygame.time.Clock()                                            # 设置帧率需要
    """这是什么"""
    msgs = []
    balls = []                                                             # 用来存放小球对象的列表
    gf.set_five_ball(ai_settings, balls, group)                            # 创建五个小球,位置随机,速度随机
    glass = Glass(ai_settings.bg_size)                                     # 实例化摩擦板
    pygame.time.set_timer(ai_settings.MYTIMER, 1000)                       # 定时器,1秒一次
    """这是什么"""
    pygame.key.set_repeat(100, 100)
    while True:                                                            # 主循环
        all_events.check_all_events(ai_settings, group, balls, msgs)       # 根据事件作出响应
        gf.blit_all(screen, background, glass, balls, group, msgs, clock)  # 绘制所有
"""运行"""
if __name__ == "__main__":                                                 # 运行
    try:
        main()
    except SystemExit:                                                     # 这是按下 × 的异常,直接忽略
        pass
    except:
        traceback.print_exc()                                              # 不知道什么意思
        pygame.quit()
        input()


game_functions.py


import pygame
from random import *                                                      # 随机生成数需要
""""自建"""
from ball import Ball
def set_five_ball(ai_settings, balls, group):
    """创建5个小球,位置随机,速度随机"""
    for i in range(5):                                                    # 遍历5
        position = randint(0, ai_settings.width - 100), \
                   randint(0, ai_settings.height - 100)                   # 随机生成位置,赋值position
        speed = [randint(1, 10), randint(1, 10)]                          # 随机生成速度,赋值speed
        ball = Ball(position, speed, ai_settings.bg_size, 5 * (i+1))      # 实例化一个球
        while pygame.sprite.spritecollide(ball, group, False,
                                          pygame.sprite.collide_circle):  # 如果一生成就碰撞
            """                           小球   group  不删除   圆形属性"""
            ball.rect.left, ball.rect.top = \
                randint(0, ai_settings.width - 100), \
                randint(0, ai_settings.height - 100)                      # 再次随机位置
        balls.append(ball)                                                # 列表用append添加
        group.add(ball)                                                   # 集合用add
########################################################################################################################
def blit_all(screen, background, glass, balls, group, msgs, clock):
    """绘制所有到屏幕上"""
    screen.blit(background, (0, 0))                                       # 绘制背景图像
    screen.blit(glass.glass_image, glass.glass_rect)                      # 绘制摩擦板
    glass.mouse_rect.left, glass.mouse_rect.top = pygame.mouse.get_pos()  # 获得鼠标当前位置
    keep_place(glass)                                                     # 设置摩擦手位置在摩擦板上
    screen.blit(glass.mouse_image, glass.mouse_rect)                      # 绘制鼠标手
    collision_detection(balls, screen, group)                             # 按是否碰撞绘制球的颜色
    for msg in msgs:                                                      # 打印消息
        screen.blit(msg[0], msg[1])
    pygame.display.flip()                                                 # 刷新界面
    clock.tick(30)                                                        # 数越大越快
def keep_place(glass):                                                    # 始终保持鼠标手在摩擦板内
    """使得鼠标手在摩擦板内移动"""
    if glass.mouse_rect.left < glass.glass_rect.left:                     # 鼠标左边<摩擦板左边,即从左边出去了
        glass.mouse_rect.left = glass.glass_rect.left                     # 让鼠标手保持在左边界
    if glass.mouse_rect.left > glass.glass_rect.right - glass.mouse_rect.width:
        glass.mouse_rect.left = glass.glass_rect.right - glass.mouse_rect.width
    if glass.mouse_rect.top < glass.glass_rect.top:
        glass.mouse_rect.top = glass.glass_rect.top
    if glass.mouse_rect.top > glass.glass_rect.bottom - glass.mouse_rect.height:
        glass.mouse_rect.top = glass.glass_rect.bottom - glass.mouse_rect.height
def collision_detection(balls, screen, group):                            # 看碰撞情况绘制不同颜色小球
    for each in balls:                                                    # 遍历小球
        each.move()                                                       # 移动小球
        if each.collide:                                                  # 碰撞
            each.speed = [randint(1, 10), randint(1, 10)]                 # 随机生成速度
            each.collide = False                                          # 碰撞状态改为False
        if each.control:                                                  # 如果小球被控制
            screen.blit(each.greenball_image, each.rect)                  # 绘制绿色小球
        else:                                                             # 如果不控制
            screen.blit(each.grayball_image, each.rect)                   # 绘制灰色小球
    for each in group:
        group.remove(each)                                                # 把自身拿出来
        if pygame.sprite.spritecollide(each, group, False,
                                       pygame.sprite.collide_circle):     # 如果自己和别的球碰撞
            each.side[0] = -each.side[0]
            each.side[1] = -each.side[1]                                  # 碰撞后移动方向相反
            each.collide = True                                           # 碰撞状态为True
            if each.control:                                              # 如果是在控制状态下
                each.side[0] = -1
                each.side[1] = -1                                         # 移动方向反向
                each.control = False                                      # 失去控制,False
        group.add(each)                                                   # 还要把自己放进去


all_events.py


import pygame
import sys                                                      # 退出需要
from pygame.locals import *                                     # 把pygame的常量名导进去
from temp import motion                                         # 其实这里用到了
def check_all_events(ai_settings, group, balls, msgs):
    """所有事件"""
    global motion                                               # 全局变量
    for event in pygame.event.get():                            # 遍历事件
        if event.type == QUIT:                                  # ×掉窗口
            pygame.quit()
            sys.exit()                                          # 退出游戏
        elif event.type == ai_settings.GAMEOVER:                # 判断事件是否为我们自定义的GAMEOVER事件
            fail(ai_settings)                                   # 失败的操作,成功的操作在空格键里面
        elif event.type == ai_settings.MYTIMER:                 # 自定义事件
            if motion:                                          # motion不为零
                for each in group:                              # 遍历group
                    if each.check(motion):                      # 控制住小球
                        each.speed = [0, 0]                     # 速度为0
                        each.control = True                     # 控制状态为True
                motion = 0                                      # motion置零
        elif event.type == MOUSEMOTION:                         # 鼠标事件
            motion += 1                                         # motion+1
        elif event.type == KEYDOWN:                             # 按键事件
            check_keydown_events(event, group,
                                 ai_settings, balls, msgs)      # 按键事件的响应
def fail(ai_settings):                                           # 时间到了,游戏失败
    """游戏失败的响应事件"""
    ai_settings.loser_sound.play()                               # 失败的声音播放
    pygame.time.delay(2000)                                      # 播放2秒暂停
    ai_settings.laugh_sound.play()                               # 笑声播放
    pygame.time.delay(2000)                                      # 播放2秒暂停
    pygame.quit()
    sys.exit()                                                   # 退出游戏
def check_keydown_events(event, group, ai_settings, balls, msgs):
    """键盘按下的事件"""
    check_w_s_a_d_events(event, group)                            # 按下wsad
    check_k_space_event(event, group, ai_settings, balls, msgs)   # 按下空格键
def check_w_s_a_d_events(event, group):
    """按下wsad的响应"""
    if event.key == K_w:                                          # 按下w键
        for each in group:                                        # 遍历球
            if each.control:                                      # 如果球被控制
                each.speed[1] -= 1                                # 上移
    if event.key == K_s:                                          # 按下s键
        for each in group:                                        # 下移
            if each.control:
                each.speed[1] += 1
    if event.key == K_a:                                          # 按下a键
        for each in group:                                        # 左移
            if each.control:
                each.speed[0] -= 1
    if event.key == K_d:                                          # 按下d键
        for each in group:                                        # 右移
            if each.control:
                each.speed[0] += 1
def check_k_space_event(event, group, ai_settings, balls, msgs):
    """按下空格的响应"""
    if event.key == K_SPACE:                                     # 按下空格键
        for each in group:
            if each.control:
                for i in ai_settings.hole:                       # 遍历5个洞
                    if i[0] <= each.rect.left <= i[1] and \
                            i[2] <= each.rect.top <= i[3]:       # 如果球在其中一个洞里
                        ai_settings.hole_sound.play()            # 进洞声音播放
                        each.speed = [0, 0]                      # 固定该小球
                        group.remove(each)                       # 删除这个小球
                        """
                        下面两行语句就是完成该小球第一个绘制,
                        然后其它小球就在该小球上边了
                        """
                        temp = balls.pop(balls.index(each))      # 先从temp 中弹出
                        balls.insert(0, temp)                    # 然后插入到第一个的位置,就会第一个画了
                        ai_settings.hole.remove(i)               # 删除这个黑洞
                if not ai_settings.hole:                         # 如果洞都满了
                    win(ai_settings, msgs)                       # 游戏胜利的事件
def win(ai_settings, msgs):                                      # 胜利的事件
    """游戏胜利的事件响应"""
    pygame.mixer.music.stop()                                    # 停止背景音乐
    ai_settings.winner_sound.play()                              # 播放胜利音效
    pygame.time.delay(3000)                                      # 播放音效需要时间,延迟3秒
    msgs.append((ai_settings.win_picture.convert_alpha(),
                 ai_settings.win_picture_pos))                   # 在指定地址绘制胜利图片
    ai_settings.laugh_sound.play()                               # 播放笑声


glass.py


import pygame
class Glass(pygame.sprite.Sprite):                                          # 摩擦板类
    def __init__(self, bg_size):                                            # 这两行代码跟前面的一样
        pygame.sprite.Sprite.__init__(self)                                 # 初始化动画精灵
        """摩擦板"""
        self.glass_image = pygame.image.load("glass.png").convert_alpha()   # 加载摩擦板图像
        self.glass_rect = self.glass_image.get_rect()                       # 获取摩擦板的矩形
        self.glass_rect.left, self.glass_rect.top = \
            (bg_size[0] - self.glass_rect.width) // 2, \
            bg_size[1] - self.glass_rect.height                             # 矩形位置所在
        """鼠标手"""
        self.mouse_image = pygame.image.load("hand.png").convert_alpha()    # 加载手图像
        self.mouse_rect = self.mouse_image.get_rect()                       # 获取手的矩形
        self.mouse_rect.left, self.mouse_rect.top = \
            self.glass_rect.left, self.glass_rect.top                       # 矩形位置所在
        """设置鼠标不可见"""
        pygame.mouse.set_visible(False)                                     # 鼠标不可见


ball.py


import pygame
from random import *                                                                # 随机生成数需要
class Ball(pygame.sprite.Sprite):                                                   # 球类,继承自Spirte类
    def __init__(self, position, speed, bg_size, target):
        pygame.sprite.Sprite.__init__(self)                                         # 初始化动画精灵
        """"
        使用 .convert_alpha() 可以转换像素格式,
        提高 blit 的速度
        """
        self.grayball_image = pygame.image.load("gray_ball.png").convert_alpha()    # 加载灰球图片
        self.greenball_image = pygame.image.load("green_ball.png").convert_alpha()  # 加载绿球图片
        self.rect = self.grayball_image.get_rect()                                  # 获取小球图片矩形
        self.rect.left, self.rect.top = position                                    # position赋值给矩形位置
        """choice() 方法返回一个列表,元组或字符串的随机项。"""
        self.side = [choice([-1, 1]), choice([-1, 1])]                              # 移动方向随机
        self.speed = speed                                                          # 移动速度
        self.collide = False                                                        # 默认未碰撞
        self.target = target                                                        # 为每一个小球设定一个不同的目标
        """
        5、小球应该添加一个 control 属性,
        用于记录当前的状态(绿色 -> 玩家控制 or 灰色 -> 随机移动)
        """
        self.control = False                                                        # 默认未控制
        self.width, self.height = bg_size[0], bg_size[1]                            # 窗口的宽高
        self.radius = self.rect.width / 2                                           # 球半径
    def move(self):
        """"
        球的移动方法
        如果小球的左侧出了边界,那么将小球左侧的位置改为右侧的边界
        这样便实现了从左边进入,右边出来的效果
        """
        if self.control:                                                           # 控制
            self.rect = self.rect.move(self.speed)                                 # 移动后的矩形位置
        else:                                                                      # 未控制
            self.rect = self.rect.move(self.side[0] * self.speed[0],
                                       self.side[1] * self.speed[1])               # 随机移动
        if self.rect.right <= 0:                                                   # 小球右边界<0,即小球出左边
            self.rect.left = self.width                                            # 从右边进来
        elif self.rect.left >= self.width:                                         # 小球左边界>窗口宽度,即小球出右边
            self.rect.right = 0                                                    # 从左边进来
        elif self.rect.bottom <= 0:                                                # 小球下边界<0,即小球出上边
            self.rect.top = self.height                                            # 从下边出来
        elif self.rect.top >= self.height:                                         # 小球上边界>窗口高度
            self.rect.bottom = 0                                                   # 从上边出来
    def check(self, motion):
        """"
        3、为小球添加一个 check() 方法,
        用于判断鼠标在1秒钟内产生的事件数量是否匹配此目标;
        """
        if self.target < motion < self.target + 5:
            return True
        else:
            return False


settings.py


import pygame
from pygame.locals import *                                       # 把pygame的常量名导进去
class Settings():
    def __init__(self):
        pygame.init()                                             # 初始化
        """所有图片"""
        self.bg_image = pygame.image.load("background.png")       # 背景图像
        self.win_picture = pygame.image.load("win.png")           # 胜利的图片
        self.bg_size = self.width, self.height = 1024, 681        # 窗口尺寸
        self.win_picture_pos = \
            (self.width - self.win_picture.get_width()) // 2, \
            (self.height - self.win_picture.get_height()) // 2    # 显示胜利图像的位置
        """添加音效"""
        self.loser_sound = pygame.mixer.Sound("fail.ogg")         # 失败的时候的声音
        self.laugh_sound = pygame.mixer.Sound("laugh.ogg")        # 嘲笑的声音
        self.winner_sound = pygame.mixer.Sound("win.ogg")         # 成功的时候的声音
        self.hole_sound = pygame.mixer.Sound("hole.ogg")          # 入洞声音
        """自定义事件"""
        self.GAMEOVER = USEREVENT                                 # 音乐播放完时游戏结束
        self.MYTIMER = USEREVENT + 1                              # 每一秒钟触发一次
        self.hole = [(115, 121, 197, 203), (223, 229, 388, 394),
                     (501, 507, 318, 324), (696, 702, 190, 196),
                     (904, 910, 417, 423)]                        # 黑洞范围(x1, x2, y1, y2)
    def play_bg_music(self):
        """添加背景音乐"""
        pygame.mixer.music.load("bg_music.ogg")                   # 加载背景音乐
        pygame.mixer.music.set_volume(0.2)                        # 设置音量
        pygame.mixer.music.play()                                 # 播放背景音乐
相关文章
|
4月前
|
存储 人工智能 算法
使用 Python 和 Pygame 制作游戏:第九章到第十章
使用 Python 和 Pygame 制作游戏:第九章到第十章
54 0
使用 Python 和 Pygame 制作游戏:第九章到第十章
|
4月前
|
存储 程序员 对象存储
使用 Python 和 Pygame 制作游戏:第六章到第八章
使用 Python 和 Pygame 制作游戏:第六章到第八章
145 0
|
4月前
|
存储 Shell 程序员
使用 Python 和 Pygame 制作游戏:第一章到第五章
使用 Python 和 Pygame 制作游戏:第一章到第五章
71 0
|
9月前
|
Python
pygame编写井字棋游戏
pygame编写井字棋游戏
133 0
|
11月前
|
算法 数据可视化 Python
Python|pygame基础之壁球游戏
Python|pygame基础之壁球游戏
129 0
|
12月前
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏06之死亡后游戏重新开始
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏06之死亡后游戏重新开始
140 0
|
12月前
|
Python 容器
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏05之滚动屏幕
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏05之滚动屏幕
106 0
|
12月前
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏04之跳跃
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏04之跳跃
108 0
|
12月前
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏03之重力及碰撞检测
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏03之重力及碰撞检测
130 0