You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame中基于Vector2实现的球体移动反射角度异常问题求助

Pygame中基于Vector2实现的球体移动反射角度异常问题求助

我在使用Pygame模块时遇到了一个问题。我写了一个小程序,用户可以点击窗口任意位置生成一个小球,小球会以135度(也就是左上方向)的角度开始移动。单独看每个小球的运动好像没什么问题,但如果生成很多小球形成一道“球流”时,就会发现它们的反射角度并不是每次都准确的90度。不是随机错误,是计算出来的问题——原本应该保持45度的移动方向,反射后明显偏得更接近90度了,你运行代码就能明白我说的意思。

以下是我的代码:

import math
import pygame

NE = 45
NW = 135
SW = 225
SE = 315
V = 5
TICK = 60
RADIUS = 10


def convert_degrees_to_radians(angle_degrees):
    return math.radians(angle_degrees)


class Circle:

    def __init__(self, center_pos, direction_angle):
        self.center_pos = center_pos
        self.movement_angle, self.movement_direction = None, None
        self.change_direction(direction_angle)

    def change_direction(self, new_angle):
        self.movement_angle = new_angle
        self.movement_direction = pygame.math.Vector2(math.cos(convert_degrees_to_radians(new_angle)),
                                                      math.sin(convert_degrees_to_radians(new_angle)))

    def change_position(self, new_position):
        self.center_pos = new_position


def draw_circle(position):
    pygame.draw.circle(screen, pygame.Color('white'), position, RADIUS)


if __name__ == '__main__':
    pygame.init()
    pygame.display.set_caption('Balls')
    size = width, height = 1000, 600
    screen = pygame.display.set_mode(size)

    running = True
    circles = []
    clock = pygame.time.Clock()
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                draw_circle(event.pos)
                circles.append(Circle(event.pos, NW))
        screen.fill(pygame.Color('black'))
        clock.tick(TICK)
        for circle in circles:
            new_center_pos = [int(circle.center_pos[0] + V * circle.movement_direction.x),
                              int(circle.center_pos[1] - V * circle.movement_direction.y)]
            circle.change_position(tuple(new_center_pos))
            draw_circle(circle.center_pos)
            if circle.center_pos[0] <= RADIUS:
                if circle.movement_angle == SW:
                    circle.change_direction(SE)
                if circle.movement_angle == NW:
                    circle.change_direction(NE)
            if circle.center_pos[0] >= width - RADIUS:
                if circle.movement_angle == SE:
                    circle.change_direction(SW)
                if circle.movement_angle == NE:
                    circle.change_direction(NW)
            if circle.center_pos[1] <= RADIUS:
                if circle.movement_angle == NW:
                    circle.change_direction(SW)
                if circle.movement_angle == NE:
                    circle.change_direction(SE)
            if circle.center_pos[1] >= height - RADIUS:
                if circle.movement_angle == SW:
                    circle.change_direction(NW)
                if circle.movement_angle == SE:
                    circle.change_direction(NE)
        pygame.display.flip()
    pygame.quit()

我试着自己手动计算方向,不用角度值,但结果还是一样。我怀疑可能是new_center_pos的计算有问题,但实在找不出哪里错了,有没有人能帮我解决这个问题?

备注:内容来源于stack exchange,提问作者Егор Золин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:18:06