cocos2dx 坐标转换相关函数应用演示

本文通过实例演示了Cocos2d-x中不同坐标系统的转换方法,并详细解释了Touch类与Node类中坐标获取及转换函数的具体含义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

坐标问题对于每一个初学者都是一个必须清晰的问题,但是一口气不能吃成胖子,面对这么函数怎么能一口气全部知道呢,毕竟初学(包括我),所以用现象说话,用实验论证,与其百度,不妨亲手一试,废话不多说上Demo,Code。

Size visableSize=Director::getInstance()->getVisibleSize();

auto block=	LayerColor::create(Color4B(255,0,0,255),200,200);
block->ignoreAnchorPointForPosition(false);
block->setPosition(visableSize.width/2,visableSize.height/2);
this->addChild(block);


auto listenerTouch=EventListenerTouchOneByOne::create();
listenerTouch->onTouchBegan=[=](Touch* t, Event* e){
	//Director::convertToUI
			

	Vec2 ViewPos= t->getLocationInView();
	Vec2 TouchPos=t->getLocation();//内部用的就是convertToGL
	Vec2 NodeSpaceToblock=block->convertToNodeSpace(TouchPos);
	Vec2 WorldSpaceToblock=block->convertToWorldSpace(TouchPos);


	std::string Info="";
	Info+=	StringUtils::format("%20s:(%.0f,%.0f)\r\n","getLocationInView",ViewPos.x,ViewPos.y);
	Info+=	StringUtils::format("%20s:(%.0f,%.0f)\r\n","getLocation",TouchPos.x,TouchPos.y);
	Info+=	StringUtils::format("%20s:(%.0f,%.0f)\r\n","convertToNodeSpace",NodeSpaceToblock.x,NodeSpaceToblock.y);
	Info+=	StringUtils::format("%20s:(%.0f,%.0f)\r\n","convertToWorldSpace",WorldSpaceToblock.x,WorldSpaceToblock.y);

	MessageBox(Info.c_str(),"test");
	return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listenerTouch,this);

随便找一个空场景的Init里面加上此段,就可以用鼠标点击来看看,各种坐标到底转化成了什么。

最后总结:


注:以下位置都是以cocos2dx标准世界坐标系左下角0,0而说的

Touch类中

getLocationInView:等效于 点击位置-右上角位置

getLocation:等效于 点击位置-左下角位置

Node类中

convertToNodeSpace:等效于 点击位置-参照物(本Node)的左下角

convertToNodeSpaceAR:等效于 点击位置-参照物(本Node)的锚点位置

convertToWorldSpace:等效于 点击位置+参照物(本Node)的左下角

convertToWorldSpaceAR:等效于 点击位置+参照物(本Node)的锚点位置

补充:一个简单获得锚点位置的方法

static Vec2 GetWorldPoint(Node* node)
{
  return node->getParent()->convertToWorldSpaceAR(node->getPosition());
}

可以发现如果锚点为(0,0)

convertToNodeSpace等效于convertToNodeSpaceAR

convertToWorldSpace等效于convertToWorldSpaceAR

Director::类静态

注:UIKIT原点左上角,OpenGL原点左下角

convertToGL:把UIKIT坐标->OpenGL坐标

convertToUI:把OpenGL坐标->UIKIT坐标

TMXTiledMap坐标转换

以下是TMX地图坐标转换函数

//pos为OpenGL世界坐标
static Vec2 ConvertToTMXMapPoint(Vec2 pos,TMXTiledMap* map)
{
	Vec2 location=map->convertToNodeSpace(pos);
	Size MapSize=map->getMapSize();
	Size TitleSize=map->getTileSize();
	return Vec2(location.x/TitleSize.width,MapSize.height-1- location.y/TitleSize.height);
}



