Pygame 面具碰撞

2025-03-05 09:15:00
admin
原创
63
摘要:问题描述:我正在尝试在 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大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2793  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1710  
  产品开发是企业的核心竞争力之一,如何提升产品开发质量一直是企业关注的重点。IPD(集成产品开发)和六西格玛作为两种重要的管理理念和方法,在提升产品开发质量方面都有着显著的成效。将两者协同起来,能够发挥更大的优势,为企业打造高质量的产品提供有力支持。IPD与六西格玛概述IPD是一套产品开发的模式、理念与方法,它强调以市场...
IPD框架   0  
  IPD(集成产品开发)研发流程与 PLM(产品生命周期管理)系统的集成,在当今企业的产品创新与管理领域正发挥着日益关键的作用。随着科技的飞速发展和市场竞争的不断加剧,对二者集成的趋势进行深入分析,有助于企业提前布局,提升自身的核心竞争力。2025 年,这一集成领域预计将呈现出一系列引人瞩目的趋势,为企业的发展带来新的机...
IPD流程中PDCP是什么意思   0  
  产品开发周期的压缩对于企业在市场中获取竞争优势至关重要。IPD(集成产品开发)和关键链项目管理作为两种有效的项目管理方法,各自有着独特的优势。将它们有机结合,能够为压缩开发周期提供强大的助力。本文将深入探讨IPD与关键链项目管理结合的原理、方法以及如何实现开发周期的有效压缩。IPD概述IPD是一种先进的产品开发管理理念...
IPD流程   0  
热门文章
项目管理软件有哪些?
曾咪二维码

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

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

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用