修复 Box2D 绘图
Fixing Box2D Drawings
我正在尝试绘制一个矩形,它的每边都有一条边(它应该代表一个带有围栏的建筑物)对于一个建筑物来说效果很好,但是当我试图添加一个新的构建它完全搞砸了。
我有创建建筑物的代码:
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]))
以及使用这些函数绘制它 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
输出是这样的:蓝色矩形代表建筑物,蓝线是栅栏,第一个建筑物非常适合,但其他建筑物由于某种原因超出了预期的位置
此外,如果您找到一种使用 for 循环创建围栏的方法,那就太好了(这就是我将 for-loop 标记放入此问题的原因)
感谢任何帮助
传递给 CreateEdgeChain
的坐标必须相对于 body。
body的位置是在构造object时设置的,例如:
self.Lower_Fence = self.Box_2_World.CreateStaticBody(
position=(self.footprint.position[0], self.footprint.position[1] -1.75*self.shape[1]))
并且边缘必须相对于此位置而不是绝对 position.e.g:
self.Lower_Fence.CreateEdgeChain([(-4.25*self.shape[0], 0), (-2.25*self.shape[0], 0)])
要在 for
循环中创建围栏,您必须定义一个边列表。使用边缘列表,您可以创建栅栏列表:
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
我正在尝试绘制一个矩形,它的每边都有一条边(它应该代表一个带有围栏的建筑物)对于一个建筑物来说效果很好,但是当我试图添加一个新的构建它完全搞砸了。
我有创建建筑物的代码:
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]))
以及使用这些函数绘制它 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
输出是这样的:蓝色矩形代表建筑物,蓝线是栅栏,第一个建筑物非常适合,但其他建筑物由于某种原因超出了预期的位置
此外,如果您找到一种使用 for 循环创建围栏的方法,那就太好了(这就是我将 for-loop 标记放入此问题的原因)
感谢任何帮助
传递给 CreateEdgeChain
的坐标必须相对于 body。
body的位置是在构造object时设置的,例如:
self.Lower_Fence = self.Box_2_World.CreateStaticBody(
position=(self.footprint.position[0], self.footprint.position[1] -1.75*self.shape[1]))
并且边缘必须相对于此位置而不是绝对 position.e.g:
self.Lower_Fence.CreateEdgeChain([(-4.25*self.shape[0], 0), (-2.25*self.shape[0], 0)])
要在 for
循环中创建围栏,您必须定义一个边列表。使用边缘列表,您可以创建栅栏列表:
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