我在我的破砖游戏中遇到了一个问题,在那里球拍有圆形的边缘,我想用完美的Angular 反射球,我使用了Angular 和sin和cos作为方向,但在推荐后我转向了矢量,为了简单起见,我也遇到了类似的问题. 以下是代码:

import sys

import pygame

pygame.init()

w, h = 1200, 800
screen = pygame.display.set_mode((w, h))
clock = pygame.Clock()

class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((10, 10))
        self.image.set_colorkey((0,0,0))
        pygame.draw.circle(self.image, (255, 0, 0), (5, 5), 3)
        self.rect = self.image.get_rect(topleft = (x, y) )
        self.mask = pygame.mask.from_surface(self.image)
        self.velocity = pygame.Vector2(0, -10)

    def update(self, circlex, circley, circle_mask):
        if self.rect.y < 0 or self.rect.y > 800:
            self.kill()
        if self.rect.x < 0 or self.rect.x > 1200:
            self.kill()

        self.rect.y += self.velocity.y
        offset = circlex - self.rect.x, circley - self.rect.y
        if p := self.mask.overlap(circle_mask, offset):
            v = pygame.Vector2(p)
            self.velocity.reflect_ip(v)


    def draw(self, screen):
        screen.blit(self.image, self.rect)


circle = pygame.Surface((400, 400))
pygame.draw.circle(circle, (255, 255, 255), (200, 200), 150)
circle_rect = circle.get_rect(topleft = (400, 100))
circle.set_colorkey((0, 0, 0))
circle_mask = pygame.mask.from_surface(circle)

gun = pygame.Surface((100, 40))
gun_rect = gun.get_rect(topleft = (200, 750))
gun.fill("red")

bullets = pygame.sprite.Group()

while True:
    mx, my = pygame.mouse.get_pos()
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if e.type == pygame.MOUSEBUTTONDOWN:
            b = Bullet(mx, 750)
            bullets.add(b)

    screen.fill((30, 30, 30))


    gun_rect.centerx = mx
    screen.blit(gun, gun_rect)
    screen.blit(circle, circle_rect)

    bullets.update(circle_rect.x, circle_rect.y, circle_mask)
    bullets.draw(screen)

    pygame.display.flip()
    clock.tick(120)

the issue is the bullet is getting straight through the circle, if you could explain how vector works that would be great. vid

推荐答案

通过方向向量的两个分量更改位置

self.rect.center += self.velocity

检测圆圈与子弹的碰撞,而不是反过来:

offset = self.rect.x - circle_rect.x, self.rect.y - circle_rect.y
if p := circle_mask.overlap(self.mask, offset):

反射向量是从圆中心到命中位置的向量:

v = pygame.Vector2(p) - (circle_rect.width/2, circle_rect.height/2)

完整的更新方法:

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

    def update(self, circle_rect, circle_mask):
        if self.rect.y < 0 or self.rect.y > 800:
            self.kill()
        if self.rect.x < 0 or self.rect.x > 1200:
            self.kill()

        self.rect.center += self.velocity
        offset = self.rect.x - circle_rect.x, self.rect.y - circle_rect.y
        if p := circle_mask.overlap(self.mask, offset):
            v = pygame.Vector2(p) - (circle_rect.width/2, circle_rect.height/2)
            self.velocity.reflect_ip(v)
            
# [...]

while True:
    # [...]

    bullets.update(circle_rect, circle_mask)

    # [...]

Python相关问答推荐

具有2D功能的Python十六进制图

使文本输入中的文本与标签中的文本相同

三个给定的坐标可以是矩形的点吗

对Numpy函数进行载体化

try 与gemini-pro进行多轮聊天时出错

对某些列的总数进行民意调查,但不单独列出每列

如何将Docker内部运行的mariadb与主机上Docker外部运行的Python脚本连接起来

如何请求使用Python将文件下载到带有登录名的门户网站?

avxspan与pandas period_range

在vscode上使用Python虚拟环境时((env))

递归访问嵌套字典中的元素值

转换为浮点,pandas字符串列,混合千和十进制分隔符

解决调用嵌入式函数的XSLT中表达式的语法移位/归约冲突

在单次扫描中创建列表

如何获取Python synsets列表的第一个内容?

干燥化与列姆化的比较

PYTHON、VLC、RTSP.屏幕截图不起作用

在Google Drive中获取特定文件夹内的FolderID和文件夹名称

如何在Python 3.9.6和MacOS Sonoma 14.3.1下安装Pyregion

如何在PythonPandas 中对同一个浮动列进行逐行划分?