python - 有没有办法可以优化多个 python for 循环?
问题描述
我正在尝试制作多人网络游戏,我有一个用 python 完成的服务器。由于游戏是多人游戏,我需要单独更新每个玩家;这需要for
循环,目前我的代码使用了很多 for 循环,这给我带来了一些不必要的副作用。副作用包括速度减慢。我对 for 循环的另一个问题是,它们会根据循环的次数来改变速度;这导致了一个问题,即循环需要循环的项目数量会根据连接的玩家数量而变化,从而弄乱了我为掩盖延迟而制作的客户端预测功能。
这是我的主要代码:
PlayerData = {}
for Player in Players:
if(Player.id > 50):
PlayerData['playerx' + str(Player.id)] = Player.x
PlayerData['playery' + str(Player.id)] = Player.y
PlayerData['playera' + str(Player.id)] = int(Player.angle)
PlayerData['playerstat' + str(Player.id)] = Player.alive
if(Player.id > 50):
if(Player.alive == 0):
Players.remove(Player)
for ID in clientIds:
PlayerData['id'] = str(clientIds[len(clientIds) - 1].id)
PlayerData['players'] = ids
if(Player.id <= 50):
hrIds.append(Player.id)
PlayerData['hx' + str(Player.id)] = Player.x
PlayerData['hy' + str(Player.id)] = Player.y
#PlayerData['ha' + str(Player.id)] = int(Player.angle)
PlayerData['hr'] = hrIds
PlayerJsonData = json.dumps(PlayerData)
await websocket.send(PlayerJsonData)
recivedData = await websocket.receive()
rData = json.loads(recivedData)
for ID in clientIds:
if(rData['id'] == str(ID.id)):
if(ID.IG == 0):
if(rData['playerstat'] == 1):
Players.append(player_classes.Basic(-1300, -1300, ID.ws, ID.id, 1))
ID.IG = 1
for Player in Players:
for Player2 in Players:
if(Player.id > 50):
Player.detect_collide(Player2)
if(rData['id'] == str(Player.id)):
if(rData['direction'] == "up"):
Player.accelerate(rData['direction'])
Player.moveUp(Player2)
if(rData['direction'] == "left"):
Player.accelerate(rData['direction'])
Player.moveLeft(Player2)
if(rData['direction'] == "down"):
Player.accelerate(rData['direction'])
Player.moveDown(Player2)
if(rData['direction'] == "right"):
Player.accelerate(rData['direction'])
Player.moveRight(Player2)
if(rData['direction'] == "none"):
Player.decelerate(rData['direction'])
编辑:我的主要循环速度问题发生在我添加更多类时Players
解决方案
您应该避免两次检查同一对玩家的碰撞。
让我们举一个非常简单的例子,Players
列表包含 0、1、2、3。
使用您的代码,您会得到很多冗余测试:
- 在循环 0 中,您针对 1、2 和 3 测试 0
- 在循环 1 中,您针对 0、2 和 3 测试 1 ===>(但已经测试了 0-1)
- 在循环 2 中,您针对 0、1 和 3 测试 2 ===>(但 0-2 / 1-2 已经测试过)
- 在循环 3 中,您针对 0、1 和 2 测试 3 ===>(但已经测试了 0-3 / 1-3 / 2-3)
所以而不是:
for Player in Players:
for Player2 in Players:
做:
for i, Player in enumerate(Players):
for Player2 in Players[i + 1:]:
如果我们再次使用包含 0、1、2、3 的列表,我们会有以下行为:
- 在循环 0 中,您针对 1、2、3 测试 0
- 在循环 1 中,您针对 2、3 测试 1
- 在循环 2 中,您针对 3 测试 2
这样,它将迭代次数从 N^2 减少到 N(N-1)/2。
推荐阅读
- python - 如何用 Numpy Python 获取多张图像的 RGB 单通道的平均值?
- neo4j - docker-compose healthcheck 不适用于 neo4j docker
- javascript - 暂停圆形菜单的 CSS 动画以打开和关闭
- javascript - 使用唯一的“key”道具反应过滤器项目并且是空比较
- javascript - 使用 django 和 AJAX 在填充字段中提交表单后,“此字段为必填项”
- javascript - 节点 JS Dialogflow 错误:INVALID_ARGUMENT:未设置输入文本。?
- c - 来自 Ua_Variant 的 C 类型转换
- swift - 如何使用“空”谓词创建 NSCompoundPredicate
- firebase - 将 contains() 与 firebase 规则一起使用
- mysql - SQL 查询根据条件返回额外的列