【问题标题】:Change body color depending on a class根据班级更改车身颜色
【发布时间】:2020-06-06 12:08:07
【问题描述】:

我有一个 Box2D 世界,我正在尝试根据它所属的类来改变身体的颜色。

我有动态物体(Car 和 Pedestrian 类)和静态物体(GroundArea 和 Building 类) 我有这些渲染功能:

def fix_vertices(vertices):
    return [(int(SCREEN_OFFSETX + v[0]), int(SCREEN_OFFSETY - v[1])) for v in vertices]


def _draw_polygon(polygon, screen, body, fixture):
    transform = body.transform
    vertices = fix_vertices([transform * v * PPM for v in polygon.vertices])
    pygame.draw.polygon(
        screen, [c / 2.0 for c in colors[body.type]], vertices, 0)
    pygame.draw.polygon(screen, colors[body.type], vertices, 1)


def _draw_circle(circle, screen, body, fixture):
    position = fix_vertices([body.transform * circle.pos * PPM])[0]
    pygame.draw.circle(screen, colors[body.type],
                       position, int(circle.radius * PPM))


colors = {dynamicBody: (133, 187, 101, 0), staticBody: (15, 0, 89, 0)}


def render():
    global screen, PPM, running
    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
        # Zoom In/Out
        elif event.type == KEYDOWN and event.key == pygame.K_KP_PLUS:
            PPM += 5
        elif event.type == KEYDOWN and event. key == pygame.K_KP_MINUS:
            if PPM <= 5:
                PPM -= 0
            else:
                PPM -= 5

        elif event.type == VIDEORESIZE:
            screen = pygame.display.set_mode(event.dict['size'], HWSURFACE | DOUBLEBUF | RESIZABLE)
    screen.fill((255, 255, 255, 255))
    # Draw the world
    b2CircleShape.draw = _draw_circle
    b2PolygonShape.draw = _draw_polygon

    for body in box2world.bodies:
        for fixture in body.fixtures:
            fixture.shape.draw(screen, body, fixture)

    # Flip the screen and try to keep at the target FPS
    pygame.display.flip()  # Update the full display Surface to the screen
    pygame.time.Clock().tick(FPS)

这在主游戏循环中

 pygame.init()
 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), HWSURFACE | DOUBLEBUF | RESIZABLE)
 colors = {dynamicBody: (133, 187, 101, 0), staticBody: (15, 0, 89, 0)}
 render()

但不幸的是,静态物体具有相同的颜色,而动态物体具有相同的颜色(根据字典颜色)。我试着这样改变它:

colors = {dynamicBody: (133, 187, 101, 0) if isinstance(body, Pedestrian), else (0,0,0,0), staticBody: (15, 0, 89, 0), if isinstance(body, Building), else (121,121,121,0)}

但它不起作用,因为isinstance() 中的body 参数未定义。

您有什么想法可以解决这个问题吗?

非常感谢您的帮助。

附:我知道在render()函数中使用全局变量不好,但是我想不出任何其他的工作方式,所以请不要指出这一点,这不是我的问题。

更新在评论中你想为实例添加代码,所以这里是(一个用于静态主体的类 - 一个建筑物和一个用于动态的body - 行人,其他类定义类似)

from Box2D import b2Filter, b2FixtureDef, b2PolygonShape
from Box2D.b2 import edgeShape
import numpy as np

CAR_CATEGORY = 0x0002
PEDESTRIAN_CATEGORY = 0x0004
BUILDING_CATEGORY = 0x0008


CAR_GROUP = 2
PEDESTRIAN_GROUP = -4
BUILDING_GROUP = -8

class Building():

    BUILDING_FILTER = b2Filter(categoryBits=BUILDING_CATEGORY,
                               maskBits=PEDESTRIAN_CATEGORY + CAR_CATEGORY,
                               groupIndex=BUILDING_GROUP,
                               )

    def __init__(self, box2world, shape, position, color=(0,0,150,0), sensor=None):
        self.box2world = box2world
        self.shape = shape
        self.position = position
        self.color = color

        if sensor is None:
            sensor = False

        self.sensor = sensor
        self.body = self.box2world.CreateStaticBody(position=position,
                                                         angle=0.0,
                                                         fixtures=b2FixtureDef(
                                                             shape=b2PolygonShape(box=(self.shape)),
                                                             density=1000,
                                                             friction=1000,
                                                             filter=Building.BUILDING_FILTER))
        self.body.userData = {'obj': self}
        self.diagonal = np.sqrt(self.shape[0]**2 + self.shape[1]**2)

而这个是行人类

from Box2D import b2Filter, b2FixtureDef, b2PolygonShape, b2CircleShape, b2Vec2
import numpy as np

CAR_CATEGORY = 0x0002
PEDESTRIAN_CATEGORY = 0x0004
BUILDING_CATEGORY = 0x0008


CAR_GROUP = 2
PEDESTRIAN_GROUP = -4

class Pedestrian():
    def __init__(self, box2world, random_movement, ped_velocity, color=(110,0,0,0), position=None):

        if position is None:
            position = [5, 5]
        self.random_movement = random_movement
        self.color = color
        self.ped_velocity = ped_velocity
        self.position = position
        self.box2world = box2world
        self.nearest_building = 0
        self.body = self.box2world.CreateDynamicBody(position=position,
                                                     angle=0.0,
                                                     fixtures=b2FixtureDef(
                                                         shape=b2CircleShape(radius=1),
                                                         density=2,
                                                         friction=0.3,
                                                         filter=b2Filter(
                                                             categoryBits=PEDESTRIAN_CATEGORY,
                                                             maskBits=CAR_CATEGORY + BUILDING_CATEGORY,
                                                             groupIndex=PEDESTRIAN_GROUP)))
        self.current_position = [self.body.position]
        self.body.userData = {'obj': self}

【问题讨论】:

  • 请用Car的代码更新您的问题。
  • 如你所愿,查看代码更新

标签: python colors pygame rendering box2d


【解决方案1】:

在我看来,对于每个需要颜色的类,您可以直接在类本身内部分配一个:

class Car():
    color = (133, 187, 101, 0)

# etc for all bodies that need a color.

然后当你需要它时:

pygame.draw.circle(screen, body.color,

【讨论】:

  • 谢谢,这是一个好点,但是当我尝试运行它时,我在函数中遇到错误 - 例如 - _draw_circle() 对象 b2Body 没有属性颜色,因为如您所见该类在技术上由两部分组成,属性如颜色、尺寸、位置,然后有一个称为 self.body 的物理属性,它是一个 Box2D 实体,具有一定的质量、惯性等。你有什么想法我可以解决这个问题吗?谢谢
  • 您可以在某种设置中为它们分配color 属性吗?
  • 这是我问题的另一部分。 Box2D 与 GUI 无关,它不关心颜色
猜你喜欢
  • 2012-01-25
  • 2017-07-10
  • 2012-08-03
  • 2017-12-07
  • 2016-06-02
  • 2019-06-20
  • 2022-09-23
相关资源
最近更新 更多