1. 程式人生 > >Cocos2d中獲取錨點所在座標的方法

Cocos2d中獲取錨點所在座標的方法

在平常拼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",0,&tolua_err)) goto tolua_lerror;
#endif

    cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,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, 2,&arg0, "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,1,"cc.Node",0,&tolua_err)) goto tolua_lerror;
#endif

    cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,0);

#if COCOS2D_DEBUG >= 1
    if (!cobj) 
    {
        tolua_error(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, 2,&arg0, "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, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:getPositionXAtAnc",argc, 1);
    return 0;

#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#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,1,"cc.Node",0,&tolua_err)) goto tolua_lerror;
#endif

    cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,0);

#if COCOS2D_DEBUG >= 1
    if (!cobj) 
    {
        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_getPositionYAtAnc'", nullptr);
        return 0;
    }
#endif

    argc = lua_gettop(tolua_S)-1;
    if (argc == 1) 
    {
        double arg0;

        ok &= luaval_to_number(tolua_S, 2,&arg0, "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,(lua_Number)ret);
        return 1;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:getPositionYAtAnc",argc, 1);
    return 0;

#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Node_getPositionYAtAnc'.",&tolua_err);
#endif

    return 0;
}

大功告成。現在你可以在Lua中使用這些方法了。

注:getPositionAtAnc這個方法,你可以傳入一個Vec2,也就是Lua中的cc.p,也可以直接傳入兩個錨點 如(0.5,1)。