粒子没有移动,那么问题是什么?

The particle is not moving so what is the problem?

我关注了一个 youtube 视频 'https://www.youtube.com/watch?v=cCiXqK9c18g',在视频中他制作了一个 class 代表一个球,他使用 pymunk 制作了一个主体并将其添加到 space 并且之后他在球内创建了一个方法 class 将使用 pygame 来绘制球,我几乎喜欢他

import pygame
import pymunk

pygame.init()

fps = 60
dt = 1/fps
dsX = 800 # screen width
dsY = 500 # screen height

display = pygame.display.set_mode((dsX, dsY))
space = pymunk.Space()
clock = pygame.time.Clock()

def convert_cor(point): # convet the coordinates from pymunk to pygame coordinates
    return point[0], dsY - point[1]

class Particle: # v: velocity, pos: position[x, y], r: radius of particle(Circle)

    def __init__(self, pos = [0, 0], v = [0, 0], r = 10, color = (255, 0, 0)):

        self.pos = pos
        self.v = v
        self.r = r
        self.color = color
        self.body = pymunk.Body()
        self.body.position = self.pos
        self.body.velocity = self.v # this is the veclocity
        self.shape = pymunk.Circle(self.body, self.r)
        self.shape.dencity = 1
        self.shape.elasticity = 1
        space.add(self.body, self.shape)

    def draw(self):

        pygame.draw.circle(display, self.color, convert_cor(self.pos), self.r)

class Box: # thickness of the sides of the box and L1, L2, L3, L4 are the sides of the box

    def __init__(self, thickness, color):

        self.thickness = thickness
        self.color = color
        L1 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L2 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L3 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L4 = pymunk.Body(body_type = pymunk.Body.STATIC)
        L1_shape = pymunk.Segment(L1, (0, 0), (dsX, 0), self.thickness)
        L2_shape = pymunk.Segment(L2, (dsX, 0), (dsX, dsY), self.thickness)
        L3_shape = pymunk.Segment(L3, (dsX, dsY), (0, dsY), self.thickness)
        L4_shape = pymunk.Segment(L4, (0, dsY), (0, 0), self.thickness)
        space.add(L1, L1_shape)
        space.add(L2, L2_shape)
        space.add(L3, L3_shape)
        space.add(L4, L4_shape)

    def draw(self):

        pygame.draw.line(display, self.color, convert_cor((0, 0)), convert_cor((dsX, 0)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((dsX, 0)), convert_cor((dsX, dsY)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((dsX, dsY)), convert_cor((0, dsY)), self.thickness * 2)
        pygame.draw.line(display, self.color, convert_cor((0, dsY)), convert_cor((0, 0)), self.thickness * 2)

def Sim(): # the infinite while loop as a function

    box = Box(2, (0, 255, 255))
    particle = Particle(pos =[dsX/2, dsY/2], v = [-200, 500]) # here i gave the position and the velocity

    while True:

        for event in pygame.event.get():

            if event.type == pygame.QUIT:

                return

        display.fill((255, 255, 255))
        box.draw()
        particle.draw()
        clock.tick(fps)
        space.step(dt)
        pygame.display.update()

Sim()

pygame.quit()

事实是,我还做了一个 class,它将为显示器添加一个刚性边,我使用 'draw' [=] 方法从盒子 class 中绘制边15=]问题出在 5:58 视频中,他给了球速度,球开始移动,而在我的代码中,它没有移动。知道为什么它不动吗? 注意:我在我的代码中调用了球粒子

您的错误既是拼写错误又是使用了错误的变量。

在你的粒子绘制函数中...

# OLD
def draw(self):
        pygame.draw.circle(display, self.color, convert_cor(self.pos), self.r)

# New
def draw(self):
        pygame.draw.circle(display, self.color, convert_cor(self.body.position), self.r)

你必须使用 body 的位置,因为它是物理 body 在 pymunk 的 space 中的位置。

其次...

class Particle: # v: velocity, pos: position[x, y], r: radius of particle(Circle)

    def __init__(self, pos, v, r=10, color=(255, 0, 0)):
        ...
        # Old
        self.shape.dencity = 1
    
        # New
        self.shape.density = 1

由于密度没有设置为任何 Pymunk 出现被零除的错误,所以它不会更新 body 的位置。

self.body.position = self.pos

要弄清楚问题:

根据我在文档中找到的内容,pymunk.Body.position 是 属性;它希望您传递一个普通的 Python 元组或一个 Vec2d (不是列表,尽管它在内部依赖于处理元组的任何东西可能都可以很好地处理列表),并调用一些编写的内部代码在另一种编程语言中。效果是,不是存储您的列表对象然后更改列表( 在您的 class 中可见,因为它是同一个对象),它只是从您的列表中获取初始值,然后不使用列表对象。

这意味着当 Pymunk 应用物理计算时,self.body.position 会发生变化,但 self.pos 不会。所以当前的self.pos没用;我们不能用它来检查对象位置。

如果你不需要这样做,那么根本不需要创建 self.pos - 直接输入 self.body.position = pos,并确保使用 self.body.position画的时候

如果您这样做,我建议您使用自己的 属性 而不是尝试设置 self.pos。执行以上操作,然后添加到 class:

@property
def pos(self):
    return self.body.position

如果您想更改代码中的位置(但您可能不应该这样做!您为什么首先使用物理引擎?),还添加:

@pos.setter
def pos(self, value):
    self.body.position = value