我有一组使用PyBox2D表示建筑物的静态实体,我也有表示行人的动态圆(自上而下的可视化),我需要行人沿着建筑物的形状移动(建筑物现在是矩形)。这意味着当它们沿建筑物的水平侧放置时,我希望它们向左/向右移动;当它们沿建筑物的垂直侧放置时,我希望它们向上/向下移动。
我想出了一种算法,如果行人的X轴位置和Y轴的位置之间的差的绝对值大于或等于建筑场地长度的一半+一定的公差,则意味着行人位于垂直方向,应该向上/向下移动,而对于另一个方向则是相反的
我已经在上面描述了预期的结果,但是没有按照应有的方式移动(例如,沿垂直轴的行人向左/向右移动)
非常感谢
编辑:这是更复杂的代码,我试图使其尽可能短:
import numpy as np
import random
import keyboard
import time
import Box2D
from Box2D.b2 import world, polygonShape, circleShape,edgeShape, staticBody, dynamicBody, kinematicBody, revoluteJoint, wheelJoint
from Box2D import b2Vec2, b2FixtureDef,b2PolygonShape, b2CircleShape, b2Dot,b2EdgeShape
import pygame
from pygame import HWSURFACE, DOUBLEBUF, RESIZABLE, VIDEORESIZE
from pygame.locals import (QUIT, KEYDOWN, K_ESCAPE)
pygame.init()
# PyBox2D setup
PPM = 20
SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480
pos_X = SCREEN_WIDTH/PPM/3
pos_Y = SCREEN_HEIGHT/PPM/3
# PyBox2D World initialization
Box_2_World = world(gravity = (0.0, 0.0), doSleep = True)
class Pedestrian():
def __init__(self,Box_2_World, position = None):
if position == None:
position = [5,5]
self.position = position
self.Box_2_World = Box_2_World
self.body = self.Box_2_World.CreateDynamicBody(position = position,
angle = 0.0,
fixtures = b2FixtureDef(
shape = b2CircleShape(radius = 0.5),
density = 2,
friction = 0.3))
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.footprint.sensor = sensor
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]))
Johnnie_Walker = Pedestrian(Box_2_World,position = (8,8))
Johnnie_Walkers = []
############################################################## Pygame visualisation
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), HWSURFACE|DOUBLEBUF|RESIZABLE)
pygame.display.set_caption('Top Down Car Using OOP')
colors = {dynamicBody: (133, 187, 101, 0), staticBody: (15, 0, 89, 0)}
running = True
Tick_Counter = 0
FPS = 24
TIME_STEP = 1.0 / FPS
k = 0
############################### Drawing functions
def my_draw_polygon(polygon, body, fixture):
vertices = [(body.transform * v) * PPM for v in polygon.vertices]
vertices = [(v[0], SCREEN_HEIGHT - v[1]) for v in vertices]
pygame.draw.polygon(screen, colors[body.type], vertices)
polygonShape.draw = my_draw_polygon
def my_draw_circle(circle, body, fixture):
position = body.transform * circle.pos * PPM
position = (position[0], SCREEN_HEIGHT - position[1])
pygame.draw.circle(screen, colors[body.type], [int(
x) for x in position], int(circle.radius * PPM))
circleShape.draw= my_draw_circle
############################### Main game loop
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
# 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:
PPM -= 5
# Draw the world
screen.fill((255, 255, 255, 255))
if event.type==VIDEORESIZE:
screen=pygame.display.set_mode(event.dict['size'],HWSURFACE|DOUBLEBUF|RESIZABLE)
for body in Box_2_World.bodies:
for fixture in body.fixtures:
fixture.shape.draw(body, fixture)
# Generate pedestrians
if not Tick_Counter % FPS:
if k <= len(Skyscrapers)-1: #TO DO: Make number of pedestrians independent on number of buildings
Which_Skyscraper = Skyscrapers[random.randint(0,len(Skyscrapers)-1)].position
Random_Skyscraper = Skyscrapers[random.randint(0,len(Skyscrapers)-1)]
Johnnie_Walkers.append(Pedestrian(Box_2_World, position = (Which_Skyscraper[0] -random.randint(-Random_Skyscraper.shape[0],Random_Skyscraper.shape[0]),Which_Skyscraper[1] -random.randint(-Random_Skyscraper.shape[1],Random_Skyscraper.shape[1]))))
k = k+1
# Make the pedestrian walk
Tick_Counter = Tick_Counter + 1
Random_Johnnie = random.randint(0,len(Johnnie_Walkers)-1)
if abs(Skyscrapers[Random_Johnnie].position[1] - Johnnie_Walkers[Random_Johnnie].position[0]) >= Skyscrapers[Random_Johnnie].shape[1]/2 +1:
Johnnie_Walkers[Random_Johnnie].body.ApplyForce(b2Vec2(5,0), Johnnie_Walkers[Random_Johnnie].body.worldCenter,True)
elif abs(Skyscrapers[Random_Johnnie].position[0] - Johnnie_Walkers[Random_Johnnie].position[1]) >= Skyscrapers[Random_Johnnie].shape[0]/2 +1:
Johnnie_Walkers[Random_Johnnie].body.ApplyForce(b2Vec2(0,5), Johnnie_Walkers[Random_Johnnie].body.worldCenter,True)
else:
Tick_Counter = 0
# Simulate dynamic equation in each step
TIME_STEP = 1.0 / FPS
Box_2_World.Step(TIME_STEP, 10, 10)
# 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.quit()
print('Done!')
[我有一组使用PyBox2D表示建筑物的静态实体,我也有表示行人的动态圆(自上而下的可视化),我需要行人沿着......>
很难说出您的代码应该做什么。但是有些事情很可能是不对的。在
Which_Skyscraper = Skyscrapers[random.randint(0,len(Skyscrapers)-1)].position
Random_Skyscraper = Skyscrapers[random.randint(0,len(Skyscrapers)-1)]
Johnnie_Walkers.append(Pedestrian(Box_2_World, position = \
(Which_Skyscraper[0] -random.randint(-Random_Skyscraper.shape[0],Random_Skyscraper.shape[0]), \
Which_Skyscraper[1] -random.randint(-Random_Skyscraper.shape[1],Random_Skyscraper.shape[1]))))