Python Box2D Pygame屏幕坐标到Box2D网格

发布于 2025-01-19 12:50:53 字数 3177 浏览 0 评论 0原文

我无法找出从鼠标坐标获取世界坐标的正确方法。

在这样的问题中: mouseWorld Coords Box2D 有一个方法:box2d.coordPixelsToWorld(x,y);但我在 box2d 的 Python 库中找不到这个方法。

position = pygame.mouse.get_pos() 

position = ??? * ??? 

body.position = position

更多上下文代码:


PPM = 20.0  # pixels per meter
TARGET_FPS = 60
TIME_STEP = 1.0 / TARGET_FPS
SCREEN_WIDTH, SCREEN_HEIGHT = 1280, 720  # 640, 480

# --- pygame setup ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32, display=1)
pygame.display.set_caption('Simple pygame example')
clock = pygame.time.Clock()

body = world.CreateStaticBody(
        position=(i, 1),
        shapes=box2d.b2PolygonShape(box=(1, 1)),
    ))

bodies.append(body)

colors = {
    box2d.b2_staticBody: (255, 255, 255, 255),
    box2d.b2_dynamicBody: (127, 127, 127, 255),
}

# --- main game loop ---
running = True
while running:
    # Check the event queue
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            # The user closed the window or pressed escape
            running = False

    screen.fill((0, 0, 0, 0))
    
    position = pygame.mouse.get_pos() 

    position = ??? * ??? 

    body.position = position

    for body in bodies:  # or: world.bodies
        # The body gives us the position and angle of its shapes
        # body
        for fixture in body.fixtures:
            # The fixture holds information like density and friction,
            # and also the shape.
            shape = fixture.shape

            # Naively assume that this is a polygon shape. (not good normally!)
            # We take the body's transform and multiply it with each
            # vertex, and then convert from meters to pixels with the scale
            # factor.
            vertices = [(body.transform * v) * PPM for v in shape.vertices]

            # But wait! It's upside-down! Pygame and Box2D orient their
            # axes in different ways. Box2D is just like how you learned
            # in high school, with positive x and y directions going
            # right and up. Pygame, on the other hand, increases in the
            # right and downward directions. This means we must flip
            # the y components.
            vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]

            pygame.draw.polygon(screen, colors[body.type], vertices)

    # Make Box2D simulate the physics of our world for one step.
    # Instruct the world to perform a single step of simulation. It is
    # generally best to keep the time step and iterations fixed.
    # See the manual (Section "Simulating the World") for further discussion
    # on these parameters and their implications.
    world.Step(TIME_STEP, 10, 10)

    # Flip the screen and try to keep at the target FPS
    pygame.display.flip()
    clock.tick(TARGET_FPS)

pygame.quit()

if __name__ == "__main__":
    print('Done!')

编辑:PPM 值是每米的像素数。 如果我将 pygame.mouse.get_pos().x 除以 PPM,它就是正确的值。但 y 值偏离 3 '米'

EDIT2:因为它是 (SCREEN_HEIGHT - y) / PPM

I can't figure out the proper way to get the world coordinates from the mouse coords.

In issues like this: mouseWorld Coordinates Box2D there is a method: box2d.coordPixelsToWorld(x,y); but I can't find this method in the Python library for box2d.

position = pygame.mouse.get_pos() 

position = ??? * ??? 

body.position = position

More Code for Context:


PPM = 20.0  # pixels per meter
TARGET_FPS = 60
TIME_STEP = 1.0 / TARGET_FPS
SCREEN_WIDTH, SCREEN_HEIGHT = 1280, 720  # 640, 480

# --- pygame setup ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32, display=1)
pygame.display.set_caption('Simple pygame example')
clock = pygame.time.Clock()

body = world.CreateStaticBody(
        position=(i, 1),
        shapes=box2d.b2PolygonShape(box=(1, 1)),
    ))

bodies.append(body)

colors = {
    box2d.b2_staticBody: (255, 255, 255, 255),
    box2d.b2_dynamicBody: (127, 127, 127, 255),
}

