zoukankan      html  css  js  c++  java
  • cocos2d-x 不规则触摸解决方案

    .h

    #ifndef __UI_BUTTON_PIXEL_H__
    #define __UI_BUTTON_PIXEL_H__ 1
    #include <iostream>
    #include <string>
    #include <string.h>
    using namespace std;
    #include <cocos2d.h>
    #include <ui/CocosGUI.h>
    
    
    class CC_GUI_DLL UIButton_pixel : public cocos2d::ui::Button
    {
    
        bool isPixelTouch;
    
        ccWidgetTouchCallback m_ccWidgetTouchCallback;
    
        cocos2d::Image *m_Image;
    public:
    
        UIButton_pixel();
    
        ~UIButton_pixel();
    
        static UIButton_pixel* create(const std::string& normalImage,
            const std::string& selectedImage = "",
            const std::string& disableImage = "",
            TextureResType texType = TextureResType::LOCAL);
    
    
        void setPixelTouch(bool is);
    
        void addPixelTouchEventListener_s(const ccWidgetTouchCallback& callback);
    
    private:
    
        //获取图片内的左边
        cocos2d::Vec2 getTouchImagePosition(cocos2d::Vec2 &TouchEndPos);
    
        //
        bool indexPixelLogic(cocos2d::Vec2 &pos);
    };
    #endif // !__UI_BUTTON_PIXEL_H__

    .cpp

    #include "UIButton_pixel.h"
    
    UIButton_pixel::UIButton_pixel() :isPixelTouch(false), m_Image(nullptr)
    {
    
    }
    
    UIButton_pixel::~UIButton_pixel()
    {
        if (m_Image)
        {
            delete m_Image;
            m_Image = nullptr;
        }
    }
    
    UIButton_pixel* UIButton_pixel::create(const std::string& normalImage, const std::string& selectedImage, const std::string& disableImage, TextureResType texType)
    {
        UIButton_pixel *btn = new (std::nothrow) UIButton_pixel;
        if (btn && btn->init(normalImage, selectedImage, disableImage, texType))
        {
            btn->autorelease();
            return btn;
        }
        CC_SAFE_DELETE(btn);
        return btn;
    }
    
    void UIButton_pixel::setPixelTouch(bool is)
    {
        isPixelTouch = is;
    }
    
    void UIButton_pixel::addPixelTouchEventListener_s(const ccWidgetTouchCallback& callback)
    {
        if (m_ccWidgetTouchCallback)
        {
            return;
        }
        m_ccWidgetTouchCallback = callback;
    
        static ccWidgetTouchCallback tmp = [&](Ref *ref, cocos2d::ui::Widget::TouchEventType e)
        {
            if (isPixelTouch && m_ccWidgetTouchCallback 
                && e == cocos2d::ui::Widget::TouchEventType::ENDED)
            {
                auto b_pos = this->getTouchBeganPosition();
    
                auto e_pos = this->getTouchEndPosition();
    
                auto pos = this->getWorldPosition();
    
    
                cocos2d::log("=============
    
    pos(%f,%f) 
    b_pos(%f,%f) 
    e_pos(%f,%f)
    
    ============ = 
    ", pos.x, pos.y, b_pos.x, b_pos.y, e_pos.x, e_pos.y);
    
    
                auto imagePos = this->getTouchImagePosition(e_pos);
    
                if (this->indexPixelLogic(imagePos))
                {
                    m_ccWidgetTouchCallback(ref, e);
                }
            }
    
        };
    
        this->addTouchEventListener(tmp);
    }
    
    cocos2d::Vec2 UIButton_pixel::getTouchImagePosition(cocos2d::Vec2 &TouchEndPos)
    {
    
        auto size = this->getContentSize();
        auto ret = cocos2d::Vec2::ZERO;
        auto worldPosition = this->getWorldPosition();
        auto anchorPoint = this->getAnchorPoint();
    
    
        auto offset = worldPosition - TouchEndPos;
    
        /** equals to Vec2(0.5, 0.5) */
        if (anchorPoint == cocos2d::Vec2::ANCHOR_MIDDLE)
        {
            ret = cocos2d::Vec2(size.width * 0.5f - offset.x, size.height * 0.5f + offset.y);
        }
        /** equals to Vec2(0, 0) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_BOTTOM_LEFT)
        {
            ret = cocos2d::Vec2(-(offset.x), size.height + offset.y);
        }
        /** equals to Vec2(0, 1) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_TOP_LEFT)
        {
            ret = cocos2d::Vec2(-(offset.x), +offset.y);
        }
        /** equals to Vec2(1, 0) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_BOTTOM_RIGHT)
        {
            ret = cocos2d::Vec2(size.width - offset.x, size.height + offset.y);
        }
        /** equals to Vec2(1, 1) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_TOP_RIGHT)
        {
            ret = cocos2d::Vec2(size.width - offset.x, +offset.y);
        }
        /** equals to Vec2(1, 0.5) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_MIDDLE_RIGHT)
        {
            ret = cocos2d::Vec2(size.width - offset.x, size.height * 0.5f + offset.y);
        }
        /** equals to Vec2(0, 0.5) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_MIDDLE_LEFT)
        {
            ret = cocos2d::Vec2(-(offset.x), size.height * 0.5f + offset.y);
        }
        /** equals to Vec2(0.5, 1) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_MIDDLE_TOP)
        {
            ret = cocos2d::Vec2(size.width * 0.5f - offset.x, offset.y);
        }
        /** equals to Vec2(0.5, 0) */
        else if (anchorPoint == cocos2d::Vec2::ANCHOR_MIDDLE_BOTTOM)
        {
            ret = cocos2d::Vec2(size.width * 0.5f - offset.x, size.height + offset.y);
        }
        else
        {
            cocos2d::log("anchorPoint error 
    ");
            return ret = cocos2d::Vec2(-1, -1);
        }
    
        return ret;
    }
    
    bool UIButton_pixel::indexPixelLogic(cocos2d::Vec2 &pos)
    {
    
        
        auto texture = this->getRendererNormal()->getTexture();
        auto size = cocos2d::Size(texture->getPixelsWide(), texture->getPixelsHigh());
    
        if (pos != cocos2d::Vec2(-1, -1)
            && pos.x <= size.width
            &&pos.y <= size.height)
        {
    
            std::cout << " pixel pos : " << pos.x << " " << pos.y << std::endl;
    
            auto path = texture->getPath();
    
            if (!m_Image)
            {
                m_Image = new (std::nothrow) cocos2d::Image();
            }
    
            if (m_Image)
            {
                auto b = m_Image->initWithImageFile(path);
                if (b
                    &&
                    m_Image->getRenderFormat() == cocos2d::Texture2D::PixelFormat::RGBA8888)
                {
                    auto data = m_Image->getData();
                    auto dataLen = m_Image->getDataLen();
                    
                    if ((int)(size.width * size.height * 4) == dataLen)
                    {
                        auto offsetPixel = (int)(((int)(pos.y) * size.width + (int)(pos.x)));
                        
                        auto rgba = data + offsetPixel * 4;
                        int r = (unsigned char)rgba[0];
                        int g = (unsigned char)rgba[1];
                        int b = (unsigned char)rgba[2];
                        int a = (unsigned char)rgba[3];
    
                        printf("R: %d G: %d B: %d A: %d
    ",
                            r,
                            g,
                            b, 
                            a);
    
                        if (a == 255)
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    tolua.cpp

    #include "lua_cocos2d_Ex.h"
    #include <iostream>
    #include "cocos2d.h"
    using namespace cocos2d;
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
    #include "scripting/lua-bindings/auto/lua_cocos2dx_experimental_video_auto.hpp"
    #include "scripting/lua-bindings/manual/ui/lua_cocos2dx_experimental_video_manual.hpp"
    #include "scripting/lua-bindings/auto/lua_cocos2dx_experimental_webview_auto.hpp"
    #include "scripting/lua-bindings/manual/ui/lua_cocos2dx_experimental_webview_manual.hpp"
    #endif
    
    #include "scripting/lua-bindings/manual/tolua_fix.h"
    #include "scripting/lua-bindings/manual/LuaBasicConversions.h"
    #include "scripting/lua-bindings/manual/cocos2d/LuaScriptHandlerMgr.h"
    #include "scripting/lua-bindings/manual/CCLuaValue.h"
    #include "ui/CocosGUI.h"
    #include "scripting/lua-bindings/manual/CCLuaEngine.h"
    #include "base/CCEventListenerFocus.h"
    #include "UIButton_pixel.h"
    
    
    static int handleUIEvent(int handler, cocos2d::Ref* sender, int eventType)
    {
        LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
    
        stack->pushObject(sender, "cc.Ref");
        stack->pushInt(eventType);
    
        stack->executeFunctionByHandler(handler, 2);
        stack->clean();
    
        return 0;
    }
    
    int lua_cocos2d_Ex_create(lua_State *tolua_S)
    {
        int argc = 0;
        //UIButton_pixel* cobj = nullptr;
        bool ok = true;
    
    #if COCOS2D_DEBUG >= 1
        tolua_Error tolua_err;
    #endif
    
        //cobj = (UIButton_pixel*)tolua_tousertype(tolua_S, 1, 0);
    
    #if COCOS2D_DEBUG >= 1
        if (!tolua_isusertable(tolua_S, 1, "ccui.UIButton_pixel", 0, &tolua_err)) goto tolua_lerror;
    #endif
    
        argc = lua_gettop(tolua_S) - 1;
    
        if (argc == 4)
        {
            std::string arg0, arg1, arg2;
            int arg3;
    
            ok &= luaval_to_std_string(tolua_S, 2, &arg0, "ccui.UIButton_pixel:create");
            if (!ok)
            {
                tolua_error(tolua_S, "invalid arguments in function 'lua_cocos2d_Ex_create'", nullptr);
                return 0;
            }
            ok &= luaval_to_std_string(tolua_S, 3, &arg1, "ccui.UIButton_pixel:create");
            if (!ok)
            {
                tolua_error(tolua_S, "invalid arguments in function 'lua_cocos2d_Ex_create'", nullptr);
                return 0;
            }
            ok &= luaval_to_std_string(tolua_S, 4, &arg2, "ccui.UIButton_pixel:create");
            if (!ok)
            {
                tolua_error(tolua_S, "invalid arguments in function 'lua_cocos2d_Ex_create'", nullptr);
                return 0;
        }
            ok &= luaval_to_int32(tolua_S, 5, &arg3, "ccui.UIButton_pixel:create");
            if (!ok)
            {
                tolua_error(tolua_S, "invalid arguments in function 'lua_cocos2d_Ex_create'", nullptr);
                return 0;
            }
    
            UIButton_pixel *ret = UIButton_pixel::create(arg0, arg1, arg2, (cocos2d::ui::TextureResType)arg3);
            object_to_luaval<UIButton_pixel>(tolua_S, "ccui.UIButton_pixel", (UIButton_pixel*)ret);
            return 1;
    }
        luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d
     ", "ccui.UIButton_pixel:create", argc, 0);
        return 0;
    #if COCOS2D_DEBUG >= 1
        tolua_lerror:
                    tolua_error(tolua_S, "#ferror in function 'lua_cocos2d_Ex_create'.", &tolua_err);
    #endif
                    return 0;
        }
    int lua_cocos2d_Ex_setPixelTouch(lua_State *tolua_S)
    {
        int argc = 0;
        UIButton_pixel* cobj = nullptr;
        bool ok = true;
    
    #if COCOS2D_DEBUG >= 1
        tolua_Error tolua_err;
    #endif
    
        cobj = (UIButton_pixel*)tolua_tousertype(tolua_S, 1, 0);
    
    #if COCOS2D_DEBUG >= 1
        if (!tolua_isusertable(tolua_S, 1, "ccui.UIButton_pixel", 0, &tolua_err)) goto tolua_lerror;
    #endif
    
    #if COCOS2D_DEBUG >= 1
        if (nullptr == self) {
            tolua_error(L, "invalid 'self' in function 'lua_cocos2d_Ex_setPixelTouch'
    ", NULL);
            return 0;
        }
    #endif
    
        argc = lua_gettop(tolua_S) - 1;
    
        if (argc == 1)
        {
            bool arg0;
            ok &= luaval_to_boolean(tolua_S, 2, &arg0, "ccui.UIButton_pixel:setPixelTouch");
            if (!ok)
            {
                tolua_error(tolua_S, "invalid arguments in function 'lua_cocos2d_Ex_setPixelTouch'", nullptr);
                return 0;
            }
            cobj->setPixelTouch(arg0);
            return 0;
        }
        luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d
     ", "ccui.UIButton_pixel:setPixelTouch", argc, 0);
        return 0;
    #if COCOS2D_DEBUG >= 1
        tolua_lerror:
                    tolua_error(tolua_S, "#ferror in function 'lua_cocos2d_Ex_setPixelTouch'.", &tolua_err);
    #endif
                    return 0;
    }
    int lua_cocos2d_Ex_addPixelTouchEventListener_s(lua_State *tolua_S)
    {
        int argc = 0;
        UIButton_pixel* cobj = nullptr;
        bool ok = true;
    
    #if COCOS2D_DEBUG >= 1
        tolua_Error tolua_err;
    #endif
    
        cobj = (UIButton_pixel*)tolua_tousertype(tolua_S, 1, 0);
    
    #if COCOS2D_DEBUG >= 1
        if (!tolua_isusertable(tolua_S, 1, "ccui.UIButton_pixel", 0, &tolua_err)) goto tolua_lerror;
    #endif
    
    #if COCOS2D_DEBUG >= 1
        if (nullptr == self) {
            tolua_error(L, "invalid 'self' in function 'lua_cocos2d_Ex_addPixelTouchEventListener_s'
    ", NULL);
            return 0;
        }
    #endif
    
        argc = lua_gettop(tolua_S) - 1;
    
        if (argc == 1)
        {
    #if COCOS2D_DEBUG >= 1
            if (!toluafix_isfunction(L, 2, "LUA_FUNCTION", 0, &tolua_err))
            {
                goto tolua_lerror;
            }
    #endif
    
            LUA_FUNCTION handler = (toluafix_ref_function(tolua_S, 2, 0));
    
            cobj->addPixelTouchEventListener_s([=](cocos2d::Ref* ref, cocos2d::ui::Widget::TouchEventType eventType) {
                handleUIEvent(handler, ref, (int)eventType);
            });
    
            ScriptHandlerMgr::getInstance()->addCustomHandler((void*)cobj, handler);
            return 0;
        }
        luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d
     ", "ccui.UIButton_pixel:addPixelTouchEventListener_s", argc, 0);
        return 0;
    #if COCOS2D_DEBUG >= 1
        tolua_lerror:
                    tolua_error(tolua_S, "#ferror in function 'lua_cocos2d_Ex_addPixelTouchEventListener_s'.", &tolua_err);
    #endif
                    return 0;
    }
    
    
    
    int lua_register_cocos2d_Ex(lua_State* tolua_S)
    {
        tolua_usertype(tolua_S, "ccui.UIButton_pixel");
        tolua_cclass(tolua_S, "UIButton_pixel", "ccui.UIButton_pixel", "ccui.Button", nullptr);
    
        tolua_beginmodule(tolua_S, "UIButton_pixel");
        if (true)
        {
    
            tolua_function(tolua_S, "create", lua_cocos2d_Ex_create);
            tolua_function(tolua_S, "setPixelTouch", lua_cocos2d_Ex_setPixelTouch);
            tolua_function(tolua_S, "addPixelTouchEventListener_s", lua_cocos2d_Ex_addPixelTouchEventListener_s);
    
    
        }
        tolua_endmodule(tolua_S);
        std::string typeName = typeid(UIButton_pixel).name();
        g_luaType[typeName] = "ccui.UIButton_pixel";
        g_typeCast["UIButton_pixel"] = "ccui.UIButton_pixel";
        return 1;
    }
    
    int register_cocos2d_Ex(lua_State* tolua_S)
    {
        tolua_open(tolua_S);
    
        tolua_module(tolua_S, "ccui", 0);
        tolua_beginmodule(tolua_S, "ccui");
    
        lua_register_cocos2d_Ex(tolua_S);
    
        tolua_endmodule(tolua_S);
        return 1;
    }
    
    int lua_cocos2d_Ex(lua_State* L)
    {
        lua_getglobal(L, "_G");
        if (lua_istable(L, -1))
        {
            register_cocos2d_Ex(L);
            if (L)
            {
                lua_pushstring(L, "ccui.UIButton_pixel");
                lua_rawget(L, LUA_REGISTRYINDEX);
                lua_pop(L, 1);
            }
        }
        lua_pop(L, 1);
        return 0;
    }

    test

        local filename = "res/GameList/GameAni/_12/skeleton.png"
        local btn = ccui.UIButton_pixel:create(filename,filename,filename,0)
        btn:setPixelTouch(true)
        btn:addPixelTouchEventListener_s(function(ref,type)
            print("UIButton_pixel touch");
        end)
        btn:setPosition(display.center)
        self:addChild(btn)
  • 相关阅读:
    Linux、CentOS系统下调整home和根分区大小
    Dell服务器Raid卡电池策略调整
    自建Saltstack的repo软件源仓库
    CentOS6.6下DRBD+HeartBeat+NFS配置
    go vendor目录
    cmd/go: unsupported GOOS/GOARCH pair linux /amd64
    linux的单用户模式
    go import导入的理解
    监控系统整合告警平台实现邮件、短信、微信、电话语音和app等多方式报警
    如何以非交互方式为psql指定密码?
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/14380180.html
Copyright © 2011-2022 走看看