使用Python Arcade无法调用Tiled地图对象层的问题求助
解决Arcade PhysicsEngineSimple无法识别Tiled对象层的问题
问题场景
使用Python Arcade 3.0.0.dev32开发俯视角游戏,通过Tiled制作地图,包含Ground瓦片层和Walls对象层(用于碰撞检测)。创建PhysicsEngineSimple时触发报错:
arcade.scene.SceneKeyError: "This scene does not contain a SpriteList named 'Walls'."
原因:Arcade的Scene将瓦片图层存入sprite_list,对象层存入object_list,而PhysicsEngineSimple仅支持遍历sprite_list,因此无法识别Walls对象层。
原代码
class MyGame(arcade.Window): def __init__(self, width, height, title): super().__init__(width, height, title) self.player = Player(center_x=1280 / 2, center_y=720 / 2, scale=1) self.player_list = arcade.SpriteList() self.player_list.append(self.player) # TileMap Object self.tile_map = None # Name of map file to load map_name = "maps/dungeon.tmx" # Layer specific options are defined based on Layer names in a dictionary layer_options = { "Walls": { "use_spatial_hash": True, }, } # Read in the tiled map self.tile_map = arcade.load_tilemap(map_name, 3, layer_options) # Scene Object self.scene = None # Initialize Scene with our TileMap, this will automatically add all layers # from the map as SpriteLists in the scene in the proper order. self.scene = arcade.Scene.from_tilemap(self.tile_map) # Physics engine self.physics_engine = None # --- Other stuff # Create the 'physics engine' self.physics_engine = arcade.PhysicsEngineSimple( self.player, walls=self.scene["Walls"] ) def on_draw(self): self.clear() # Draw our Scene self.scene.draw() self.player_list.draw() def on_update(self, delta_time): self.player.update() self.player.update_animation() def on_key_press(self, key, modifiers): if key == arcade.key.UP or key == arcade.key.W: self.player.change_y = 5 elif key == arcade.key.LEFT or key == arcade.key.A: self.player.change_x = -5 elif key == arcade.key.DOWN or key == arcade.key.S: self.player.change_y = -5 elif key == arcade.key.RIGHT or key == arcade.key.D: self.player.change_x = 5 elif key == arcade.key.SPACE: self.player.change_state(PlayerState.DIE) self.player.change_x = 0 self.player.change_y = 0 def on_key_release(self, key, modifiers): if key == arcade.key.UP or key == arcade.key.W: self.player.change_y = 0 elif key == arcade.key.LEFT or key == arcade.key.A: self.player.change_x = 0 elif key == arcade.key.DOWN or key == arcade.key.S: self.player.change_y = 0 elif key == arcade.key.RIGHT or key == arcade.key.D: self.player.change_x = 0 elif key == arcade.key.SPACE: self.player.change_state(PlayerState.DIE) # pass
解决方案
方案一:将Tiled中的Walls改为瓦片图层
直接在Tiled编辑器中,把Walls对象层转换为瓦片图层。加载地图后,该层会自动成为Scene的SpriteList,原代码中self.scene["Walls"]即可正常被PhysicsEngineSimple识别,无需修改代码逻辑。
方案二:手动将对象层转换为SpriteList
若必须保留对象层,需手动将Walls对象层的对象转换为Sprite并生成SpriteList,再传给物理引擎:
# 在初始化Scene之后添加以下代码 self.walls_sprite_list = arcade.SpriteList(use_spatial_hash=True) # 遍历Walls对象层的所有对象(以矩形对象为例) for obj in self.tile_map.object_lists["Walls"]: # 创建纯色碰撞Sprite,匹配对象尺寸与位置 wall_sprite = arcade.SpriteSolidColor(obj.width, obj.height, arcade.color.GRAY) wall_sprite.center_x = obj.center_x wall_sprite.center_y = obj.center_y self.walls_sprite_list.append(wall_sprite) # 修改物理引擎初始化代码 self.physics_engine = arcade.PhysicsEngineSimple( self.player, walls=self.walls_sprite_list )
注:如果对象层包含多边形或其他形状,需对应调整Sprite创建逻辑,比如使用多边形碰撞精灵或加载对应纹理。
方案三:更换支持对象层的物理引擎(可选)
PhysicsEngineSimple仅支持SpriteList,若使用PhysicsEnginePlatformer等高级引擎,部分可直接处理对象层,但需根据引擎API调整代码逻辑。
内容的提问来源于stack exchange,提问作者eezageeza
相关产品推荐
相关产品推荐

