我已经卡了将近一个月了,始终无法解决这个问题。我设法决定圆圈(或者我称之为行人)应该向左/右移动还是向上/下移动,但我需要让行人有可能绕过一个建筑物(也就是说,他们必须在拐角处转弯,基本上无论朝向如何,他们都只需要转90度)。
非常感谢!
import numpy as np
import random
import keyboard
from Box2D.b2 import world, polygonShape, circleShape, edgeShape, staticBody, dynamicBody, kinematicBody, revoluteJoint, wheelJoint
from Box2D import b2Vec2, b2FixtureDef, b2PolygonShape, b2CircleShape, b2Dot, b2EdgeShape, b2Contact,b2ContactFilter,b2Filter,b2ContactListener,b2GetPointStates
import pygame
from pygame import HWSURFACE, DOUBLEBUF, RESIZABLE, VIDEORESIZE
from pygame.locals import (QUIT, KEYDOWN, K_ESCAPE)
pygame.init()
box2world = world(contactListener = MyContactListener(), gravity = (0.0, 0.0), doSleep = True)
class Pedestrian():
def __init__(self,box2world, position = None):
if position == None:
position = [5,5]
self.position = position
self.box2world = box2world
self.Current_Position = []
self.body = self.box2world.CreateDynamicBody(position = position,
angle = 0.0,
fixtures = b2FixtureDef(
shape = b2CircleShape(radius = 0.5),
density = 2,
friction = 0.3,
))
class Building():
def __init__(self, box2world,shape, position, sensor= None):
self.box2world = box2world
self.shape = shape
self.position = position
if sensor == None:
sensor = False
self.corners = [((self.position[0] + self.shape[0]), (self.position[1] + self.shape[1])),
((self.position[0] + self.shape[0]), (self.position[1] - self.shape[1])),
((self.position[0] - self.shape[0]), (self.position[1] - self.shape[1])),
((self.position[0] - self.shape[0]), (self.position[1] + self.shape[1]))]
self.sensor = sensor
self.footprint = self.box2world.CreateStaticBody(position = position,
angle = 0.0,
fixtures = b2FixtureDef(
shape = b2PolygonShape(box=(self.shape)),
density = 1000,
friction = 1000))
############################################################## Pygame visualisation
PPM = 10
SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480
SCREEN_OFFSETX, SCREEN_OFFSETY = SCREEN_WIDTH/16, SCREEN_HEIGHT
POS_X = SCREEN_WIDTH/PPM/3
POS_Y = SCREEN_HEIGHT/PPM/3
MAX_AMOUNT_PEDESTRIANS = 10
FPS = 24
TIME_STEP = 1.0 / FPS
k = 0
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)}
walkers = []
skyscraper = Building(box2world,shape = (5,5), position = (POS_X + 3, POS_Y + 5))
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_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))
circleShape.draw = _draw_circle
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
running = False
screen.fill((255, 255, 255, 255))
for body in box2world.bodies:
for fixture in body.fixtures:
fixture.shape.draw(screen, body, fixture)
if k <= MAX_AMOUNT_PEDESTRIANS:
walkers.append(Pedestrian(box2world, position = (skyscraper.position[0] -random.randint(-skyscraper.shape[0],skyscraper.shape[0]),\
skyscraper.position[1] -random.randint(-skyscraper.shape[1],skyscraper.shape[1]))))
k = k+1
for walker in walkers:
pedestrian_walk(walker,skyscraper)
# Simulate dynamic equation in each step
TIME_STEP = 1.0 / FPS
box2world.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!')
所以基本上有两个目标,一个是让行人转弯(可能在施加垂直力之前需要施加与其现在相反方向的平行力,使他们立即停下来,然后再转弯,但我不知道如何做到这一点(或者也许有不同的解决方案,这就是我在问的原因)。
另一个目标是在for循环中实现这一点,因为在我的游戏中有四座建筑物...我试图把它放在for循环中,但失败了(如果有要求,我可以稍后发布我的for循环,但请先解决我的第一个问题。)
免责声明:有些人可能会注意到,几乎相同的问题出现在GameDev.StackExchange.com上,在我的第二个用户帐户下,我不知道我为什么创建了另一个帐户,但我知道那不是一个好的解决办法,对此我很抱歉。我只是想要求您不要谈论我为什么创建了新帐户以及它不好......我知道这一点,再次对此表示歉意...
我把问题放在这里的原因是我认为这里是更好的地方,有两个原因:首先:这更像是一个算法问题而不是一个游戏开发问题;其次:SO比GameDev繁忙得多,我已经卡在这里很长时间了,所以我真的需要帮助。
编辑:我设法将此属性添加到Building类并将其实现到pedestrian_walk函数中,它偶尔会起作用,但我该如何改进它?或者使它更具“pythonic性”?非常感谢。
def pedestrian_walk(Pedestrian, Building):
if Pedestrian.body.position[0] <= Building.position[0] and Building.position[1] - Building.shape[1] < Pedestrian.position[1] < Building.position[1] + Building.shape[1]:
Pedestrian.body.__SetLinearVelocity(b2Vec2(0,10))
elif Pedestrian.body.position[0] > Building.position[0] and Building.position[1] - Building.shape[1] < Pedestrian.position[1] < Building.position[1] + Building.shape[1]:
Pedestrian.body.__SetLinearVelocity(b2Vec2(0,-10))
elif Pedestrian.body.position[1] > Building.position[1] and Building.position[0] - Building.shape[0] < Pedestrian.position[0] < Building.position[0] + Building.shape[0]:
Pedestrian.body.__SetLinearVelocity(b2Vec2(10,0))
elif Pedestrian.body.position[1] <= Building.position[1] and Building.position[0] - Building.shape[0] < Pedestrian.position[0] < Building.position[0] + Building.shape[0]:
Pedestrian.body.__SetLinearVelocity(b2Vec2(-10,0))
if ((Building.corners[0][0] -0.5 <= Pedestrian.body.position[0] <= Building.corners[0][0] + 0.5 and\
Building.corners[0][1] -0.5 <= Pedestrian.body.position[1] <= Building.corners[0][1] + 0.5)):
Pedestrian.body.__SetLinearVelocity(b2Vec2(-100,100))
print("Changing direction")
elif((Building.corners[1][0] -0.5 <= Pedestrian.body.position[0] <= Building.corners[1][0] + 0.5 and\
Building.corners[1][1] -0.5 <= Pedestrian.body.position[1] <= Building.corners[1][1] + 0.5)):
Pedestrian.body.__SetLinearVelocity(b2Vec2(-100,200))
print("Changing direction")
elif((Building.corners[2][0] -0.5 <= Pedestrian.body.position[0] <= Building.corners[2][0] + 0.5 and\
Building.corners[2][1] -0.5 <= Pedestrian.body.position[1] <= Building.corners[2][1] + 0.5)):
Pedestrian.body.__SetLinearVelocity(b2Vec2(-100,200))
print("Changing direction")
elif((Building.corners[3][0] -0.5 <= Pedestrian.body.position[0] <= Building.corners[3][0] + 0.5 and\
Building.corners[3][1] -0.5 <= Pedestrian.body.position[1] <= Building.corners[3][1] + 0.5)):
Pedestrian.body.__SetLinearVelocity(b2Vec2(-100,200))
print("Changing direction")
append
,我可能会认为Skyscrapers
是一个列表,但我不能确定。然而,Skyscrapers[Random_Johnnie]
感觉就不对。 - stefan