Pygame 面具碰撞

2025-03-05 09:15:00
admin
原创
61
摘要:问题描述:我正在尝试在 pygame 中对旋转表面进行正确的碰撞检测。我决定尝试使用遮罩。它在某种程度上有效,但并不像我希望/想象的那样精确。我尝试在循环结束时更新遮罩以获得下一帧的“新鲜”碰撞箱,但它没有按预期工作。我的错误是什么?import pygame import random WHITE = [...

问题描述:

我正在尝试在 pygame 中对旋转表面进行正确的碰撞检测。我决定尝试使用遮罩。它在某种程度上有效,但并不像我希望/想象的那样精确。我尝试在循环结束时更新遮罩以获得下一帧的“新鲜”碰撞箱,但它没有按预期工作。我的错误是什么?

import pygame
import random

WHITE = [255, 255, 255]
RED = [255, 0, 0]

pygame.init()

FPS = pygame.time.Clock()
fps = 6

winW = 1000
winH = 500
BGCOLOR = WHITE
win = pygame.display.set_mode((winW, winH))
win.fill(WHITE)
pygame.display.set_caption('')
pygame.display.set_icon(win)


class Box(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([w, h], pygame.SRCALPHA)
        self.image.fill(random_color())
        self.mask = pygame.mask.from_surface(self.image)
        self.rect = pygame.Rect(x, y, w, h)
        self.angle = 0

    def move(self):
        self.rect.center = pygame.mouse.get_pos()

    def draw(self):
        blits = self.rotate()
        win.blit(blits[0], blits[1])
        self.mask = pygame.mask.from_surface(blits[0])

    def rotate(self):
        self.angle += 3
        new_img = pygame.transform.rotate(self.image, self.angle)
        new_rect = new_img.get_rect(center=self.rect.center)
        return new_img, new_rect


def update_display():
    win.fill(BGCOLOR)
    player.draw()
    for p in platforms:
        p.draw()
    pygame.display.update()


def collision():
    return pygame.sprite.spritecollide(player, plat_collide, False, pygame.sprite.collide_mask)


def random_color():
    return [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]


player = Box(100, 400, 50, 50)

platforms = [Box(300, 400, 100, 50)]
plat_collide = pygame.sprite.Group(platforms)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    hits = collision()
    if hits:
        BGCOLOR = RED
    else:
        BGCOLOR = WHITE

    player.move()

    update_display()

    FPS.tick(fps)

pygame.quit()

解决方案 1:

您的应用程序运行良好。但请注意,pygame.sprite.collide_mask()使用精灵对象的.rect和属性进行碰撞检测。旋转图像后
您必须更新:.mask
self.rect

class Box(pygame.sprite.Sprite):
    # [...]

    def rotate(self):
        self.angle += 3
        new_img = pygame.transform.rotate(self.image, self.angle)
        new_rect = new_img.get_rect(center=self.rect.center)
        
        # update .rect attribute
        self.rect = new_rect # <------
        
        return new_img, new_rect

另请参阅精灵遮罩


最小示例:![IT科技](https://i.sstatic.net/5jD0C.png) repl.it/@Rabbid76/PyGame-SpriteMask

IT科技

import pygame

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h, color):
        pygame.sprite.Sprite.__init__(self)
        self.angle = 0
        self.original_image = pygame.Surface([w, h], pygame.SRCALPHA)
        self.original_image.fill(color)
        self.image = self.original_image
        self.rect = self.image.get_rect(center = (x, y))
        self.mask = pygame.mask.from_surface(self.image )
    def update(self):
        self.rotate()
    def rotate(self):
        self.angle += 0.3
        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = self.rect.center)
        self.mask = pygame.mask.from_surface(self.image )

pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((400, 400))
size = window.get_size()

moving_object = SpriteObject(0, 0, 50, 50, (128, 0, 255))
static_objects = [
    SpriteObject(size[0] // 2, size[1] // 3, 100, 50, (128, 128, 128)),
    SpriteObject(size[0] // 4, size[1] * 2 // 3, 100, 50, (128, 128, 128)),
    SpriteObject(size[0] * 3 // 4, size[1] * 2 // 3, 100, 50, (128, 128, 128))
]
all_sprites = pygame.sprite.Group([moving_object] + static_objects)
static_sprites = pygame.sprite.Group(static_objects)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    moving_object.rect.center = pygame.mouse.get_pos()
    all_sprites.update() 
    collide = pygame.sprite.spritecollide(moving_object, static_sprites, False, pygame.sprite.collide_mask)
    
    window.fill((255, 0, 0) if collide else (255, 255, 255))
    all_sprites.draw(window)
    pygame.display.update()

pygame.quit()
exit()
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2787  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1710  
  产品配置管理在企业产品研发与生产过程中扮演着至关重要的角色,它能够确保产品在不同阶段的一致性、可追溯性以及高效的变更管理。PLM(产品生命周期管理)系统作为整合产品全生命周期信息的平台,为产品配置管理提供了强大的支持。随着技术的不断发展,到2025年,PLM系统在支持产品配置管理方面将有一系列值得关注的技术实践。基于人...
plm系统主要干什么的   11  
  敏捷迭代周期与 PLM 流程的适配是现代企业在产品开发过程中面临的重要课题。随着市场竞争的加剧和技术的快速发展,企业需要更加高效、灵活的产品开发模式,以满足客户不断变化的需求。敏捷迭代周期强调快速响应变化、持续交付价值,而 PLM 流程则侧重于产品全生命周期的管理和控制。如何将两者有机结合,优化交付节奏,成为提升企业竞...
plm是什么意思   10  
  在企业的数字化转型进程中,PLM(产品生命周期管理)与ERP(企业资源计划)作为两款重要的企业级系统,发挥着关键作用。然而,很多企业人员对它们之间的区别以及协同逻辑并不十分清晰。深入了解这两者的差异与协同方式,有助于企业更好地规划信息化建设,提升整体运营效率。PLM系统概述PLM系统聚焦于产品从概念设计到退役的全生命周...
国产plm软件   12  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用