Tiled 图像集合瓦片集(Image Collection Tileset)实战:Sticker Knight 横版平台跳跃示例深度解析
Tiled 图像集合瓦片集Image Collection Tileset实战Sticker Knight 横版平台跳跃示例深度解析【免费下载链接】tiledFlexible level editor项目地址: https://gitcode.com/gh_mirrors/ti/tiled本文围绕 Tiled 官方示例examples/sticker-knight/展开它由 ponywolf 制作并已释放到公有领域Public Domain。该示例是学习 Tiled **图像集合瓦片集Image Collection Tileset与瓦片对象Tile Object**的绝佳范本整个横版平台跳跃关卡——从背景、地面、城堡到 UI 界面——没有使用任何传统瓦片图层而是全部由放置在对象图层上的瓦片对象构成。读完本文你将掌握图像集合瓦片集的创建方式、TMX/JSON 两种文件格式下的数据结构、模板Template与对象图层的实战用法以及视差Parallax和世界文件World的搭配技巧。示例概览一个全对象图层驱动的平台跳跃关卡examples/sticker-knight/目录结构如下examples/sticker-knight/ ├── README.md # 示例说明本文解读对象 ├── preview.png # 示例预览图 ├── sprites.png # 素材总览图 ├── sticker-knight.world # 世界文件串联三个地图 ├── map/ # 游戏关卡 │ ├── objs.tsx # 核心图像集合瓦片集62 个瓦片每个对应一张独立 PNG │ ├── sandbox.tmx # 主关卡地图 │ ├── sandbox2.tmx # 第二张关卡地图 │ └── templates/ # 对象模板 │ ├── block.tx # 可推动方块模板 │ ├── diamond.tx # 金币模板 │ └── hero.tx # 主角模板 └── ui/ # 游戏标题界面 ├── title.png # 标题界面背景 ├── title.json # 以 JSON 格式存储的 UI 地图 └── backgroundSet.png # UI 背景素材README 中明确点出这个示例的核心价值Its a great example of using the flexible image collection tilesets with tiles on object layers, for both the map and the UI.这是使用灵活的图像集合瓦片集、把瓦片放在对象图层上同时应用于地图与 UI 的优秀示例。这意味着整个示例可以用来演示两个关键特性图像集合瓦片集每个瓦片引用自己独立的图片文件允许瓦片尺寸各不相同非常适合角色、道具、建筑等不规整素材瓦片对象对象图层中的对象直接引用瓦片集的某个瓦片通过gid从而在不需要传统瓦片图层的情况下摆放素材还能叠加自定义属性、旋转、透明度等对象能力。图像集合瓦片集核心概念与创建方式两种瓦片集类型在 Tiled 中新建瓦片集时可以选择两种类型详见 docs/manual/editing-tilesets.rst基于瓦片集图片Based on Tileset Image所有瓦片大小固定从一张大图中按网格裁剪支持 margin边距与 spacing间距设置适合规整的地形瓦片图像集合Collection of Images每个瓦片引用自己的图片文件瓦片尺寸可以各不相同。官方文档明确说明它适用于瓦片大小不一致或纹理打包留到后续处理的场景。Sticker Knight 示例选择的正是第二种map/objs.tsx中 62 个瓦片分别引用了map/目录下的独立 PNG 文件尺寸从 32×32 的小地砖如grey.png、blue.png到 384×128 的云朵cloud.png、192×192 的火光flare.png不一而足充分体现了灵活二字的含义。图像集合瓦片集的 TMX 结构打开 examples/sticker-knight/map/objs.tsx 可以看到其典型结构?xml version1.0 encodingUTF-8? tileset version1.4 tiledversion1.4.1 nameobjs tilewidth384 tileheight332 tilecount62 columns0 tile id0 image width160 height192 sourcealter.png/ /tile tile id1 image width96 height64 sourceblobBlue.png/ /tile tile id2 image width96 height64 sourceblobGreen.png/ /tile !-- ... 其余 59 个 tile 依此类推 ... -- /tileset关键点解读tileset根元素上的tilewidth/tileheight在图像集合类型中没有实际意义这里写 384×332 只是编辑器显示所需真正决定瓦片大小的是每个tile内image元素的width/heightcolumns0表示该瓦片集不是从单张图片切割而来TMX 文档格式中columns属性对图像集合瓦片集是可编辑的仅用于控制瓦片集在编辑器中的显示列数见 docs/reference/tmx-map-format.rst 与 tmx-changelog 中 Addedcolumnsattribute to thetilesetelement 条目每个瓦片通过source引用相对于该瓦片集文件所在目录的图片路径。在本示例中objs.tsx与所有 PNG 同处map/目录所以直接用文件名即可若图片在子目录中则需写相对路径从 Tiled 1.0 起官方推荐将瓦片集保存为独立文件如这里的.tsx这样所有引用该瓦片集的地图都能共享瓦片元信息如自定义属性、碰撞形状避免重复维护值得注意示例中瓦片 ID 从 0 到 62 并非完全连续跳过了 47这正是 TMX 变更日志中提到的行为——图像集合瓦片集删除瓦片后不会改变其他瓦片的 ID因此 ID 可以不连续。在编辑器中针对图像集合瓦片集的瓦片其Image属性会显示该瓦片的图片文件并允许修改见 docs/manual/editing-tilesets.rst这是图像集合瓦片集独有的编辑能力。瓦片对象把瓦片摆放到对象图层瓦片对象与gid机制传统做法是把瓦片放进瓦片图层Tile Layer但 Sticker Knight 示例反其道而行所有内容都以对象的形式放在对象图层Object Group中。对象图层中的每个object通过gidGlobal Tile ID全局瓦片 ID引用瓦片集中的某个瓦片这类对象即瓦片对象Tile Object。gid的计算规则是gid firstgid 瓦片在瓦片集中的 ID。在地图文件里引用外部瓦片集时通过firstgid建立映射例如sandbox.tmx第 3 行tileset firstgid1 sourceobjs.tsx/这意味着objs.tsx中 ID 为 0 的瓦片alter.png在该地图中的gid为 1ID 为 1 的blobBlue.png的gid为 2依此类推。验证一下sandbox.tmx中gid16的对象对应瓦片 ID 15flare.png192×192而该对象声明width192 height192完全吻合。gid的高位比特还被用于编码翻转Flip状态。以 examples/sticker-knight/map/sandbox.tmx 中的视差云层对象为例objectgroup id10 nameparallax clouds parallaxx0.5 parallaxy0.5 object id95 gid7 x-16.2424 y452.394 width384 height128/ object id91 gid2147483655 x373.939 y627.121 width384 height128/ ... /objectgroup2147483655减去 2³¹2147483648等于 7说明该对象使用的是与 ID 95 相同的云朵瓦片gid 7 → 瓦片 ID 6即cloud.png但带上了水平翻转标志。同理sandbox.tmx城堡层中的2147483681表示 gid 33 的瓦片平台方块做了水平翻转。这正是 TMX 规范中GID 高位比特表示翻转机制的实际应用详见 docs/reference/tmx-map-format.rst 与 docs/reference/global-tile-ids.rst。瓦片对象的属性叠加能力瓦片对象的优势在于它既拥有瓦片本身的图片外观又是一个完整的对象可以附加自定义属性、旋转、透明度等。看sandbox.tmx的ground对象图层第 30-44 行objectgroup id3 nameground object id2 gid31 x0 y1087 width256 height96 properties property namebodyType valuestatic/ property namefriction typefloat value1/ /properties /object object id4 gid30 x1216 y895 width256 height96 properties property namebodyType valuestatic/ property namefloating typebool valuetrue/ property namefriction typefloat value1/ /properties /object ... /objectgroup每个地面瓦片对象都带有bodyTypestatic、friction1等物理属性悬空平台还额外标记floatingtrue——这些属性在 Tiled 中只是普通自定义属性但会被游戏引擎读取并解析为物理实体参数。这正是编辑器摆画面引擎读属性的典型协作模式。再比如castledeco层中的出口对象第 187-191 行object id57 typeexit gid13 x2016 y991 width160 height192 properties property namemap valuescene/game/map/sandbox2.json/ /properties /objecttypeexit声明了对象类型map属性指定了切换到sandbox2.json的关卡路径游戏逻辑据此实现关卡切换。另外shading层第 193-211 行使用了opacity0.36的对象图层并复用同一张阴影贴图瓦片来营造整体光影氛围展示了对象图层级透明度控制的威力。对象模板复用带属性的预制件对象模板Object Template允许把瓦片 默认属性打包成可复用的预制件避免在多个对象上重复输入相同属性。Sticker Knight 在map/templates/下提供了三个模板。hero.tx主角出生点examples/sticker-knight/map/templates/hero.tx?xml version1.0 encodingUTF-8? template tileset firstgid1 source../objs.tsx/ object namehero typehero gid22 width128 height160/ /template引用模板时需要给出相对于模板文件自身位置的瓦片集路径../objs.tsx。gid 22 对应瓦片 ID 21即hero.png128×160与模板中声明的宽高一致。diamond.tx金币examples/sticker-knight/map/templates/diamond.tx?xml version1.0 encodingUTF-8? template tileset firstgid1 source../objs.tsx/ object typecoin gid17 width64 height64/ /template模板声明了typecoingid 17 对应瓦片 ID 16gemBlueStroked.png64×64。block.tx可推动方块examples/sticker-knight/map/templates/block.tx 展示了模板最实用的场景——携带物理参数?xml version1.0 encodingUTF-8? template tileset firstgid1 source../objs.tsx/ object nameblock gid44 width96 height96 properties property namebodyType valuedynamic/ property namedensity typefloat value2/ property namefriction typefloat value0.45/ /properties /object /template它引用的是瓦片 ID 43pushBlock3.png96×96并预设了bodyTypedynamic动态刚体、density2、friction0.45等物理属性。在关卡中实例化模板game对象图层sandbox.tmx 第 212-222 行通过template属性实例化这些预制件摆放时只需给出坐标objectgroup id7 namegame object id58 templatetemplates/hero.tx x45 y979.5/ object id111 templatetemplates/block.tx x594 y571/ object id190 templatetemplates/diamond.tx x238 y947.5/ ... /objectgroup模板引用路径同样相对于地图文件所在目录templates/hero.tx相对于map/。使用模板后关卡文件极为精简一行坐标即一个游戏实体若要统一调整金币的物理参数只需修改diamond.tx一处。这正是对象模板在大型关卡工程中的价值——详见 docs/manual/using-templates.rst。视差滚动对象图层级的 Parallax 配置sandbox.tmx通过多个对象图层实现了层次丰富的视差背景每层有独立的parallaxx/parallaxy图层parallaxx / parallaxy内容static0 / 0固定装饰不随相机移动parallax clouds0.5 / 0.5远景云层半速滚动parallax background0.8 / 0.8远景山脉、塔楼八折速度background1 / 1常规背景满速ground / castle 等1 / 1游戏主体对应代码sandbox.tmx 第 4-22 行objectgroup id11 namestatic parallaxx0 parallaxy0 object id90 gid16 x146.97 y693.727 width192 height192/ /objectgroup objectgroup id10 nameparallax clouds parallaxx0.5 parallaxy0.5 ... /objectgroup objectgroup id1 nameparallax background parallaxx0.8 parallaxy0.8 ... /objectgroupparallaxx0的图层完全不随相机移动常驻画面的静态层0.5表示相机移动 1 像素、该层只移动 0.5 像素数值越小滚动越慢、感觉越远。地图根元素上的parallaxoriginx/parallaxoriginy示例中为 1264、720即画布中心定义了视差的原点。这种图层级视差Layer Parallax Factor是 Tiled 1.4 引入的能力详见 docs/manual/layers.rst。关卡串联World 文件.worldexamples/sticker-knight/sticker-knight.world 把三张地图组织进同一个世界方便在编辑器中整体预览与跳转{ maps: [ { fileName: map/sandbox2.tmx, height: 992, width: 2560, x: 1824, y: 0 }, { fileName: map/sandbox.tmx, height: 1440, width: 2528, x: 0, y: -1792 }, { fileName: ui/title.json, height: 832, width: 1216, x: -1760, y: -1408 } ], onlyShowAdjacentMaps: false, type: world }要点每张地图通过x/y在世界坐标系中定位width/height声明其占据的像素范围onlyShowAdjacentMaps: false表示同时显示所有地图默认只渲染相邻地图以提升性能有趣的是ui/title.json也被当作一张地图挂入世界——用 JSON 格式存储的 UI 布局与游戏关卡在同一个世界文件中协同预览世界文件支持相对路径其路径基准是.world文件所在目录这里三张地图都在sticker-knight/之下。UI 的 JSON 实现同一种技巧的另一种载体ui/title.json是 TiledJSON 地图格式见 docs/reference/json-map-format.rst的实例整个标题界面同样是图像集合瓦片集 对象图层只是换用了 JSON 语法。前 80 行已可窥其全貌{ backgroundcolor:#3b97d3, compressionlevel:-1, height:26, infinite:false, layers:[ { draworder:topdown, id:1, name:background-near, objects:[ { gid:7, height:262.666666666667, id:11, name:ground, rotation:0, type:, visible:true, width:1736, x:-256, y:920.666666666667 }, ... ], opacity:1, type:objectgroup, visible:true, x:0, y:0 }, { id:6, name:background-far, objects:[ ... ], opacity:0.57, parallaxx:0.7, parallaxy:0.7, type:objectgroup, ... } ] }与 TMX 语法对照type: objectgroup对应 TMX 的objectgroupobjects数组对应其中的object列表每个对象同样用gid引用瓦片用x/y/width/height定义位置与显示尺寸rotation、visible、name一应俱全parallaxx/parallaxy如background-far层的 0.7同样支持视差opacity0.57实现图层半透明compressionlevel: -1表示压缩级别由 Tiled 默认决定-1 为无压缩的默认层级详见 JSON 格式文档中的compressionlevel说明。可见同一套图像集合瓦片集 瓦片对象工作流可以无缝跨越 TMX 与 JSON 两种格式UI 与游戏场景共享同样的数据模型。对象图层替代瓦片图层的取舍分析从源码结构看sandbox.tmx的 12 个对象图层中没有一个layer瓦片图层本示例把对象图层用到了极致。这种做法的取舍如下优势尺寸自由每个瓦片对象独立指定宽高同一张图片可以按需拉伸如把 96×64 的平台连接件拉成任意长度属性丰富对象天然支持自定义属性、旋转、透明度、类型名可直接承载游戏逻辑物理参数、关卡跳转、出生点标记模板复用配合模板可批量维护预制件参数图层级控制视差、透明度均可在对象图层层面整体调节。代价对象图层不适合逐格绘制的密集地形数千个对象会让文件臃肿且难以手绘编辑栅格对齐、自动图块AutoMapping等瓦片图层专用能力无法直接应用Tiled 的自动映射是针对瓦片图层的见 docs/manual/automapping.md。因此更典型的工程实践是瓦片图层画地形 对象图层放实体的混合方案Sticker Knight 之所以全用对象图层正是为了把瓦片对象 属性 模板这一套能力完整演示出来。动手实践建议用 Tiled 打开 examples/sticker-knight/sticker-knight.world从世界视图进入map/sandbox.tmx打开Tilesets面板观察objs瓦片集——注意每个瓦片的尺寸各不相同新建一张地图用Add External Tileset引入map/objs.tsx选择任意瓦片后使用插入瓦片工具Insert Tile在对象图层上点击即可复现示例中的瓦片对象摆放流程对图像集合瓦片集Object Alignment 属性见 docs/manual/editing-tilesets.rst会影响瓦片对象相对其原点的对齐方式尝试在Templates视图中拖拽block.tx到场景观察它自动携带的bodyType/density/friction属性修改objs.tsx的Columns属性仅图像集合瓦片集可编辑体会它如何改变瓦片集在面板中的显示排布将sandbox.tmx另存为 JSON 格式File Save As对比title.json的数据结构理解两种格式的对应关系。本示例全部素材由 ponywolf 制作并已释放至公有领域可在遵循其来源声明的前提下自由用于游戏项目——这正是它在 Tiled 官方仓库中长期作为图像集合瓦片集 瓦片对象教学范本的原因。【免费下载链接】tiledFlexible level editor项目地址: https://gitcode.com/gh_mirrors/ti/tiled创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考