# --- main game loop ---
running = True
while running:
    # Check the event queue
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
            # The user closed the window or pressed escape
            running = False

    screen.fill((0, 0, 0, 0))
    
    position = pygame.mouse.get_pos() 

    position = ??? * ??? 

    body.position = position

    for body in bodies:  # or: world.bodies
        # The body gives us the position and angle of its shapes
        # body
        for fixture in body.fixtures:
            # The fixture holds information like density and friction,
            # and also the shape.
            shape = fixture.shape

            # Naively assume that this is a polygon shape. (not good normally!)
            # We take the body's transform and multiply it with each
            # vertex, and then convert from meters to pixels with the scale
            # factor.
            vertices = [(body.transform * v) * PPM for v in shape.vertices]

            # But wait! It's upside-down! Pygame and Box2D orient their
            # axes in different ways. Box2D is just like how you learned
            # in high school, with positive x and y directions going
            # right and up. Pygame, on the other hand, increases in the
            # right and downward directions. This means we must flip
            # the y components.
            vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]

            pygame.draw.polygon(screen, colors[body.type], vertices)

    # Make Box2D simulate the physics of our world for one step.
    # Instruct the world to perform a single step of simulation. It is
    # generally best to keep the time step and iterations fixed.
    # See the manual (Section "Simulating the World") for further discussion
    # on these parameters and their implications.
    world.Step(TIME_STEP, 10, 10)

    # Flip the screen and try to keep at the target FPS
    pygame.display.flip()
    clock.tick(TARGET_FPS)

pygame.quit()

if __name__ == "__main__":
    print('Done!')

EDIT: The PPM value is the amount on pixels per meter.
If I divide the pygame.mouse.get_pos().x with PPM it is the correct value. But the y value is off by 3 'meters'

EDIT2: Because it is (SCREEN_HEIGHT - y) / PPM

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

东风软 2025-01-26 12:50:53

虽然不熟悉 Python 的 Box2d,但如果您正在寻找的是将鼠标 X,Y 转换为世界 X,Y
只需使用 Box2d 转换因子、PIXEL_PER_METERS 或您使用的任何值转换鼠标 x,y,因此 f.ex
浮动 PIXEL_PER_METER = 100.f;
因此,screenpos 1200, 600 是“box2d 单位/米”中的 12,6

  • ,您已经完成了该操作,但有些偏离,您是否考虑了浮点/整数转换?
    Python 毕竟会调用 C++ Box2d 函数,因此请确保您没有将任何 floats 转换为 integers ,但仔细检查后,您看起来并没有这样做。
  • 相机 ScreenToWorld 或 WorldToScreen ->它们是如何实施的?
    我认为你在某处有类似的东西,
    此问题是相机功能问题的一个相当典型的症状。

但如何将鼠标转换为世界的答案是:
-如果你想要 Box2d 单位的世界:使用比例因子进行转换
-将Camera.Offset值添加到鼠标x,y以获取世界位置

 Camera.MinWorld  <- update this depending on what camera is focused on

 Mouse.x + Camera.MinWorld.x , Mouse.y + Camera.MinWorld.y = world position

world pos到screenpos:
pos.x - Camera.MinWorld.x , pos.y - Camera.MinWorld.y

While not familiar with Box2d for Python, but if what you are looking for is to convert mouse X,Y to world X,Y
just converting the mouse x,y with the Box2d conversion factor, PIXEL_PER_METERS or whatever you use, so f.ex
float PIXEL_PER_METER = 100.f;
thus screenpos 1200, 600 is 12,6 in "box2d units / meters"

  • and you've done that and are somewhat off, have you accounted for floating point / integer conversion?
    Python will after all call a C++ Box2d function, so make sure you're not converting any floats to integers , but on closer inspection it doesnt look like you are doing that.
  • Camera ScreenToWorld or WorldToScreen -> how are they implemented?
    I would think you have something along those lines somewhere,
    this problem is a fairly typical symptom of an issue in the Camera function.

But the answer to how to convert mouse to world is:
-if you want world in Box2d units: convert with the scaling factor
-add the Camera.Offset value to the mouse x,y to get world position

 Camera.MinWorld  <- update this depending on what camera is focused on

 Mouse.x + Camera.MinWorld.x , Mouse.y + Camera.MinWorld.y = world position

world pos to screenpos:
pos.x - Camera.MinWorld.x , pos.y - Camera.MinWorld.y

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文