绕着正方形滚动一个圆

2024-01-05

近一个月后,我仍然停留在这个问题上,我设法决定圆圈(或我所说的行人)是否应该向左/向右或向上/向下移动,但我需要有可能移动行人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")

很难说出你的代码应该做什么。但有些事情很可能是不对的。在

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]))))

你确实创造了行人。不过定位很奇怪。你随机选取一栋建筑(Which_Skyscraper)并将其与另一个随机选取的建筑物(Random_Skyscraper)。这些建筑物可能偶然相同,但更可能是不同的。我认为你打算将行人放置在建筑物内,这需要随机抽取建筑物一次。

更糟糕的是建筑物和行人的损毁

# 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 ...

在这里你可以得到行人的随机索引random.randint(0,len(Johnnie_Walkers)-1)然后将其应用于建筑物列表Skyscrapers[Random_Johnnie].shape[1]/2这是无稽之谈。约翰尼二世与 3 号街的建筑物无关。

还有更难以理解的代码,例如重置滴答计数器Tick_Counter = 0如果无法施加武力。

一些一般提示:

让你的代码可读。正确命名变量。Random_Johnnie可能只在你耳中听起来很有趣。每个人都可以看到索引是随机选择的。但没有任何迹象表明它将用于什么用途。关于什么person_to_start_walking?同样适用于Which_Skyscraper。关于什么building_where_to_generate_person?代码将如何阅读?好多了。

从类似 C 的语言更改为 python 时,一个非常重要的问题是,(几乎)从不使用索引,学会使用引用,它们甚至比索引更便宜。像循环一样for building in buildings:并且在你的情况下使用random.choice()随机挑选人员或建筑物时。这样你就不会意外地在建筑集合上使用人员索引。

另外 - 使用临时变量而不是长嵌套表达式。它更容易阅读,特别是如果它们有好名字的话。不要命名某物Which_Skyscraper如果它是一个位置。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

绕着正方形滚动一个圆 的相关文章

  • 与区域指示符字符类匹配的 python 正则表达式

    我在 Mac 上使用 python 2 7 10 表情符号中的标志由一对表示区域指示符号 https en wikipedia org wiki Regional Indicator Symbol 我想编写一个 python 正则表达式来在
  • Pandas 日期时间格式

    是否可以用零后缀表示 pd to datetime 似乎零被删除了 print pd to datetime 2000 07 26 14 21 00 00000 format Y m d H M S f 结果是 2000 07 26 14
  • Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字

    我正在尝试在 MQL5 中设置一个 PUB 套接字 并在 Python 中设置一个 SUB 套接字来接收消息 我在 MQL5 中有这个 include
  • n 或 nlog(n) 比常数时间或对数时间更好吗?

    在 Coursera 上的普林斯顿教程中 讲师解释了遇到的常见增长顺序函数 他说 线性和线性算术运行时间是 我们努力的目标 他的推理是 随着输入大小的增加 运行时间也会增加 我认为这是他犯了错误的地方 因为我之前听过他提到线性增长顺序对于高
  • 每个术语出现的次数

    我得到了一个数组a n 2 where n can be 10 5最大时有n个科目和n个学生 全部编号为 1 2 n a i 0 and a i 1 1 lt i lt n 表示在第 i 个科目中 所有来自a i 0 to a i 1 通过
  • 在Python中检索PostgreSQL数据库的新记录

    在数据库表中 第二列和第三列有数字 将会不断添加新行 每次 每当数据库表中添加新行时 python 都需要不断检查它们 当 sql 表中收到的新行数低于 105 时 python 应打印一条通知消息 警告 数量已降至 105 以下 另一方面
  • Docker 中的 Python 日志记录

    我正在 Ubuntu Web 服务器上的 Docker 容器中测试运行 python 脚本 我正在尝试查找由 Python Logger 模块生成的日志文件 下面是我的Python脚本 import time import logging
  • 在 Sphinx 文档中*仅*显示文档字符串?

    Sphinx有一个功能叫做automethod从方法的文档字符串中提取文档并将其嵌入到文档中 但它不仅嵌入了文档字符串 还嵌入了方法签名 名称 参数 我如何嵌入only文档字符串 不包括方法签名 ref http www sphinx do
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • pip 列出活动 virtualenv 中的全局包

    将 pip 从 1 4 x 升级到 1 5 后pip freeze输出我的全局安装 系统 软件包的列表 而不是我的 virtualenv 中安装的软件包的列表 我尝试再次降级到 1 4 但这并不能解决我的问题 这有点类似于这个问题 http
  • Python3 在 DirectX 游戏中移动鼠标

    我正在尝试构建一个在 DirectX 游戏中执行一些操作的脚本 除了移动鼠标之外 我一切都正常 是否有任何可用的模块可以移动鼠标 适用于 Windows python 3 Thanks I used pynput https pypi or
  • 使用特定颜色和抖动在箱形图上绘制数据点

    我有一个plotly graph objects Box图 我显示了箱形 图中的所有点 我需要根据数据的属性为标记着色 如下所示 我还想抖动这些点 下面未显示 Using Box我可以绘制点并抖动它们 但我不认为我可以给它们着色 fig a
  • 如何在 Windows 命令行中使用参数运行 Python 脚本

    这是我的蟒蛇hello py script def hello a b print hello and that s your sum sum a b print sum import sys if name main hello sys
  • Python:XML 内所有标签名称中的字符串替换(将连字符替换为下划线)

    我有一个格式不太好的 XML 标签名称内有连字符 我想用下划线替换它 以便能够与 lxml objectify 一起使用 我想替换所有标签名称 包括嵌套的子标签 示例 XML
  • 在本地网络上运行 Bokeh 服务器

    我有一个简单的 Bokeh 应用程序 名为app py如下 contents of app py from bokeh client import push session from bokeh embed import server do
  • 实现 XGboost 自定义目标函数

    我正在尝试使用 XGboost 实现自定义目标函数 在 R 中 但我也使用 python 所以有关 python 的任何反馈也很好 我创建了一个返回梯度和粗麻布的函数 它工作正常 但是当我尝试运行 xgb train 时它不起作用 然后 我
  • 使用for循环时如何获取前一个元素? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 循环内的上一个和下一个值 https stackoverflow com questions 1011938 python previous and next values inside
  • 如何计算Python中字典中最常见的前10个值

    我对 python 和一般编程都很陌生 所以请友善 我正在尝试分析包含音乐信息的 csv 文件并返回最常听的前 n 个乐队 从下面的代码中 每听一首歌曲都是一个列表中的字典条目 格式如下 album Exile on Main Street
  • 我在函数的最后一次递归调用中得到“方案应用程序而不是过程”

    所以这是代码 define time prime test n newline display n start prime test n runtime define start prime test n start time if pri
  • cv2.VideoWriter:请求一个元组作为 Size 参数,然后拒绝它

    我正在使用 OpenCV 4 0 和 Python 3 7 创建延时视频 构造 VideoWriter 对象时 文档表示 Size 参数应该是一个元组 当我给它一个元组时 它拒绝它 当我尝试用其他东西替换它时 它不会接受它 因为它说参数不是

随机推荐