Cocos Creator3.8.0 Tiled地图三合一完整脚本(加载+兼容性校验+坐标互转,一键可用,适配Tiled1.4.x)

以下是实用型代码,仅供参考。

import { _decorator, Component, Node, TiledMap, Vec2, Input, input, EventTouch, resources, error, log } from 'cc';

const { ccclass, property } = _decorator;

@ccclass('TiledMapFullTool')

export class TiledMapFullTool extends Component {

@property({tooltip: "resources下地图路径,无.tmx后缀(例:map/gameMap)"})

mapPath: string = "";

@property({tooltip: "地图节点名称"})

mapNodeName: string = "GameTiledMap";

private tiledMap: TiledMap = null; // 地图组件缓存

start() {

// 一键执行:加载→校验→绑定坐标功能

this.loadAndInitMap();

}

// 1. 地图加载核心(动态创建+挂载)

async loadAndInitMap() {

if(!this.mapPath) {error("请填写resources下地图路径!"); return;}

log("开始加载Tiled地图...");

try {

// 动态创建地图节点+组件

let mapNode = this.node.getChildByName(this.mapNodeName);

if(!mapNode) {

mapNode = new Node(this.mapNodeName);

this.node.addChild(mapNode);

}

mapNode.setAnchorPoint(0, 0); // 必设,对齐Tiled原点

this.tiledMap = mapNode.getComponent(TiledMap) || mapNode.addComponent(TiledMap);

// 加载地图资源

const tmxRes = await resources.load<TiledMap>(this.mapPath);

this.tiledMap.tmxAsset = tmxRes;

log("✅ 地图加载成功");

// 加载后自动校验+绑定坐标功能

this.checkMapCompatibility();

this.bindClickGetTile();

} catch (e) {

error(`❌ 地图加载失败:${e}`);

log("💡 排查:路径错误/资源不在resources/格式非XML");

}

}

// 2. 兼容性自动校验(4大核心项)

checkMapCompatibility() {

if(!this.tiledMap) return;

log("开始地图兼容性校验...");

// 校验1:地图格式(必须XML)

if(this.tiledMap.tmxAsset?.rawXml) log("✅ 地图格式为XML,符合要求");

else error("❌ 地图格式错误!Tiled需导出XML格式,禁用二进制/CSV");

// 校验2:图层(无中文/空格)

const invalidLayers = this.tiledMap.getLayers().filter(l => l.name.includes(" ") || /\\u4e00-\\u9fa5/.test(l.name));

invalidLayers.length > 0 ? error(`❌ 非法图层名:${invalidLayers.map(l=>l.name)}`) : log("✅ 图层校验通过");

// 校验3:瓦片集(无缺失)

this.tiledMap.getTileSets().length > 0 ? log("✅ 瓦片集加载正常") : error("❌ 瓦片集缺失!tmx/tsx/png需同目录");

// 校验4:路径(无中文)

/\\u4e00-\\u9fa5/.test(this.mapPath) ? error("❌ 地图路径含中文") : log("✅ 地图路径合法");

this.tiledMap.getLayers().length>0 ? log("🎉 所有校验通过,地图可用") : error("❌ 地图无有效图层");

}

// 3. 坐标互转核心(世界↔瓦片)

// 世界坐标转瓦片坐标

worldToTile(worldPos: Vec2): Vec2 {

if(!this.tiledMap) return Vec2.ZERO;

const tileSize = this.tiledMap.tileSize;

const mapWorldPos = this.tiledMap.node.worldPosition;

const x = Math.floor((worldPos.x - mapWorldPos.x) / tileSize.width);

const y = Math.floor((mapWorldPos.y - worldPos.y) / tileSize.height);

return new Vec2(x, y);

}

// 瓦片坐标转世界坐标(默认返回瓦片中心)

tileToWorld(tilePos: Vec2): Vec2 {

if(!this.tiledMap) return Vec2.ZERO;

const tileSize = this.tiledMap.tileSize;

const mapWorldPos = this.tiledMap.node.worldPosition;

const worldX = mapWorldPos.x + tilePos.x * tileSize.width + tileSize.width/2;

const worldY = mapWorldPos.y - tilePos.y * tileSize.height - tileSize.height/2;

return new Vec2(worldX, worldY);

}

// 实用功能:点击地图打印瓦片坐标

bindClickGetTile() {

input.on(Input.EventTouch.END, (event: EventTouch) => {

if(!this.tiledMap) return;

const worldPos = event.getUILocation();

const tilePos = this.worldToTile(worldPos);

log("当前点击瓦片坐标:X="+tilePos.x+",Y="+tilePos.y);

}, this);

}

}

✅ 3步零踩坑使用(直接上线)

  1. 脚本挂载到Canvas节点,无需额外节点

  2. 属性面板填2个参数:①mapPath(resources下地图路径,无后缀)②地图节点名(默认即可)

  3. 运行项目,自动完成加载→校验→坐标可用,控制台看结果

🚨 终极避坑(必看)

  1. 地图资源:tmx+tsx+瓦片png 必须同目录,且全放resources文件夹

  2. Tiled导出:XML格式+外部tsx+兼容1.4格式,禁用高版本特性

  3. 坐标系:地图锚点已自动适配(0,0),无需手动改

相关推荐
Rauser Mack2 天前
Vibe coding游戏实战:零代码编程五子棋小游戏
人工智能·python·游戏·html·prompt
想做后端的前端3 天前
游戏里的水面是怎么做的
游戏
leoZ2313 天前
Claude 全面解析:从基础原理到实战应用指南
人工智能·游戏
2501_943782353 天前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
星空露珠3 天前
迷你世界UGc3.0脚本Wiki[剧情动画模块管理接口 Timeline]
开发语言·数据结构·算法·游戏·lua
yangmu32033 天前
《星露谷物语》MOD配置与实战安装综合指南
游戏·游戏引擎·游戏程序
xcLeigh3 天前
Unity基础:Game视图详解——游戏预览、分辨率模拟与性能显示
游戏·unity·游戏引擎·音频·视频·game·play模式
yyuuuzz3 天前
2026独立站运营的几个技术细节问题
运维·服务器·网络·人工智能·游戏
Johnstons4 天前
游戏网络测试怎么做?从延迟到丢包,一套完整的游戏弱网测试方案
网络·游戏·php
2023自学中4 天前
imx6ull 开发板, mame 模拟器,运行游戏 测试
linux·游戏·嵌入式·开发板