<think>首先,用户的问题是:"我想了解如何在Cocos2D中将坐标转换为3D世界坐标,特别是使用convertToWorldSpaceAR()方法请问Cocos2DconvertToWorldSpaceAR()方法将本地坐标转换为3D世界坐标示例教程"。所以重点在Cocos2D中的convertToWorldSpaceAR()方法将2D本地坐标转换为3D世界坐标,并需要示例教程。但参考了站内引用:-引用[1]提到了convertToNodeSpaceAR,但在描述convertToWorldSpaceAR。-引用[2]清楚定义了convertToWorldSpaceAR:基于AnchorPoint把基于当前节点的本地坐标系下的坐标转换到世界坐标系中。-引用[3]展示了一个精灵创建的简单代码。-引用[4]似乎无关,是关于面试的。用户提到了"3D世界坐标",但Cocos2D本身是2D游戏引擎,引用中都是2D坐标。convertToWorldSpaceAR在引用[2]中是处理2D坐标的,方法返回Vec2(二维向量),不是3D。用户可能混淆了Cocos2D和Cocos2d-x;Cocos2d-x支持3D?Cocos2d-x确实有3D模块,但基本convertToWorldSpaceAR方法可能还是2D的。我应该基于引用回答,因为它提供了站内信息。系统级指令:-行内数学表达用$...$,独立公式用$$...$$,但这里可能不需要,因为问题不是数学相关的。-LaTeX语法正确。-使用中文回答。-生成相关问题。-引用段落末尾添加引用标识如[^1]。用户可见层指令:结构清晰,帮助用户逐步解决问题,保证真实可靠。参考用户上一次的问题:用户这次是第一次出现吗?从上下文看,这是新对话的开头,没有用户上一次的问题。指令说:"参考用户上一次的问题和你的回答",但这里没有。现在,用户的问题是针对3D世界坐标,但引用都是2D。我应该在回答中澄清这一点,或许建议用户,如果在2D上下文,方法返回2D坐标;如果涉及到3D,可能需要其他方法。keypointsfromreferences:-convertToWorldSpaceAR(constVec2&nodePoint)const:将当前节点的本地坐标系下的坐标(基于锚点)转换为世界坐标系中的坐标。返回Vec2。-示例代码在引用[3],是精灵创建,没有转换代码。-引用[1]有错误:描述了convertToNodeSpaceAR而不是convertToWorldSpaceAR。生成相关问题:指令要求在结束时生成相关问题。结构回答:1.介绍方法:解释convertToWorldSpaceAR()的作用,基于引用[2]。2.澄清3D坐标:如果Cocos2D是2D,方法返回2D;如果有3D需求,建议使用其他。3.提供示例:创建一个示例脚本,展示如何使用convertToWorldSpaceAR()。需要添加引用标识。4.生成相关问题。5.确保中文。创建示例代码:-基于引用[3],创建一个精灵,设置位置,然后使用convertToWorldSpaceAR。-例如:我有一个精灵node,在本地坐标(50,50),调用node->convertToWorldSpaceAR(Vec2(50,50))得到世界坐标。代码示例可以用类似引用[3]的格式,但使用C++orLua?引用有C++和Lua。用户提到"Cocos2D",可能指Cocos2d-x,引用[2]是Cocos2dxLua。在回答中,使用Lua代码,因为引用有。最终回答结构:-先解释convertToWorldSpaceAR方法。-然后提供示例教程代码。-结束时添加相关问题。</think> ### Cocos2D 坐标转换教程:使用 convertToWorldSpaceAR() 方法 在 Cocos2D(或 Cocos2d-x)中,`convertToWorldSpaceAR()` 是一个用于将 **本地坐标系(模型坐标)中的点转换为世界坐标系坐标** 的关键方法。基于您的需求,我将逐步解释该方法如何工作,并提供详细的示例教程。首先,需要澄清一个重要点:Cocos2D 引擎(包括 Cocos2d-x)默认主要处理 **2D 坐标**(通过 `Vec2` 类型,表示二维向量)。`convertToWorldSpaceAR()` 返回的是 **2D 世界坐标**,而不是 3D。如果您需要在 3D 场景中使用,Cocos2d-x 提供了 `Node::convertToWorldSpace()` 或 `Camera` 类的额外方法支持 3D 转换,但本文重点基于您的查询和引用内容,聚焦于 `convertToWorldSpaceAR()` 的 2D 应用。 我会参考站内引用的定义和代码片段[^1][^2][^3],确保回答真实可靠。以下是结构化教程: --- ### 1. `convertToWorldSpaceAR()` 方法介绍 - **作用**:该方法将当前节点(Node)的本地坐标系(模型坐标系)中的点,基于节点的 **锚点(Anchor Point)** 转换为世界坐标系中的坐标。锚点是节点的旋转和缩放中心,默认值为 $(0.5, 0.5)$(中心点)。 - **语法(Lua/C++)**: - Lua: `convertToWorldSpaceAR(nodePoint)` - C++: `Vec2 convertToWorldSpaceAR(const Vec2& nodePoint) const` - **返回值**:`Vec2` 类型(二维向量),表示转换后的世界坐标,单位是点(Points)。 - **关键特性**: - 输入参数 `nodePoint` 是当前节点的本地坐标。 - 该方法考虑了节点的 **位置、旋转、缩放和父节点的变换**,输出绝对的世界坐标。 - 与 `convertToWorldSpace()` 不同,`convertToWorldSpaceAR()` 基于锚点进行转换,适用于节点内部相对位置的计算[^2][^1]。 引用说明: > "基于Anchor Point把基于当前节点的本地坐标系下的坐标转换到世界坐标系中"[^2]。 > 类似地,方法确保了坐标转换的准确性,特别适用于 UI 元素或游戏对象的精确定位。 --- ### 2. 使用场景和教程:将本地坐标转换为世界坐标 在本节中,我将提供一个完整的 Lua 示例代码(基于引用[^3]的样式),展示如何在 Cocos2d-x 中使用 `convertToWorldSpaceAR()`。假设您有一个精灵(Sprite)节点,我们将其本地坐标转换为世界坐标。 #### 示例代码 ```lua -- 创建一个父节点(例如场景根节点) local sceneNode = cc.Node:create() sceneNode:setPosition(200, 200) -- 设置父节点在世界坐标系中的位置 self:addChild(sceneNode) -- 添加到场景中(this 通常是当前层) -- 创建一个子精灵(作为要转换坐标的节点) local sprite = cc.Sprite:create("example.png") sprite:setAnchorPoint(0.5, 0.5) -- 设置锚点为精灵中心(默认) sprite:setPosition(50, 50) -- 本地坐标:相对于父节点 sceneNode 的坐标 sceneNode:addChild(sprite) -- 将精灵添加为 sceneNode 的子节点 -- 使用 convertToWorldSpaceAR() 将精灵的本地坐标转换为世界坐标 -- 定义精灵内部的一个点(本地坐标) local localPoint = cc.p(30, 30) -- 在精灵坐标系中的点 local worldPoint = sprite:convertToWorldSpaceAR(localPoint) -- 打印转换结果(世界坐标) print("本地坐标: (" .. localPoint.x .. ", " .. localPoint.y .. ")") print("世界坐标: (" .. worldPoint.x .. ", " .. worldPoint.y .. ")") -- 可选:创建一个标记点可视化世界坐标 local marker = cc.Sprite:create("marker.png") marker:setPosition(worldPoint) -- 直接在场景中设置到世界坐标位置 self:addChild(marker) ``` #### 代码解释 - **创建节点层次**: - `sceneNode` 是父节点,设置在世界坐标 (200, 200) 处。 - `sprite` 是子节点,其本地坐标 (50, 50) 是相对于 `sceneNode` 的位置。如果不转换,精灵的实际世界坐标将是 $(200 + 50, 200 + 50) = (250, 250)$。 - **convertToWorldSpaceAR() 使用**: - `localPoint` 定义为精灵内部的一个点(如 (30, 30)),表示在精灵本地坐标系中的相对位置。 - 调用 `sprite:convertToWorldSpaceAR(localPoint)` 将这个本地点转换为世界坐标。由于考虑了锚点,输出值将是基于世界坐标的绝对位置。 - 例如:如果精灵设置在不同位置,转换会自动处理所有父节点的变换。 - **结果验证**: - 输出日志会显示转换后的世界坐标,您可以在场景中添加标记点可视化。 - **锚点重要性**:如果锚点设置为 $(0,0)$(左下角), `convertToWorldSpaceAR()` 会使转换结果从锚点开始计算,避免偏移错误。 引用提示: > "模型坐标转换为世界坐标"[^1]。 > 此方法在实现拖拽、碰撞检测或跨节点位置对齐时特别有用。 --- ### 3. 注意事项和常见问题 - **2D vs 3D 坐标**:`convertToWorldSpaceAR()` 返回 2D 坐标(`Vec2`)。Cocos2d-x 支持 3D 场景,但不通过此方法。对于 3D 世界坐标,建议: - 使用 `Node::convertToWorldSpace()`(返回 `Vec3`)或通过 `Camera` 转换。 - 例如:在 3D 节点上调用 `convertToWorldSpace()`,或使用 `Camera::projectGL()` 方法。 - **性能考虑**:频繁调用此方法可能影响性能,尤其是在移动设备上。优化建议:缓存坐标或只在需要时计算。 - **错误处理**:输入坐标必须是本地坐标系中的点;如果节点未添加到场景,转换可能失败。 - **兼容性**:该方法在 Cocos2d-x 4.0 及以上版本中可用,兼容 Lua 和 C++。 如果您的场景需要更多 3D 支持,请提供具体细节,我可以进一步补充代码示例。 --- ### 相关问题生成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值