近一个月后,我仍然停留在这个问题上,我设法决定圆圈(或我所说的行人)是否应该向左/向右或向上/向下移动,但我需要有可能移动行人around一座建筑物(这意味着他们必须转角,基本上无论方向如何,他们只需要转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!')
所以基本上有两个目标,一是让行人转弯(可能我必须在施加垂直力之前施加与他们现在正在移动的方向平行的力,这样他们就会立即停下来并then转但我不知道该怎么做(或者可能有不同的解决方案,这就是我问的原因)
另一个目标是在 for 循环中执行此操作,因为在我的游戏中有四个建筑物...我尝试将其放入 for 循环中但失败了(如果需要,我可以稍后发布我的 for 循环,但请我需要解决我的第一个问题。
免责声明你们中的一些人可能会注意到,在我的第二个用户帐户下,GameDev.StackExchange.com 上出现了几乎相同的问题,我不知道为什么创建另一个帐户,但我知道这不是一个好的解决方案,对此我感到抱歉。我只是想请你不要谈论我为什么创建新帐户以及它很糟糕......我知道这一点,我再次为此感到抱歉......
我在这里提出问题的原因是我认为这里是一个更好的地方,有两个原因,第一:它更多的是算法问题而不是游戏开发问题,第二:SO 比 GameDev 更忙,我被困在这个问题上很长一段时间了,所以我真的需要帮助
EDIT:我设法将此属性添加到建筑类并将其实现到行人行走函数中,它偶尔会起作用,但我该如何改进它呢?或者也许让它更“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")