在平常拼UI的时候,我们经常会想获取一个Node所在的位置,但是写起来有时候会很繁琐。比如我们先创建了一个精灵,如下:
local sp = cc.Sprite:create("XXX.png") sp:setAnchorPoint(0,0.5) sp:setPosition(100,100) layer:addChild(sp)
好,我们现在有了一个精灵,现在我要在他的右边再创建一个贴合他的精灵:
local rightSp = cc.Sprite:create("XXX.png") rightSp:setAnchorPoint(0,0.5) rightSp:setPosition(sp:getPositionX()+sp:getBoundingBox().width,100) layer:addChild(rightSp)
可以看到其中的『sp:getPositionX()+sp:getBoundingBox().width』 写的其实是非常繁琐的。而且如果我们要获得很多Node的位置才能确定这个Node的位置,表达式有时候要写的很长。
那么问题来了,如何在这里提高写代码的效率和正确率?
我们不妨在CCNode里加几个函数。
把以下代码拷贝到CCNode.h中:
virtual const Vec2 getPositionatanc(const Vec2& point) const; virtual const Vec2 getPositionatanc(float x,float y) const; virtual float getPositionXatanc(float x) const; virtual float getPositionYatanc(float y) const;
再把以下代码拷贝到CCNode.cpp中:
const Vec2 Node::getPositionatanc(const Vec2& point) const { Vec2 targetPos; targetPos.x = _position.x - (_anchorPoint.x - point.x) * getBoundingBox().size.width; targetPos.y = _position.y - (_anchorPoint.y - point.y) * getBoundingBox().size.height; return targetPos; } const Vec2 Node::getPositionatanc(float x,float y) const { Vec2 targetPos; targetPos.x = _position.x - (_anchorPoint.x - x) * getBoundingBox().size.width; targetPos.y = _position.y - (_anchorPoint.y - y) * getBoundingBox().size.height; return targetPos; } float Node::getPositionXatanc(float x) const { return _position.x - (_anchorPoint.x - x) * getBoundingBox().size.width; } float Node::getPositionYatanc(float y) const { return _position.y - (_anchorPoint.y - y) * getBoundingBox().size.height; }
好了。现在我们可以使用getPositionatanc这个方法,通过往里传入你想获得坐标的锚点来获得坐标了。
为方便在Lua中的使用,我们再将其ToLua一下。
在lua_cocos2dx_auto.cpp中,找到那一堆tolua_function(XXXX) 在其中加入这三行:
tolua_function(tolua_S,"getPositionatanc",lua_cocos2dx_Node_getPositionatanc); tolua_function(tolua_S,"getPositionXatanc",lua_cocos2dx_Node_getPositionXatanc); tolua_function(tolua_S,"getPositionYatanc",lua_cocos2dx_Node_getPositionYatanc);
int lua_cocos2dx_Node_getPositionatanc(lua_State* tolua_S) { int argc = 0; cocos2d::Node* cobj = nullptr; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; #endif #if COCOS2D_DEBUG >= 1 if (!tolua_isusertype(tolua_S,1,"cc.Node",&tolua_err)) goto tolua_lerror; #endif cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,0); #if COCOS2D_DEBUG >= 1 if (!cobj) { tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionatanc'",nullptr); return 0; } #endif argc = lua_gettop(tolua_S)-1; do{ if (argc == 2) { double arg0; ok &= luaval_to_number(tolua_S,2,&arg0,"cc.Node:getPositionatanc"); if (!ok) { break; } double arg1; ok &= luaval_to_number(tolua_S,3,&arg1,"cc.Node:getPositionatanc"); if (!ok) { break; } const cocos2d::Vec2& ret = cobj->getPositionatanc(arg0,arg1); vec2_to_luaval(tolua_S,ret); return 1; } }while(0); ok = true; do{ if (argc == 1) { cocos2d::Vec2 arg0; ok &= luaval_to_vec2(tolua_S,"cc.Node:getPositionatanc"); if(!ok) { tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_getPositionatanc'",nullptr); return 0; } const cocos2d::Vec2& ret = cobj->getPositionatanc(arg0); vec2_to_luaval(tolua_S,ret); return 1; } }while(0); luaL_error(tolua_S,"%s has wrong number of arguments: %d,was expecting %d \n","cc.Node:getPositionatanc",argc,1); return 0; #if COCOS2D_DEBUG >= 1 tolua_lerror: tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Node_getPositionatanc'.",&tolua_err); #endif return 0; } int lua_cocos2dx_Node_getPositionXatanc(lua_State* tolua_S) { int argc = 0; cocos2d::Node* cobj = nullptr; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; #endif #if COCOS2D_DEBUG >= 1 if (!tolua_isusertype(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionXatanc'",nullptr); return 0; } #endif argc = lua_gettop(tolua_S)-1; if (argc == 1) { double arg0; ok &= luaval_to_number(tolua_S,"cc.Node:getPositionXatanc"); if(!ok) { tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_getPositionXatanc'",nullptr); return 0; } double ret = cobj->getPositionXatanc(arg0); tolua_pushnumber(tolua_S,(lua_Number)ret); return 1; } luaL_error(tolua_S,"cc.Node:getPositionXatanc","#ferror in function 'lua_cocos2dx_Node_getPositionXatanc'.",&tolua_err); #endif return 0; } int lua_cocos2dx_Node_getPositionYatanc(lua_State* tolua_S) { int argc = 0; cocos2d::Node* cobj = nullptr; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; #endif #if COCOS2D_DEBUG >= 1 if (!tolua_isusertype(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionYatanc'","cc.Node:getPositionYatanc"); if(!ok) { tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_getPositionYatanc'",nullptr); return 0; } double ret = cobj->getPositionYatanc(arg0); tolua_pushnumber(tolua_S,"cc.Node:getPositionYatanc","#ferror in function 'lua_cocos2dx_Node_getPositionYatanc'.",&tolua_err); #endif return 0; }
大功告成。现在你可以在Lua中使用这些方法了。
注:getPositionatanc这个方法,你可以传入一个Vec2,也就是Lua中的cc.p,也可以直接传入两个锚点 如(0.5,1)。