简体   繁体   中英

Fixing Box2D Drawings

I am trying to draw a rectangle which would have an edge next to each of its sides (it should represent a building with a fence) for one building it goes quite well, but when I am trying to add a new building it messes itself up completely.

I have this code to create buildings:

class Building():
    def __init__(self, Box_2_World,shape, position, sensor= None):
        self.Box_2_World = Box_2_World
        self.shape = shape
        self.position = position

        if sensor == None:
            sensor = False

        self.sensor = sensor
        self.footprint = self.Box_2_World.CreateStaticBody(position = position,
                                                           angle = 0.0,
                                                           fixtures = b2FixtureDef(
                                                               shape = b2PolygonShape(box=(self.shape)),
                                                               density = 1000,
                                                               friction = 1000))

        self.Lower_Fence = self.Box_2_World.CreateStaticBody(position=(self.footprint.position[0],self.footprint.position[1] -1.75*self.shape[1]))
        self.Lower_Fence.CreateEdgeChain([(self.Lower_Fence.position[0]-4.25*self.shape[0],self.Lower_Fence.position[1]),
                            (self.Lower_Fence.position[0]-2.25*self.shape[0],self.Lower_Fence.position[1]),
                        ])

        self.Right_Fence = self.Box_2_World.CreateStaticBody(position=(self.footprint.position[0]-1*self.shape[0],self.footprint.position[1]))
        self.Right_Fence.CreateEdgeChain([(self.Right_Fence.position[0],self.Right_Fence.position[1] - 1.25*self.shape[1]),
                            (self.Right_Fence.position[0],self.Right_Fence.position[1]-3.25*self.shape[1]),
                        ])

        self.Upper_Fence = self.Box_2_World.CreateStaticBody(position=(self.footprint.position[0],self.footprint.position[1] -0.45* self.shape[1]))
        self.Upper_Fence.CreateEdgeChain([(self.Upper_Fence.position[0] - 4.25* self.shape[0],self.Upper_Fence.position[1]),
                            (self.Upper_Fence.position[0]- 3.25* self.shape[0]+ self.shape[0],self.Upper_Fence.position[1]),
                        ])

        self.Left_Fence = self.Box_2_World.CreateStaticBody(position=(self.footprint.position[0]-2.25*self.shape[0],self.footprint.position[1]))
        self.Left_Fence.CreateEdgeChain([(self.Left_Fence.position[0],self.Left_Fence.position[1] - 1.25*self.shape[1]),
                            (self.Left_Fence.position[0],self.Left_Fence.position[1]-3*self.shape[1]),
                        ])

Skyscrapers = []
Rectangles = [(pos_X-5, pos_Y-5),(pos_X+15, pos_Y -5),(pos_X - 5,pos_Y + 15),(pos_X+15, pos_Y + 15)]

for i in range(4):
    Skyscrapers.append(Building(Box_2_World,shape = (5,5), position =  Rectangles[i]))

and these functions to draw it using PyGame:

SCREEN_OFFSETX, SCREEN_OFFSETY = SCREEN_WIDTH/16, SCREEN_HEIGHT

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)
polygonShape.draw = _draw_polygon

def _draw_edge(edge, screen, body, fixture):
    vertices = fix_vertices(
        [body.transform * edge.vertex1 * PPM, body.transform * edge.vertex2 * PPM])
    pygame.draw.line(screen, colors[body.type], vertices[0], vertices[1])
edgeShape.draw = _draw_edge

And the output is this: Blue rectangles represent buildings, blue lines are fences, first building fits quite nice, but the others are for some reason out of desired positions

Also, if you find out a way how to create the fences using for loop, it would be great (that's the reason why I put for-loop tag into this question)

Any help appreciated

在此处输入图像描述

The coordinates which are passed to CreateEdgeChain have to be relative to the body.

The position of the body is set when the object is constructed eg:

self.Lower_Fence = self.Box_2_World.CreateStaticBody(
    position=(self.footprint.position[0], self.footprint.position[1] -1.75*self.shape[1]))

And the edges have to be relative to this position rather than an absolute position.eg:

self.Lower_Fence.CreateEdgeChain([(-4.25*self.shape[0], 0), (-2.25*self.shape[0], 0)])

To create the fences in a for -loop, you've to define a list of the edges. With the list of the edges you can create a list of fences:

fence_edges = [
    [(-4.25, -1.75), (-2.25, -1.75)],
    [(-1.00, -1.25), (-1.00, -3.25)],
    [(-4.25, -0.45), (-2.25, -0.45)],
    [(-2.25, -1.25), (-2.25, -3.25)]
]

self.Fences = []
for edge in fence_edges:
    p1, p2 = edge
    fence = self.Box_2_World.CreateStaticBody(position=self.footprint.position[:])
    fence.CreateEdgeChain(
        [(p1[0] * self.shape[0], p1[1] * self.shape[1]),
         (p2[0] * self.shape[0], p2[1] * self.shape[1])])
    self.Fences.append(fence)

self.Lower_Fence, self.Right_Fence, self.Upper_Fence, self.Left_Fence = self.Fences

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM