You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:43:09