87.碰撞检测

简介: 87.碰撞检测

碰撞检测


碰撞之后会反方向移动,方向和速度都取反


import pygame
import sys                   # 退出游戏需要
import math                  # 数学公式需要
from pygame.locals import *  # 把pygame的常量名导进去
from random import *         # 随机生成数需要
class Ball(pygame.sprite.Sprite):  # 定义一个球类,继承动画精灵基类
    """小球的属性"""
    def __init__(self, image, position, speed, bg_size):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image).convert_alpha()   # 加载图像
        self.rect = self.image.get_rect()                 # 获取图像矩形
        self.rect.left, self.rect.top = position          # 获取图像位置
        self.speed = speed                                # 速度
        self.width, self.height = bg_size[0], bg_size[1]  # 窗口宽高
    """小球的移动"""
    def move(self):
        self.rect = self.rect.move(self.speed)   # 移动球所在矩形
        """实现小球从某侧出界,从对侧进来"""
        if self.rect.right < 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 collide_check(item, target):  # item是取出的一个小球,target是小球集合五个
    """碰撞检测"""
    col_balls = []   # 建立一个收集碰撞的球的空列表
    for each in target:
        distance = math.sqrt(
            math.pow((item.rect.center[0]-each.rect.center[0]), 2) +
            math.pow((item.rect.center[0]-each.rect.center[0]), 2)
                            )   # 求两点之间的距离
        if distance <= (item.rect.width + each.rect.width) / 2:
            # 距离小于两个球半径相加
            col_balls.append(each)
    return col_balls
def main():         # 主函数
    pygame.init()   # 初始化,游戏开始都需要的
    ball_image = "gray_ball.png"   # 灰球图像
    bg_image = "background.png"    # 背景图片,图片上有五个黑球
    running = True  # 初试running为True
    bg_size = width, height = 1024, 681        # 窗口尺寸,也是背景的尺寸大小
    screen = pygame.display.set_mode(bg_size)  # 绘制窗口
    pygame.display.set_caption("玩个球")        # 窗口名
    background = pygame.image.load(bg_image).convert_alpha()  # 加载背景图片进去
    balls = []   # 球列表,初始空列表
    # 创建五个小球
    BALL_NUM = 5
    for i in range(BALL_NUM):  # 遍历0到4即五个小球
        # position = (left, top)   左边和上边的坐标
        position = randint(0, width-100), randint(0, height-100)   # 随机生成球的坐标,球大小是100×100
        speed = [randint(-10, 10), randint(-10, 10)]               # 球速度随机-10到10
        ball = Ball(ball_image, position, speed, bg_size)          # 实例化上面的Ball类,建立一个小球,循环五次就建立了五个
        while collide_check(ball, balls):                          # 如果刚开始就碰撞了
            ball.rect.left, ball.rect.top = randint(0, width-100), randint(0, height-100)  # 重新初试位置
        balls.append(ball)        # 添加球到球列表,循环五次就添加了五个
    clock = pygame.time.Clock()   # 设置帧率需要用到
    while running:   # 主循环
        for event in pygame.event.get():  # 遍历事件
            if event.type == QUIT:        # ×掉窗口
                sys.exit()                # 退出游戏
        screen.blit(background, (0, 0))   # 更新图像和位置
        for each in balls:    # 遍历球类里面的各个球
            each.move()       # 各自移动
            screen.blit(each.image, each.rect)  # 更新每个球和球矩形位置
        for i in range(BALL_NUM):  # 检测碰撞
            item = balls.pop(i)    # 先取出来小球
            if collide_check(item, balls):      # 如果碰撞
                item.speed[0] = -item.speed[0]  # 速度取反
                item.speed[1] = -item.speed[1]
            balls.insert(i, item)  # 取出来的放回去
        pygame.display.flip()  # 刷新界面,相当于游戏结束都需要的
        clock.tick(30)         # 这里设置帧率
if __name__ == "__main__":
    main()


使用spritecollide()碰撞检测


spritecollide(sprite, group, dokill, collided = None)


第一个参数 sprite 是指定被检测的精灵;(就是我们写的里面的 item)


第二个参数 group 是指定一个组(就是我们写的里面的 target 列表),它是 sprite 的组,因此要使用 sprite.Group() 来生成;


第三个参数 dokill 是设置是否从组中删除检测到碰撞的精灵,设置为True,则删除;


第四个参数 collided 是指定一个回调函数,用于定制特殊的检测方法,如果第四个参数忽略的话,默认是检测精灵之间的 rect 属性。


import pygame
import sys                      # 退出需要
from pygame.locals import *     # 把pygame的常量名导进去
from random import *            # 随机生成数需要
# 球类继承自Spirte类
class Ball(pygame.sprite.Sprite):
    def __init__(self, image, position, speed, bg_size):
        # 初始化动画精灵
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image).convert_alpha()
        self.rect = self.image.get_rect()
        # 将小球放在指定位置
        self.rect.left, self.rect.top = position            # 小球的左边和上边
        self.speed = speed
        self.width, self.height = bg_size[0], bg_size[1]    # 窗口的宽高
        self.radius = self.rect.width / 2  # 增加半径属性
    def move(self):
        self.rect = self.rect.move(self.speed)
        # 如果小球的左侧出了边界,那么将小球左侧的位置改为右侧的边界
        # 这样便实现了从左边进入,右边出来的效果
        if self.rect.right < 0:
            self.rect.left = self.width
        elif self.rect.left > self.width:
            self.rect.right = 0
        elif self.rect.bottom < 0:
            self.rect.top = self.height
        elif self.rect.top > self.height:
            self.rect.bottom = 0
