Pygame基础8-碰撞

简介: Pygame基础8-碰撞

Collisions

Pygame中,我们使用矩形来移动物体,并且用矩形检测碰撞。

colliderect检测两个矩形是否碰撞,但是没法确定碰撞的方向。

Rect1.colliderect(Rect2)
# collision -> return Ture 
# else -> return False

collidepoint可以确定一个矩形是否和另一个矩形的某个碰撞(并确定碰撞方向),但是会很麻烦,并且很容易遗漏某些碰撞。

Rect1.collidepoint(x, y)
# x,y is the point on a Rect

综合考虑之后,

我们通常使用colliderect来检测碰撞,然后根据两个矩形的相对位置确定碰撞方向。

案例

一个矩形(和边框的碰撞)

# rect1
rect1 = pygame.Rect(100, 100, 50, 50)
color1 = (255, 255, 255)
speed_1_x = 5
speed_1_y = 5

def update_rect():
    global speed_1_x, speed_1_y
    rect1.x += speed_1_x
    rect1.y += speed_1_y

    # rect 和边界的碰撞:
    if rect1.left <= 0 and speed_1_x <0:
        speed_1_x *= -1
    elif rect1.right >= witdth and speed_1_x > 0:
        speed_1_x *= -1

    if rect1.top <= 0 and speed_1_y < 0 :
        speed_1_y *= -1
    elif rect1.bottom >= height and speed_1_y > 0:
        speed_1_y *= -1

    pygame.draw.rect(screen, color1, rect1)

# 在主循环中调用 update_rect()
while True:
    ...
    screen.fill((30, 30, 30))
    update_rect()
    ...

添加第二个矩形

注意:除了判断碰撞方向之外,还要判断矩形的速度方向,以防止矩形在碰撞后反复移动。

# rect2
rect2 = pygame.Rect(200, 200, 200, 50)
color2 = (0, 255, 0)
speed_2_x = 0
speed_2_y = 4 # 为了简化,rect2只在竖直方向上移动


def update_rect():
    global speed_1_x, speed_1_y,  speed_2_y
    ...

    rect2.y += speed_2_y
    # rect 和边界的碰撞:
    ...
    if rect2.top <= 0 and speed_2_y < 0 :
        speed_2_y *= -1
    elif rect2.bottom >= height and speed_2_y > 0:
        speed_2_y *= -1

    # rect1 和 rect2的碰撞
    collide_threshold = 20
    if rect1.colliderect(rect2): 
        if abs(rect1.top - rect2.bottom) < collide_threshold and speed_1_y < 0:
            speed_1_y *= -1
        elif abs(rect1.bottom - rect2.top) < collide_threshold and speed_1_y > 0:
            speed_1_y *= -1
        elif abs(rect1.left - rect2.right) < collide_threshold and speed_1_x < 0:
            speed_1_x *= -1
        elif abs(rect1.right - rect2.left) < collide_threshold and speed_1_x > 0:
            speed_1_x *= -1

    

    pygame.draw.rect(screen, color1, rect1)
    pygame.draw.rect(screen, color2, rect2)

完整案例

两个方块的碰撞。为了简化,rect2只在竖直方向上移动。

import sys
import time
import pygame


# Initialize Pygame
pygame.init()

# Set up the display
witdth = 800
height = 600
screen = pygame.display.set_mode((witdth, height))

# Set up the clock
clock = pygame.time.Clock()


# rect1
rect1 = pygame.Rect(100, 100, 50, 50)
color1 = (255, 255, 255)
speed_1_x = 5
speed_1_y = 5

# rect2
rect2 = pygame.Rect(200, 200, 300, 50)
color2 = (0, 255, 0)
speed_2_x = 0 
speed_2_y = 4 # 为了简化,rect2只在竖直方向上移动

def update_rect():
    global speed_1_x, speed_1_y, speed_2_x, speed_2_y
    rect1.x += speed_1_x
    rect1.y += speed_1_y

    #rect2.x += speed_2_x
    rect2.y += speed_2_y

    # rect 和边界的碰撞:
    if rect1.left <= 0 and speed_1_x <0:
        speed_1_x *= -1
    elif rect1.right >= witdth and speed_1_x > 0:
        speed_1_x *= -1

    if rect1.top <= 0 and speed_1_y < 0 :
        speed_1_y *= -1
    elif rect1.bottom >= height and speed_1_y > 0:
        speed_1_y *= -1
    
    
    if rect2.top <= 0 and speed_2_y < 0 :
        speed_2_y *= -1
    elif rect2.bottom >= height and speed_2_y > 0:
        speed_2_y *= -1
        #以 HH:MM:SS 的格式 输出当前时间 
        form_time1 = time.strftime("%H:%M:%S", time.localtime())
        print('rect2 to bottom', 'time= ', form_time1)

    # rect1 和 rect 2的碰撞
    collide_threshold = 20
    if rect1.colliderect(rect2): 
        if abs(rect1.top - rect2.bottom) < collide_threshold and speed_1_y < 0:
            speed_1_y *= -1
            
        if abs(rect1.bottom - rect2.top) < collide_threshold and speed_1_y > 0:
            speed_1_y *= -1
        
        if abs(rect1.left - rect2.right) < collide_threshold and speed_1_x < 0:
            speed_1_x *= -1
         
        if abs(rect1.right - rect2.left) < collide_threshold and speed_1_x > 0:
            speed_1_x *= -1
         

    # Draw the rect
    pygame.draw.rect(screen, color1, rect1)
    pygame.draw.rect(screen, color2, rect2)

while True:
    # Handle events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    screen.fill((30, 30, 30))
    update_rect()
    # Update the display
    pygame.display.flip()

    # Cap the frame rate
    clock.tick(60)
目录
打赏
0
0
0
0
48
分享
相关文章
|
10月前
|
数据收集方法
数据收集方法
494 1
在VS2022上安装pygame模块
【10月更文挑战第4天】这是在VS2022中安装Pygame模块的步骤:首先确认已安装Python环境,并通过“工具”-&gt;“Python”-&gt;“Python环境”进行检查;接着打开VS2022集成终端;然后输入`pip install pygame`安装Pygame;最后,在Python脚本中导入Pygame验证安装是否成功。如遇问题,请检查网络连接、权限及Python环境配置。对于权限问题,需以管理员身份运行命令提示符或终端。某些系统可能需要安装额外的系统级依赖项。
319 5
OpenSPG 新版发布:新增大模型知识抽取,3 步快速搭建专属知识图谱
OpenSPG 新版发布,支持大模型增强的图谱构建,仅需 3 个步骤快速搭建专属知识图谱。
OpenSPG 新版发布:新增大模型知识抽取,3 步快速搭建专属知识图谱
MaxCompute ODPS重装上阵, IF ELSE分支语句
MaxCompute通过脚本模式支持IF ELSE分支语句,让程序根据条件自动选择执行逻辑,支持更好的处理因数据不同而需要采用不同策略的业务场景产生的复杂SQL,提高开发者编程的灵活性!
1218 2
esquisse包—不写代码生成ggplot图
esquisse包—不写代码生成ggplot图
125 5
settime计时器和POSIX timer函数
settime计时器和POSIX timer函数
328 0
编排系统K8S Ingress-nginx源码解析
上篇文章介绍了Ingress-nginx的基本架构原理,具体可参考: 编排系统K8S Ingress-nginx介绍 本篇重点以源码为基础,深入讲解 Ingress-nginx的内部工作流以及整体工作模式。
334 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问