{"id":1103,"date":"2015-05-07T04:22:20","date_gmt":"2015-05-06T20:22:20","guid":{"rendered":"http:\/\/www.shuizilong.com\/house\/?p=1103"},"modified":"2015-05-07T04:29:43","modified_gmt":"2015-05-06T20:29:43","slug":"cocos2d-x-3-x-%e5%a4%9a%e6%8c%87%e8%a7%a6%e6%8e%a7%e5%ae%9e%e7%8e%b0%e7%a7%bb%e5%8a%a8%e3%80%81%e6%8b%89%e4%bc%b8%e3%80%81%e6%97%8b%e8%bd%ac","status":"publish","type":"post","link":"https:\/\/www.shuizilong.com\/house\/archives\/cocos2d-x-3-x-%e5%a4%9a%e6%8c%87%e8%a7%a6%e6%8e%a7%e5%ae%9e%e7%8e%b0%e7%a7%bb%e5%8a%a8%e3%80%81%e6%8b%89%e4%bc%b8%e3%80%81%e6%97%8b%e8%bd%ac\/","title":{"rendered":"Cocos2d-x 3.x \u591a\u6307\u89e6\u63a7\u5b9e\u73b0\u79fb\u52a8\u3001\u62c9\u4f38\u3001\u65cb\u8f6c"},"content":{"rendered":"<h3>\u4ecb\u7ecd\uff1a<\/h3>\n<p>\u6211\u4eec\u77e5\u9053 Mac \u4e2d\u9884\u89c8\u56fe\u7247\u7684\u65f6\u5019\u53ef\u4ee5\u4f7f\u7528\u591a\u6307\u89e6\u63a7\u5bf9\u56fe\u7247\u8fdb\u884c\u62c9\u4f38\u548c\u65cb\u8f6c\u3002<br \/>\n\u5728 iOS \u4e2d\u3001\u6211\u4eec\u53ef\u4ee5\u8ba9\u624b\u6307\u5728\u56fe\u4e2d\u7684\u76f8\u5bf9\u4f4d\u7f6e\u4fdd\u6301\u4e0d\u53d8\uff0c\u4ece\u800c\u5c06\u8fd9\u4e09\u4e2a\u64cd\u4f5c\u7edf\u4e00\u8d77\u6765\uff0c\u66f4\u65b9\u4fbf\u7684\u5b9e\u73b0\u7f16\u8f91\u529f\u80fd\u3002<\/p>\n<p>\u6f14\u793a\u5730\u5740\uff1a<a href=\"http:\/\/www.pgyer.com\/Hu8O\">http:\/\/www.pgyer.com\/Hu8O<\/a><br \/>\n\u53c2\u8003\u8d44\u6599\uff1acpp-test \u4e2d\u7684 multitouch<\/p>\n<p>To-do: \u5982\u4f55\u652f\u6301\u6cbf\u7740\u4e00\u4e2a\u65b9\u5411\u7684\u62c9\u4f38\uff08\u4e09\u6307\uff1f\uff09<\/p>\n<h3>\u4ee3\u7801\uff1a<\/h3>\n<p><!--more---><\/p>\n<p>\u9996\u5148\u5b9a\u4e49\u652f\u6301\u7f16\u8f91\u64cd\u4f5c\u7684 <code>MySprite<\/code> \u7c7b\u3002<\/p>\n<pre class=\"brush: cpp; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\nstruct MySprite : public Sprite{\r\n    \r\n    static MySprite* _target; static vector&lt;Vec2&gt; _pos; static vector&lt;Node*&gt; _pot;\r\n    static double _dist2, _atan2;\r\n    \r\n    bool isMoveable, isZoomable, isRotatable;\r\n\r\n    void onTouchesBegan(const std::vector&lt;Touch*&gt;&amp; touches, cocos2d::Event  *event);\r\n    void onTouchesMoved(const std::vector&lt;Touch*&gt;&amp; touches, cocos2d::Event  *event);\r\n    void onTouchesEnded(const std::vector&lt;Touch*&gt;&amp; touches, cocos2d::Event  *event);\r\n    void onTouchesCancelled(const std::vector&lt;Touch*&gt;&amp; touches, cocos2d::Event  *event);\r\n    \r\n    void init2(bool,bool,bool);\r\n};\r\n<\/pre>\n<p>\u6ce8\u610f\u5230\u4e0d\u540c\u4e8e\u5355\u70b9\u89e6\u63a7\u3001\u591a\u70b9\u89e6\u63a7\u7684 <code>onTouchesBegan()<\/code> \u65b9\u6cd5\u4f3c\u4e4e\u6ca1\u6709\u8fd4\u56de\u51fd\u6570\u3001\u56e0\u6b64\u6211\u4eec\u9700\u8981\u624b\u52a8\u7eaa\u5f55\u4e00\u4e0b _target\u3002<br \/>\n\u5f53\u4f5c\u7528\u5728\u591a\u4e2a\u5bf9\u8c61\u4e0a\u65f6\uff0c\u53ea\u64cd\u4f5c\u6700\u4e0a\u5c42\u7684\u3002<\/p>\n<p><code>_dist2<\/code> \u7528\u6765\u8bb0\u5f55\u4e24\u6307\u4e4b\u95f4\u7684\u8ddd\u79bb\uff0c\u7528\u6765\u5b9e\u73b0\u653e\u5927\u3002<br \/>\n<code>_atan2<\/code> \u7528\u6765\u8bb0\u5f55\u4e24\u53ea\u4e4b\u95f4\u7684\u89d2\u5ea6\uff0c\u7528\u6765\u5b9e\u73b0\u65cb\u8f6c\u3002<\/p>\n<pre class=\"brush: cpp; light: false; title: ; toolbar: true; notranslate\" title=\"\">\r\n#include &quot;HelloWorldScene.h&quot;\r\n#include &quot;cocostudio\/CocoStudio.h&quot;\r\n#include &quot;ui\/CocosGUI.h&quot;\r\n#include &quot;Audio.h&quot;\r\n\r\n#include &quot;Template.h&quot;\r\n#include &quot;Global.h&quot;\r\nUSING_NS_CC;\r\n\r\nvoid addAroundEdge(Sprite* t){\r\n    Size s = t-&gt;getContentSize();\r\n    auto e = DrawNode::create();\r\n    \r\n    auto radius = 1;\r\n    auto color = Color4F(0, 0, 0, 1.0f);\r\n    \r\n    auto lb = Vec2(0, 0), rb = Vec2(s.width, 0);\r\n    auto lt = Vec2(0, s.height), rt = Vec2(s.width, s.height);\r\n    \r\n    e-&gt;drawSegment(lb, rb, radius, color);\r\n    e-&gt;drawSegment(lb, lt, radius, color);\r\n    e-&gt;drawSegment(rb, rt, radius, color);\r\n    e-&gt;drawSegment(lt, rt, radius, color);\r\n    e-&gt;setName(&quot;edge&quot;);\r\n    t-&gt;addChild(e);\r\n}\r\n\r\n\/*\r\nvoid MySprite::init(string s){\r\n}\r\n*\/\r\n\r\nvector&lt;Vec2&gt; MySprite::_pos;\r\nvector&lt;Node*&gt; MySprite::_pot;\r\nMySprite* MySprite::_target;\r\nDB MySprite::_atan2, MySprite::_dist2;\r\n \r\nvoid MySprite::init2(bool _isMoveable = 1, bool _isZoomable = 1, bool _isRotatable = 1){\r\n    \r\n    isMoveable = _isMoveable;\r\n    isZoomable = _isZoomable;\r\n    isRotatable = _isRotatable;\r\n    \r\n    auto listener = EventListenerTouchAllAtOnce::create();\r\n    \r\n    listener-&gt;onTouchesBegan = CC_CALLBACK_2(MySprite::onTouchesBegan, this);\r\n    listener-&gt;onTouchesMoved = CC_CALLBACK_2(MySprite::onTouchesMoved, this);\r\n    listener-&gt;onTouchesEnded = CC_CALLBACK_2(MySprite::onTouchesEnded, this);\r\n    _eventDispatcher-&gt;addEventListenerWithSceneGraphPriority(listener-&gt;clone(), this);\r\n    \r\n    addAroundEdge(this);\r\n}\r\n\r\n\r\nstatic const Color3B* s_TouchColors&#x5B;5] = {\r\n    &amp;Color3B::YELLOW,\r\n    &amp;Color3B::BLUE,\r\n    &amp;Color3B::GREEN,\r\n    &amp;Color3B::RED,\r\n    &amp;Color3B::MAGENTA\r\n};\r\n\r\nstruct TouchPoint : public Node\r\n{\r\n    \r\n    \r\n    TouchPoint(const Vec2 &amp;touchPoint, const Color3B &amp;touchColor)\r\n    {\r\n        DrawNode* drawNode = DrawNode::create();\r\n        auto s = Director::getInstance()-&gt;getWinSize();\r\n        Color4F color(touchColor.r\/255.0f, touchColor.g\/255.0f, touchColor.b\/255.0f, 1.0f);\r\n        \r\n        \/*drawNode-&gt;drawLine(Vec2(-s.width, touchPoint.y), Vec2(s.width, touchPoint.y), color);\r\n        drawNode-&gt;drawLine(Vec2(touchPoint.x, -s.height), Vec2(touchPoint.x, s.height), color);\r\n        drawNode-&gt;drawDot(touchPoint, 3, color);*\/\r\n        \r\n        drawNode-&gt;drawLine(Vec2(-s.width, 0), Vec2(s.width, 0), color);\r\n        drawNode-&gt;drawLine(Vec2(0, -s.height), Vec2(0, s.height), color);\r\n        drawNode-&gt;drawDot(Vec2(0, 0), 3, color);\r\n        addChild(drawNode);\r\n    }\r\n    \r\n    static TouchPoint* touchPointWithParent(Node* pParent, const Vec2 &amp;touchPoint, const Color3B &amp;touchColor)\r\n    {\r\n        auto pRet = new (std::nothrow) TouchPoint(touchPoint, touchColor);\r\n        pRet-&gt;setContentSize(pParent-&gt;getContentSize());\r\n        pRet-&gt;setAnchorPoint(Vec2(0.0f, 0.0f));\r\n        pRet-&gt;autorelease();\r\n        return pRet;\r\n    }\r\n};\r\n\r\n\r\nvoid MySprite::onTouchesBegan(const std::vector&lt;Touch*&gt;&amp; touches, Event  *event)\r\n{\r\n    auto target = static_cast&lt;MySprite*&gt;(event-&gt;getCurrentTarget());\r\n\r\n    for (auto &amp;touch: touches)\r\n    {\r\n        auto location = touch-&gt;getLocation();\r\n        Point locationInNode = target-&gt;convertToNodeSpace(touch-&gt;getLocation());\r\n        Size s = target-&gt;getContentSize();\r\n        Rect rect = Rect(0, 0, s.width, s.height);\r\n        if (!rect.containsPoint(locationInNode)){\r\n            return;\r\n        }\r\n    }\r\n    \r\n    if (_target != nullptr &amp;&amp; _target != target) return;\r\n    \r\n    for (auto &amp;touch: touches)\r\n    {\r\n        auto location = touch-&gt;getLocation();\r\n        Point locationInNode = target-&gt;convertToNodeSpace(touch-&gt;getLocation());\r\n        \r\n        \/\/\u70b9\u51fb\u8303\u56f4\u5224\u65ad\u68c0\u6d4b\r\n        Size s = target-&gt;getContentSize();\r\n        Rect rect = Rect(0, 0, s.width, s.height);\r\n        \r\n        auto touchPoint = TouchPoint::touchPointWithParent(this, location, *s_TouchColors&#x5B;touch-&gt;getID()%5]);\r\n        touchPoint-&gt;setName(&quot;touchPoint&quot;);\r\n        Global::game-&gt;addChild(touchPoint);\r\n        touchPoint-&gt;setPosition(location);\r\n        \r\n        _pos.PB(location), _pot.PB(touchPoint);\r\n    }\r\n    \r\n    _target = target;\r\n    \r\n    if (_pos.size() == 2){\r\n        \/\/log(&quot;%.2f %.2f %.2f %.2f\\n&quot;, _pos&#x5B;0].x, _pos&#x5B;0].y, _pos&#x5B;1].x, _pos&#x5B;1].y);\r\n        _dist2 = _pos&#x5B;0].getDistance(_pos&#x5B;1]);\r\n        Vec2 d = _pos&#x5B;1] - _pos&#x5B;0];\r\n        _atan2 = atan2(d.y, d.x);\r\n    }\r\n}\r\n\r\nvoid MySprite::onTouchesMoved(const std::vector&lt;Touch*&gt;&amp; touches, Event  *event)\r\n{\r\n    \r\n    auto target = static_cast&lt;MySprite*&gt;(event-&gt;getCurrentTarget());\r\n    if (target != _target) return;\r\n    if (_pos.empty()) return;\r\n    \r\n    vector&lt;Vec2&gt; new_pos;\r\n    \r\n    for( auto &amp;item: touches)\r\n    {\r\n        \r\n        \/\/if (state&#x5B;item] == false) continue;\r\n        \r\n        auto touch = item;\r\n\r\n        auto location = touch-&gt;getLocation();\r\n        Point locationInNode = target-&gt;convertToNodeSpace(touch-&gt;getLocation());\r\n        \/\/\u70b9\u51fb\u8303\u56f4\u5224\u65ad\u68c0\u6d4b\r\n        \r\n        Size s = target-&gt;getContentSize();\r\n        Rect rect = Rect(0, 0, s.width, s.height);\r\n        \/\/if (!rect.containsPoint(locationInNode)) continue;\r\n        new_pos.PB(location);\r\n    }\r\n    \r\n    if (_pos.size() != new_pos.size()) return;\r\n    \r\n    REP(i, _pos.size()){\r\n        _pot&#x5B;i]-&gt;setPosition(new_pos&#x5B;i]);\r\n    }\r\n    \r\n    if (_pos.size() == 1){ \/\/ \u5e73\u79fb...\r\n\/\/        log(&quot;%.2f %.2f  %.2f %.2f&quot;, target-&gt;getPosition().x, target-&gt;getPosition().y, (t-&gt;getPosition() - target-&gt;_pos).x , (t-&gt;getPosition() - target-&gt;_pos).y );\r\n        target-&gt;setPosition(target-&gt;getPosition() + (new_pos&#x5B;0] - _pos&#x5B;0]));\r\n        _pos = new_pos;\r\n    }\r\n    else if (_pos.size() == 2){\r\n\r\n        auto target = static_cast&lt;Sprite*&gt;(event-&gt;getCurrentTarget());\r\n        auto new_dist2 = new_pos&#x5B;0].getDistance(new_pos&#x5B;1]);\r\n        target-&gt;setScale((DB)target-&gt;getScale()\/_dist2*new_dist2);\r\n        _dist2 = new_dist2;\r\n        \/\/log(&quot;%.2f %.2f %.2f\\n&quot;, _dist2, new_dist2, target-&gt;getScale()\/_dist2*new_dist2);\r\n\r\n        Vec2 d = new_pos&#x5B;1] - new_pos&#x5B;0];\r\n        DB new_atan2 = atan2(d.y, d.x);\r\n        target-&gt;setRotation( target-&gt;getRotation() -  (new_atan2 - _atan2) \/ PI * 180);\r\n        _atan2 = new_atan2;\r\n    }\r\n}\r\n\r\nvoid MySprite::onTouchesEnded(const std::vector&lt;Touch*&gt;&amp; touches, Event  *event)\r\n{\r\n    \r\n    auto target = static_cast&lt;MySprite*&gt;(event-&gt;getCurrentTarget());\r\n    \r\n    while (Global::game-&gt;getChildByName(&quot;touchPoint&quot;) != nullptr){\r\n        Global::game-&gt;getChildByName(&quot;touchPoint&quot;)-&gt;removeFromParent();\r\n    }\r\n    _pos.clear(); _pot.clear();\r\n    _target = nullptr;\r\n    \r\n    \r\n    \/*for ( auto &amp;item: touches )\r\n    {\r\n        \/\/if (state&#x5B;item] == false) continue;\r\n        \r\n        auto touch = item;        auto pTP = s_map.at(target);\r\n       \r\n        if (pTP == nullptr) continue;\r\n        \r\n        pTP-&gt;removeFromParent();\r\n        s_map.erase(target);\r\n    }*\/\r\n    \r\n    \r\n    \/*for ( auto &amp;item: touches ){\r\n        state.erase(item);\r\n    }*\/\r\n}\r\n\r\nvoid MySprite::onTouchesCancelled(const std::vector&lt;Touch*&gt;&amp; touches, Event  *event)\r\n{\r\n    onTouchesEnded(touches, event);\r\n}\r\n\r\n\r\n\r\n\r\nvoid LongTouch::upd(){\r\n    if (counter &gt; 0){\r\n        if (--counter == 0){\r\n            Audio::playSE(&quot;coin.mp3&quot;);\r\n        }\r\n    }\r\n}\r\n\r\nScene* HelloWorld::createScene()\r\n{\r\n    auto scene = Scene::create();\r\n    auto layer = HelloWorld::create();\r\n    scene-&gt;addChild(layer);\r\n    return scene;\r\n}\r\n\r\nvoid HelloWorld::update(float dt){\r\n    longTouch-&gt;upd();\r\n    return;\r\n}\r\n\r\n\r\nbool HelloWorld::init()\r\n{\r\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n    \/\/ 1. super init first\r\n    if ( !LayerColor::initWithColor(Color4B(255, 255, 255, 255)))\r\n    {\r\n        return false;\r\n    }\r\n    \r\n    \r\n    Global::game = this;\r\n    \r\n    longTouch = new LongTouch;\r\n    \r\n    auto size = Director::getInstance()-&gt;getWinSize();\r\n    \r\n    auto t1 = static_cast&lt;MySprite*&gt;(Sprite::create(&quot;star_on.png&quot;)); t1-&gt;init2();\r\n    t1-&gt;setPosition(size \/ 2); addChild(t1);\r\n    \r\n    auto t2 = static_cast&lt;MySprite*&gt;(Sprite::create(&quot;star_on.png&quot;)); t2-&gt;init2();\r\n    t2-&gt;setPosition(Vec2(size.width \/ 2 - 100, size.height \/ 2 - 100) ); addChild(t2);\r\n    \r\n    \r\n    auto t3 = static_cast&lt;MySprite*&gt;(Sprite::create(&quot;star_on.png&quot;)); t3-&gt;init2();\r\n    t3-&gt;setPosition(Vec2(size.width \/ 2 + 100, size.height \/ 2 + 100) ); addChild(t3);\r\n    \r\n    \r\n    \/*\r\n    auto _touchListener = EventListenerTouchOneByOne::create();\r\n    _touchListener-&gt;setSwallowTouches(true);\r\n    \r\n    _touchListener-&gt;onTouchBegan = &#x5B;&amp;](Touch* touch, Event* event){\r\n        \r\n        auto target = static_cast&lt;Sprite*&gt;(event-&gt;getCurrentTarget());\r\n        Point locationInNode = target-&gt;convertToNodeSpace(touch-&gt;getLocation());\r\n        Size s = target-&gt;getContentSize();\r\n        Rect rect = Rect(0, 0, s.width, s.height);\r\n        \r\n        \/\/\u70b9\u51fb\u8303\u56f4\u5224\u65ad\u68c0\u6d4b\r\n        if (rect.containsPoint(locationInNode))\r\n        {\r\n            longTouch-&gt;counter = 20;\r\n            longTouch-&gt;target = target;\r\n            return true;\r\n        }\r\n        return false;\r\n    };\r\n    \r\n    _touchListener-&gt;onTouchEnded = &#x5B;&amp;](Touch* touch, Event* event){\r\n        if (longTouch-&gt;counter == 0) return;\r\n        longTouch-&gt;counter = 0;\r\n        Audio::playSE(&quot;error.mp3&quot;);\r\n    };\r\n    \r\n    _eventDispatcher-&gt;addEventListenerWithSceneGraphPriority(_touchListener-&gt;clone(), t);\r\n    scheduleUpdate(); *\/\r\n    return true;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4ecb\u7ecd\uff1a \u6211\u4eec\u77e5\u9053 Mac \u4e2d\u9884\u89c8\u56fe\u7247\u7684\u65f6\u5019\u53ef\u4ee5\u4f7f\u7528\u591a\u6307\u89e6\u63a7\u5bf9\u56fe\u7247\u8fdb\u884c\u62c9\u4f38\u548c\u65cb\u8f6c\u3002 \u5728 iOS \u4e2d\u3001\u6211\u4eec\u53ef\u4ee5\u8ba9\u624b\u6307\u5728\u56fe\u4e2d\u7684\u76f8\u5bf9\u4f4d\u7f6e\u4fdd\u6301\u4e0d\u53d8\uff0c\u4ece\u800c\u5c06\u8fd9\u4e09\u4e2a\u64cd\u4f5c\u7edf\u4e00\u8d77\u6765\uff0c\u66f4\u65b9\u4fbf\u7684\u5b9e\u73b0\u7f16\u8f91\u529f\u80fd\u3002 \u6f14\u793a\u5730\u5740\uff1ahttp:\/\/www.pgyer.com\/Hu8O \u53c2\u8003\u8d44\u6599\uff1acpp-test \u4e2d\u7684 multitouch To-do: \u5982\u4f55\u652f\u6301\u6cbf\u7740\u4e00\u4e2a\u65b9\u5411\u7684\u62c9\u4f38\uff08\u4e09\u6307\uff1f\uff09 \u4ee3\u7801\uff1a<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[34],"tags":[],"class_list":["post-1103","post","type-post","status-publish","format-standard","hentry","category-34"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2tdP7-hN","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/posts\/1103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/comments?post=1103"}],"version-history":[{"count":1,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/posts\/1103\/revisions"}],"predecessor-version":[{"id":1104,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/posts\/1103\/revisions\/1104"}],"wp:attachment":[{"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/media?parent=1103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/categories?post=1103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shuizilong.com\/house\/wp-json\/wp\/v2\/tags?post=1103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}