def main():
    pygame.init()
    ball_image = "gray_ball.png"
    bg_image = "background.png"
    running = True
    # 根据背景图片指定游戏界面尺寸
    bg_size = width, height = 1024, 681
    screen = pygame.display.set_mode(bg_size)
    pygame.display.set_caption("小游戏")
    background = pygame.image.load(bg_image).convert_alpha()
    # 用来存放小球对象的列表
    balls = []
    group = pygame.sprite.Group()
    # 创建五个小球
    for i in range(5):
        # 位置随机,速度随机
        position = randint(0, width - 100), randint(0, height - 100)   # 随机生成位置
        speed = [randint(-10, 10), randint(-10, 10)]                   # 随机生成速度
        ball = Ball(ball_image, position, speed, bg_size)              # 实例化小球
        while pygame.sprite.spritecollide(ball, group, False, pygame.sprite.collide_circle):  # 在创建小球这里必须进行一下碰撞检测
            ball.rect.left, ball.rect.top = randint(0, width - 100), randint(0, height - 100)  # 随机生成的小球碰撞了就在随机生成位置
        balls.append(ball)   # 列表用append
        group.add(ball)      # 集合用add
    clock = pygame.time.Clock()
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
        screen.blit(background, (0, 0))
        for each in balls:
            each.move()
            screen.blit(each.image, each.rect)
        for each in group:
            group.remove(each)  # 把自身拿出来
            if pygame.sprite.spritecollide(each, group, False, pygame.sprite.collide_circle):  # 把自己和别的球进行碰撞检测
                each.speed[0] = -each.speed[0]
                each.speed[1] = -each.speed[1]
            group.add(each)  # 还要把自己放进去
        pygame.display.flip()
        clock.tick(30)
if __name__ == "__main__":
    main()


推荐阅读博客


博客一

目录
相关文章
|
2月前
|
安全 Java 测试技术
Java 工程化体系:代码规范与团队协作全链路标准
本文系统阐述Java工程化规范体系,涵盖代码命名、格式、异常处理、日志、注释、模块结构、Git流程、自动化门禁等七大维度,强调规范是团队协作的“通用语言”,须通过工具链强制落地,而非依赖人工自觉,最终实现高质量、可持续的研发交付。
343 1
|
运维 负载均衡 网络协议
从底层技术来看,GSLB 究竟难在哪儿
本文作者吕宏利来自硅谷的SRE,有着多年的国内外大型互联网公司运维开发经验,专注于分布式系统设计、监控、容量规划,数据中心技术以及生产环境的最佳实践。在本文中他将他将向读者介绍什么是GSLB,以及实现细节和维护方法。
9381 0
|
8月前
|
Rust JavaScript 安全
Github 2024-09-02 开源项目周报 Top13
本周GitHub热门项目涵盖AI、开发工具与开源替代品。包括Notion替代AppFlowy、Airtable替代NocoDB、云平台Coolify及可观察性平台OpenObserve等,涉及Python、TypeScript、Rust等语言,聚焦效率、隐私与自动化。
473 1
|
9月前
|
存储 SQL 大数据
告别 Count Distinct 慢查询:StarRocks 高效去重全攻略
在大数据分析中,去重计算(如 Count Distinct)因高计算开销常成为性能瓶颈,尤其在高基数和高并发场景下更为明显。本文以 StarRocks 为分析平台,深入探讨多种去重优化策略,包括使用函数、数据类型转换(如 String 转 Int)、高效数据结构(如 Bitmap 和 HLL),以及物化视图的预计算方案。通过实际案例分析,对比不同方法在性能、精度和易用性方面的优劣,帮助用户在不同业务场景下选择最合适的优化手段。此外,文章还详细解析了如何结合 SQL 查询构建物化视图,以提升去重计算效率,并讨论了精确与近似去重的适用场景。最终目标是为复杂数据分析提供高效、灵活的解决方案。
|
机器学习/深度学习 人工智能 并行计算
【AI系统】Kernel 层架构
推理引擎的Kernel层负责执行底层数学运算,如矩阵乘法、卷积等,直接影响推理速度与效率。它与Runtime层紧密配合,通过算法优化、内存布局调整、汇编优化及调度优化等手段,实现高性能计算。Kernel层针对不同硬件(如CPU、GPU)进行特定优化,支持NEON、AVX、CUDA等技术,确保在多种平台上高效运行。
583 32
|
编解码 iOS开发 Windows
B站电脑版,原来还隐藏着这个白嫖福利|Windows如何打开heic图片?
B站电脑版,原来还隐藏着这个白嫖福利|Windows如何打开heic图片?
|
编译器 C++ 开发者
【C/C++】C/C++编程——第一个 C++ 程序:HelloWorld
【C/C++】C/C++编程——第一个 C++ 程序:HelloWorld
750 0
|
JavaScript 容器
ECharts----九个配置项
ECharts----九个配置项
389 0
|
机器学习/深度学习 算法 数据挖掘
2022年数学建模国赛--赛后总结
2022年全国大学生数学建模比赛已经落下帷幕,每一位坚持到比赛结束的数模人都值得我们去敬佩!
 2022年数学建模国赛--赛后总结
|
网络协议 安全 测试技术
【TCP/IP】【测试】常用发流软件一览
【TCP/IP】【测试】常用发流软件一览
2182 0